Skip to content

Commit e7031b7

Browse files
authored
[Babel 8] Treat allowSuperOutsideMethod as top-level only (#17505)
1 parent da0d1ad commit e7031b7

File tree

32 files changed

+687
-14
lines changed

32 files changed

+687
-14
lines changed

eslint/babel-eslint-parser/test/index.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,9 +930,9 @@ describe("Babel and Espree", () => {
930930
);
931931
});
932932

933-
it("super outside method - enabled", () => {
933+
it("super outside method - enabled - in top level", () => {
934934
expect(() => {
935-
parseForESLint("function F() { super(); }", {
935+
parseForESLint("super();", {
936936
babelOptions: {
937937
...BABEL_OPTIONS,
938938
parserOpts: {
@@ -942,6 +942,21 @@ describe("Babel and Espree", () => {
942942
});
943943
}).not.toThrow();
944944
});
945+
946+
it("super outside method - enabled - in function body", () => {
947+
expect(() => {
948+
parseForESLint("function F() { super(); }", {
949+
babelOptions: {
950+
...BABEL_OPTIONS,
951+
parserOpts: {
952+
allowSuperOutsideMethod: true,
953+
},
954+
},
955+
});
956+
}).toThrow(
957+
/`super\(\)` is only valid inside a class constructor of a subclass\./,
958+
);
959+
});
945960
} else {
946961
it("super outside method in Babel 7", () => {
947962
expect(() => {

packages/babel-parser/src/options.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export interface Options {
3030
*/
3131
allowNewTargetOutsideFunction?: boolean;
3232

33+
/**
34+
* By default, super calls are not allowed outside of a method.
35+
* Set this to true to accept such code.
36+
*/
3337
allowSuperOutsideMethod?: boolean;
3438

3539
/**
@@ -190,7 +194,7 @@ function createDefaultOptions(): OptionsWithDefaults {
190194
// When enabled, import/export statements are not constrained to
191195
// appearing at the top of the program.
192196
allowImportExportEverywhere: false,
193-
// TODO
197+
// When enabled, super outside a method is not considered an error.
194198
allowSuperOutsideMethod: false,
195199
// When enabled, export statements can reference undeclared variables.
196200
allowUndeclaredExports: false,

packages/babel-parser/src/parser/expression.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,17 +1545,22 @@ export default abstract class ExpressionParser extends LValParser {
15451545
parseSuper(): N.Super {
15461546
const node = this.startNode<N.Super>();
15471547
this.next(); // eat `super`
1548-
if (
1549-
this.match(tt.parenL) &&
1550-
!this.scope.allowDirectSuper &&
1551-
!(this.optionFlags & OptionFlags.AllowSuperOutsideMethod)
1552-
) {
1553-
this.raise(Errors.SuperNotAllowed, node);
1554-
} else if (
1555-
!this.scope.allowSuper &&
1556-
!(this.optionFlags & OptionFlags.AllowSuperOutsideMethod)
1557-
) {
1558-
this.raise(Errors.UnexpectedSuper, node);
1548+
if (this.match(tt.parenL) && !this.scope.allowDirectSuper) {
1549+
if (process.env.BABEL_8_BREAKING) {
1550+
this.raise(Errors.SuperNotAllowed, node);
1551+
} else {
1552+
if (!(this.optionFlags & OptionFlags.AllowSuperOutsideMethod)) {
1553+
this.raise(Errors.SuperNotAllowed, node);
1554+
}
1555+
}
1556+
} else if (!this.scope.allowSuper) {
1557+
if (process.env.BABEL_8_BREAKING) {
1558+
this.raise(Errors.UnexpectedSuper, node);
1559+
} else {
1560+
if (!(this.optionFlags & OptionFlags.AllowSuperOutsideMethod)) {
1561+
this.raise(Errors.UnexpectedSuper, node);
1562+
}
1563+
}
15591564
}
15601565

15611566
if (

packages/babel-parser/src/parser/util.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ export default abstract class UtilParser extends Tokenizer {
385385
if (this.optionFlags & OptionFlags.AllowNewTargetOutsideFunction) {
386386
scopeFlags |= ScopeFlag.NEW_TARGET;
387387
}
388+
if (process.env.BABEL_8_BREAKING) {
389+
if (this.optionFlags & OptionFlags.AllowSuperOutsideMethod) {
390+
scopeFlags |= ScopeFlag.SUPER | ScopeFlag.DIRECT_SUPER;
391+
}
392+
}
388393
this.scope.enter(scopeFlags);
389394
}
390395

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Derived extends Base {
2+
property = super();
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"allowSuperOutsideMethod": true,
3+
"BABEL_8_BREAKING": false
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"type": "File",
3+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
4+
"program": {
5+
"type": "Program",
6+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
7+
"sourceType": "script",
8+
"interpreter": null,
9+
"body": [
10+
{
11+
"type": "ClassDeclaration",
12+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
13+
"id": {
14+
"type": "Identifier",
15+
"start":6,"end":13,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":13,"index":13},"identifierName":"Derived"},
16+
"name": "Derived"
17+
},
18+
"superClass": {
19+
"type": "Identifier",
20+
"start":22,"end":26,"loc":{"start":{"line":1,"column":22,"index":22},"end":{"line":1,"column":26,"index":26},"identifierName":"Base"},
21+
"name": "Base"
22+
},
23+
"body": {
24+
"type": "ClassBody",
25+
"start":27,"end":52,"loc":{"start":{"line":1,"column":27,"index":27},"end":{"line":3,"column":1,"index":52}},
26+
"body": [
27+
{
28+
"type": "ClassProperty",
29+
"start":31,"end":50,"loc":{"start":{"line":2,"column":2,"index":31},"end":{"line":2,"column":21,"index":50}},
30+
"static": false,
31+
"key": {
32+
"type": "Identifier",
33+
"start":31,"end":39,"loc":{"start":{"line":2,"column":2,"index":31},"end":{"line":2,"column":10,"index":39},"identifierName":"property"},
34+
"name": "property"
35+
},
36+
"computed": false,
37+
"value": {
38+
"type": "CallExpression",
39+
"start":42,"end":49,"loc":{"start":{"line":2,"column":13,"index":42},"end":{"line":2,"column":20,"index":49}},
40+
"callee": {
41+
"type": "Super",
42+
"start":42,"end":47,"loc":{"start":{"line":2,"column":13,"index":42},"end":{"line":2,"column":18,"index":47}}
43+
},
44+
"arguments": []
45+
}
46+
}
47+
]
48+
}
49+
}
50+
],
51+
"directives": []
52+
}
53+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Derived extends Base {
2+
property = super();
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"allowSuperOutsideMethod": true,
3+
"BABEL_8_BREAKING": true
4+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"type": "File",
3+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
4+
"errors": [
5+
"SyntaxError: `super()` is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class? (2:13)"
6+
],
7+
"program": {
8+
"type": "Program",
9+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
10+
"sourceType": "script",
11+
"interpreter": null,
12+
"body": [
13+
{
14+
"type": "ClassDeclaration",
15+
"start":0,"end":52,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":52}},
16+
"id": {
17+
"type": "Identifier",
18+
"start":6,"end":13,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":13,"index":13},"identifierName":"Derived"},
19+
"name": "Derived"
20+
},
21+
"superClass": {
22+
"type": "Identifier",
23+
"start":22,"end":26,"loc":{"start":{"line":1,"column":22,"index":22},"end":{"line":1,"column":26,"index":26},"identifierName":"Base"},
24+
"name": "Base"
25+
},
26+
"body": {
27+
"type": "ClassBody",
28+
"start":27,"end":52,"loc":{"start":{"line":1,"column":27,"index":27},"end":{"line":3,"column":1,"index":52}},
29+
"body": [
30+
{
31+
"type": "ClassProperty",
32+
"start":31,"end":50,"loc":{"start":{"line":2,"column":2,"index":31},"end":{"line":2,"column":21,"index":50}},
33+
"static": false,
34+
"key": {
35+
"type": "Identifier",
36+
"start":31,"end":39,"loc":{"start":{"line":2,"column":2,"index":31},"end":{"line":2,"column":10,"index":39},"identifierName":"property"},
37+
"name": "property"
38+
},
39+
"computed": false,
40+
"value": {
41+
"type": "CallExpression",
42+
"start":42,"end":49,"loc":{"start":{"line":2,"column":13,"index":42},"end":{"line":2,"column":20,"index":49}},
43+
"callee": {
44+
"type": "Super",
45+
"start":42,"end":47,"loc":{"start":{"line":2,"column":13,"index":42},"end":{"line":2,"column":18,"index":47}}
46+
},
47+
"arguments": []
48+
}
49+
}
50+
]
51+
}
52+
}
53+
],
54+
"directives": []
55+
}
56+
}

0 commit comments

Comments
 (0)