Closed Mercerenies closed 3 years ago
Found the issue report on Godot. Apparently it's intended behavior. So we definitely have to work around it.
Lambdas exhibit the same behavior. Basically, anything that creates an inner class in Godot and needs to reference an outer static.
(defn foo () 1)
(lambda () (foo))
It goes without saying, but I'll say it anyway so there's a note of it. Lambda classes are also guilty of this.
(defn foo () 1)
(new (Reference) (defn example () (foo)))
Two more for good measure
(defn foo () 1)
(defclass Example (Reference)
(defn call-foo () static (foo)))
(defn foo () 1)
(new (Reference) (defn example () static (foo)))
Edit: As of dc08744, the latter example is no longer allowed. Lambda classes cannot have static functions.
In summary, I can currently think of several places this is problematic.
labels
forms which require full closure (resolved by 9bed099)flet
/ labels
forms which require (simple) closure (resolved by 9bed099)labels
/ flet
forms which do not require any closure (resolved by 16b7d86)Other problems that need fixing
As of fb84972, this issue has mercifully been resolved.
The only minor divergence from the original plan is that lambda classes can no longer have static methods at all, so static methods in lambda classes are a nonissue. That change arose while trying to fix this issue and realizing that static methods on lambda classes were horribly broken (they pretended they had access to a closure and a self
argument that they had no right too) and are frankly not that useful to begin with, so I simply made it a compile error.
Aside from that, (GDScript) static functions in the outer scope are now accessible. If accessed from a non-static inner class scope (including explicit inner classes, lambdas, lambda classes, function references, and labels
blocks), a reference to the enclosing class will be created on the instance using load
. If accessed from a static inner class scope (which can only happen if explicitly requested in GDLisp; none of the implicit class constructs in GDLisp create static inner class methods as of right now), the current file will be loaded on-demand in the method using load
. Note that the outer class reference is only created if it's actually going to be used.
So, evidently, Godot won't let you access static functions from outer scope in an inner class. That is to say, the following code compiles in GDLisp (correctly)
and becomes (simplified slightly for the sake of example)
Which doesn't run in Godot. Godot thinks
foo
doesn't exist in the inner class scope. I suppose for now we need to preface all inner calls withload
. This seems like a GDScript issue, not a GDLisp one, but we need to accommodate I suppose.