Fix scope of assignments in dynamic class keys

Dynamic class keys were using the method scope for compilation,
resulting in missing declarations and runtime errors.
This commit is contained in:
Chris Connelly
2017-01-19 21:46:42 +00:00
parent 9e13100f58
commit 4f6073f283
3 changed files with 21 additions and 1 deletions

View File

@@ -2782,7 +2782,7 @@
}
compileNode(o) {
var answer, body, condition, exprs, haveSplatParam, i, ifTrue, j, k, len1, len2, m, modifiers, name, param, paramNames, params, paramsAfterSplat, ref, ref3, ref4, ref5, ref6, ref7, signature, splatParamName, thisAssignments, val, wasEmpty;
var answer, body, condition, exprs, haveSplatParam, i, ifTrue, j, k, len1, len2, m, methodScope, modifiers, name, param, paramNames, params, paramsAfterSplat, ref, ref3, ref4, ref5, ref6, ref7, ref8, signature, splatParamName, thisAssignments, val, wasEmpty;
if (this.ctor) {
if (this.isAsync) {
this.variable.error('Class constructor may not be async');
@@ -2928,10 +2928,12 @@
body = this.body.compileWithDeclarations(o);
}
if (this.isMethod) {
ref8 = [o.scope, o.scope.parent], methodScope = ref8[0], o.scope = ref8[1];
name = this.name.compileToFragments(o);
if (name[0].code === '.') {
name.shift();
}
o.scope = methodScope;
}
answer = this.joinFragmentArrays((function() {
var l, len3, results;

View File

@@ -2009,8 +2009,10 @@ exports.Code = class Code extends Base
# We need to compile the body before method names to ensure super references are handled
if @isMethod
[methodScope, o.scope] = [o.scope, o.scope.parent]
name = @name.compileToFragments o
name.shift() if name[0].code is '.'
o.scope = methodScope
answer = @joinFragmentArrays (@makeCode m for m in modifiers), ' '
answer.push @makeCode ' ' if modifiers.length and name

View File

@@ -845,6 +845,22 @@ test "#1392 calling `super` in methods defined on namespaced classes", ->
@a::m = -> super
eq 5, (new C.a).m()
test "dynamic method names", ->
class A
"#{name = 'm'}": -> 1
eq 1, new A().m()
class B extends A
"#{name = 'm'}": -> super
eq 1, new B().m()
getName = -> 'm'
class C
"#{name = getName()}": -> 1
eq 1, new C().m()
test "dynamic method names and super", ->
class Base
@m: -> 6