Open Gouvernathor opened 1 year ago
Hmm, so if I understand it correctly, the label parameters could be considered 'local scoped' but are declared in global scope?
That should be possible to configure with the parser. I've made some good progress there, but it's nowhere near ready for release. (Though I might do some gradual feature releases).
Soon it should be possible to use 'go to definition' on labels and have invalid label name detection etc
Yes. The scope concerns with renpy labels do not work the same as python scope concerns.
In Python, where you see name
, it may resolve to a local, non-local or global variable, but to figure out which one it is, you need only to look at the script, it can be determined statically. That is, you can't have a function containing a name
evaluation, call that function twice in different contexts and have the variable be bound to a global the first time and a local the second time. That's because Python functions have a static scope that is visible (through indentation) in the file, and strictly delimited.
That's the same with JS by the way.
In renpy, it is different, mainly because of the jump instruction but mostly because Tom made it that way. In renpy there is no scope barriers between files (unlike Python's modules) and there is no label scope. A label taking a block is misleading, because if you dedent what comes after it, the result is exactly the same. As such, all variables (except those in Python functions or in named Python scopes) are in the same global store
. The variables set by label parameters being evaluated update the store
, and they are rolled back to their previous value (or deleted if none) when either encountering a return
statement, or renpy.pop_call.
In renpy, you can have a label containing a $ name
, and have that variable be bound to a global constant declared using define
one time that label is called, and another time it can be bound to a label parameter that occured before that label gets called or jumped to.
Hope that helps.
This is most likely a long-term improvement, and the boundaries of what should and should not be flagged are relatively blurred. Here, you can see that the variable is flagged as not defaulted. But if it's a label parameter (see just above), then the variable exists (as long as you come from that label being called and did not return from it yet, and that's a more difficult if not impossible thing to check). That variable cannot be unbound (whether the label parameter is defaulted or required), at least while we are in the label block and have not passed another label. Even a use of highlight_properties in another file may be correct too, because if I jump or call a label of the other file from game_loop, the variable will still be bound.
So, I don't think we can realistically narrow down the issue more than this : every parameter of every label should be marked as correct regarding being defaulted. The only exception would be a label which doesn't call or jump anywhere, doesn't contain any python (which could jump), screens or custom statements (same) and just returns. In that case we can be sure its parameters are only bound within that label. But asserting that would require pretty heavy reachability analysis.