diff --git a/src/parser/expression.js b/src/parser/expression.js index 775d658f32..d92b9db2f8 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -382,7 +382,11 @@ pp.parseExprAtom = function (refShorthandDefaultPos) { switch (this.state.type) { case tt._super: - if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { + if ( + !this.state.inMethod && + !this.state.inClassProperty && + !this.options.allowSuperOutsideMethod + ) { this.raise(this.state.start, "'super' outside of function or class"); } diff --git a/src/parser/statement.js b/src/parser/statement.js index 03fc2aaac3..488a554b94 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -783,6 +783,7 @@ pp.parseClassBody = function (node) { }; pp.parseClassProperty = function (node) { + this.state.inClassProperty = true; if (this.match(tt.eq)) { if (!this.hasPlugin("classProperties")) this.unexpected(); this.next(); @@ -791,6 +792,7 @@ pp.parseClassProperty = function (node) { node.value = null; } this.semicolon(); + this.state.inClassProperty = false; return this.finishNode(node, "ClassProperty"); }; diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 2e35b3ac4f..1bbfbda23d 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -18,6 +18,7 @@ export default class State { this.inAsync = this.inPropertyName = this.inType = + this.inClassProperty = this.noAnonFunctionType = false; @@ -73,6 +74,7 @@ export default class State { inAsync: boolean; inType: boolean; inPropertyName: boolean; + inClassProperty: boolean; // Labels in scope. labels: Array; diff --git a/test/fixtures/experimental/class-properties/super/actual.js b/test/fixtures/experimental/class-properties/super/actual.js new file mode 100644 index 0000000000..9c760b0bb1 --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/actual.js @@ -0,0 +1,3 @@ +class Fails extends class { c(){} } { + c = super.c(); +} diff --git a/test/fixtures/experimental/class-properties/super/expected.json b/test/fixtures/experimental/class-properties/super/expected.json new file mode 100644 index 0000000000..3460702b3b --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/expected.json @@ -0,0 +1,272 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Fails" + }, + "name": "Fails" + }, + "superClass": { + "type": "ClassExpression", + "start": 20, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "id": null, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 26, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 28, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "c" + }, + "name": "c" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 31, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "body": [], + "directives": [] + } + } + ] + } + }, + "body": { + "type": "ClassBody", + "start": 36, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 40, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "c" + }, + "name": "c" + }, + "value": { + "type": "CallExpression", + "start": 44, + "end": 53, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "callee": { + "type": "MemberExpression", + "start": 44, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 13 + } + }, + "object": { + "type": "Super", + "start": 44, + "end": 49, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "c" + }, + "name": "c" + }, + "computed": false + }, + "arguments": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-properties/super/options.json b/test/fixtures/experimental/class-properties/super/options.json new file mode 100644 index 0000000000..9c27576d4a --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties"] +}