1
0
Fork 0
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 (#4754)

* 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:
Geoffrey Booth 2017-10-25 22:15:05 -07:00 committed by GitHub
parent 0dc4755920
commit e2308093e4
3 changed files with 38 additions and 6 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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