mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
* Fix #4752: Error on calling super with @params in a derived class constructor * Catch calls to super with not-top-level @params
This commit is contained in:
parent
0dc4755920
commit
e2308093e4
3 changed files with 38 additions and 6 deletions
|
@ -3908,7 +3908,9 @@
|
|||
exprs.unshift(new Assign(new Value(new Arr([
|
||||
new Splat(new IdentifierLiteral(splatParamName)),
|
||||
...((function() {
|
||||
var k, len2, results;
|
||||
var k,
|
||||
len2,
|
||||
results;
|
||||
results = [];
|
||||
for (k = 0, len2 = paramsAfterSplat.length; k < len2; k++) {
|
||||
param = paramsAfterSplat[k];
|
||||
|
@ -4076,13 +4078,23 @@
|
|||
return seenSuper;
|
||||
}
|
||||
|
||||
// Find all super calls in the given context node
|
||||
// Returns `true` if `iterator` is called
|
||||
// Find all super calls in the given context node;
|
||||
// returns `true` if `iterator` is called.
|
||||
eachSuperCall(context, iterator) {
|
||||
var seenSuper;
|
||||
seenSuper = false;
|
||||
context.traverseChildren(true, (child) => {
|
||||
if (child instanceof SuperCall) {
|
||||
// `super` in a constructor (the only `super` without an accessor)
|
||||
// cannot be given an argument with a reference to `this`, as that would
|
||||
// be referencing `this` before calling `super`.
|
||||
if (!child.variable.accessor) {
|
||||
Block.wrap(child.args).traverseChildren(true, (node) => {
|
||||
if (node.this) {
|
||||
return node.error("Can't call super with @params in derived class constructors");
|
||||
}
|
||||
});
|
||||
}
|
||||
seenSuper = true;
|
||||
iterator(child);
|
||||
} else if (child instanceof ThisLiteral && this.ctor === 'derived' && !seenSuper) {
|
||||
|
|
|
@ -2783,13 +2783,19 @@ exports.Code = class Code extends Base
|
|||
|
||||
seenSuper
|
||||
|
||||
# Find all super calls in the given context node
|
||||
# Returns `true` if `iterator` is called
|
||||
# Find all super calls in the given context node;
|
||||
# returns `true` if `iterator` is called.
|
||||
eachSuperCall: (context, iterator) ->
|
||||
seenSuper = no
|
||||
|
||||
context.traverseChildren true, (child) =>
|
||||
context.traverseChildren yes, (child) =>
|
||||
if child instanceof SuperCall
|
||||
# `super` in a constructor (the only `super` without an accessor)
|
||||
# cannot be given an argument with a reference to `this`, as that would
|
||||
# be referencing `this` before calling `super`.
|
||||
unless child.variable.accessor
|
||||
Block.wrap(child.args).traverseChildren yes, (node) =>
|
||||
node.error "Can't call super with @params in derived class constructors" if node.this
|
||||
seenSuper = yes
|
||||
iterator child
|
||||
else if child instanceof ThisLiteral and @ctor is 'derived' and not seenSuper
|
||||
|
|
|
@ -1339,6 +1339,20 @@ test "derived constructors can't use @params without calling super", ->
|
|||
^^
|
||||
'''
|
||||
|
||||
test "derived constructors can't call super with @params", ->
|
||||
assertErrorFormat 'class extends A then constructor: (@a) -> super(@a)', '''
|
||||
[stdin]:1:49: error: Can't call super with @params in derived class constructors
|
||||
class extends A then constructor: (@a) -> super(@a)
|
||||
^^
|
||||
'''
|
||||
|
||||
test "derived constructors can't call super with buried @params", ->
|
||||
assertErrorFormat 'class extends A then constructor: (@a) -> super((=> @a)())', '''
|
||||
[stdin]:1:53: error: Can't call super with @params in derived class constructors
|
||||
class extends A then constructor: (@a) -> super((=> @a)())
|
||||
^^
|
||||
'''
|
||||
|
||||
test "'super' is not allowed in constructor parameter defaults", ->
|
||||
assertErrorFormat 'class extends A then constructor: (a = super()) ->', '''
|
||||
[stdin]:1:40: error: 'super' is not allowed in constructor parameter defaults
|
||||
|
|
Loading…
Reference in a new issue