mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 14:18:42 +01:00
Fix closures in methods.
A local name inside a method should always resolve to a self send even if there is a local variable with that name outside of the method.
This commit is contained in:
@ -1230,9 +1230,13 @@ static int addUpvalue(Compiler* compiler, bool isLocal, int index)
|
||||
// not close over local variables.
|
||||
static int findUpvalue(Compiler* compiler, const char* name, int length)
|
||||
{
|
||||
// If we are at a method boundary or the top level, we didn't find it.
|
||||
if (compiler->parent == NULL || compiler->enclosingClass != NULL) return -1;
|
||||
|
||||
// If we are at the top level, we didn't find it.
|
||||
if (compiler->parent == NULL) return -1;
|
||||
|
||||
// If we hit the method boundary (and the name isn't a static field), then
|
||||
// stop looking for it. We'll instead treat it as a self send.
|
||||
if (name[0] != '_' && compiler->parent->enclosingClass != NULL) return -1;
|
||||
|
||||
// See if it's a local variable in the immediately enclosing function.
|
||||
int local = resolveLocal(compiler->parent, name, length);
|
||||
if (local != -1)
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
// TODO: Is this right? Shouldn't it resolve to this.local?
|
||||
var foo = null
|
||||
|
||||
{
|
||||
var local = "local"
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
System.print(local)
|
||||
}
|
||||
}
|
||||
|
||||
foo = Foo.new()
|
||||
}
|
||||
|
||||
foo.method // expect: local
|
||||
@ -1,13 +0,0 @@
|
||||
// TODO: Is this right? Shouldn't it resolve to this.local?
|
||||
{
|
||||
var local = "local"
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
System.print(local)
|
||||
}
|
||||
}
|
||||
|
||||
Foo.new().method // expect: local
|
||||
}
|
||||
22
test/language/variable/local_outside_method.wren
Normal file
22
test/language/variable/local_outside_method.wren
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
var foo = "variable"
|
||||
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
foo { "method" }
|
||||
|
||||
method {
|
||||
System.print(foo)
|
||||
}
|
||||
|
||||
static foo { "class method" }
|
||||
|
||||
static classMethod {
|
||||
System.print(foo)
|
||||
}
|
||||
}
|
||||
|
||||
Foo.new().method // expect: method
|
||||
Foo.classMethod // expect: class method
|
||||
}
|
||||
Reference in New Issue
Block a user