Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: disable await binding identifier within static block #12661

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/babel-parser/src/parser/error-message.js
Expand Up @@ -14,6 +14,8 @@ export const ErrorMessages = Object.freeze({
"Async functions can only be declared at the top level or inside a block",
AwaitBindingIdentifier:
"Can not use 'await' as identifier inside an async function",
AwaitBindingIdentifierInStaticBlock:
"Can not use 'await' as identifier inside a static block",
AwaitExpressionFormalParameter:
"await is not allowed in async function parameters",
AwaitNotInAsyncContext:
Expand Down
3 changes: 3 additions & 0 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -2320,6 +2320,9 @@ export default class ExpressionParser extends LValParser {
if (this.prodParam.hasAwait) {
this.raise(startLoc, Errors.AwaitBindingIdentifier);
return;
} else if (this.scope.inStaticBlock && !this.scope.inNonArrowFunction) {
this.raise(startLoc, Errors.AwaitBindingIdentifierInStaticBlock);
return;
} else {
this.expressionScope.recordAsyncArrowParametersError(
startLoc,
Expand Down
7 changes: 2 additions & 5 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -20,6 +20,7 @@ import {
SCOPE_FUNCTION,
SCOPE_OTHER,
SCOPE_SIMPLE_CATCH,
SCOPE_STATIC_BLOCK,
SCOPE_SUPER,
CLASS_ELEMENT_OTHER,
CLASS_ELEMENT_INSTANCE_GETTER,
Expand Down Expand Up @@ -1519,10 +1520,7 @@ export default class StatementParser extends ExpressionParser {
) {
this.expectPlugin("classStaticBlock", member.start);
// Start a new lexical scope
this.scope.enter(SCOPE_CLASS | SCOPE_SUPER);
// Start a new expression scope, this is required for parsing edge cases like:
// async (x = class { static { await; } }) => {}
this.expressionScope.enter(newExpressionScope());
this.scope.enter(SCOPE_CLASS | SCOPE_STATIC_BLOCK | SCOPE_SUPER);
// Start a new scope with regard to loop labels
const oldLabels = this.state.labels;
this.state.labels = [];
Expand All @@ -1532,7 +1530,6 @@ export default class StatementParser extends ExpressionParser {
const body = (member.body = []);
this.parseBlockOrModuleBlockBody(body, undefined, false, tt.braceR);
this.prodParam.exit();
this.expressionScope.exit();
this.scope.exit();
this.state.labels = oldLabels;
classBody.body.push(this.finishNode<N.StaticBlock>(member, "StaticBlock"));
Expand Down
4 changes: 4 additions & 0 deletions packages/babel-parser/src/util/scope.js
Expand Up @@ -8,6 +8,7 @@ import {
SCOPE_PROGRAM,
SCOPE_VAR,
SCOPE_CLASS,
SCOPE_STATIC_BLOCK,
BIND_SCOPE_FUNCTION,
BIND_SCOPE_VAR,
BIND_SCOPE_LEXICAL,
Expand Down Expand Up @@ -61,6 +62,9 @@ export default class ScopeHandler<IScope: Scope = Scope> {
get inClass() {
return (this.currentThisScope().flags & SCOPE_CLASS) > 0;
}
get inStaticBlock() {
return (this.currentThisScope().flags & SCOPE_STATIC_BLOCK) > 0;
}
get inNonArrowFunction() {
return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0;
}
Expand Down
22 changes: 12 additions & 10 deletions packages/babel-parser/src/util/scopeflags.js
Expand Up @@ -2,15 +2,16 @@

// Each scope gets a bitset that may contain these flags
// prettier-ignore
export const SCOPE_OTHER = 0b00000000,
SCOPE_PROGRAM = 0b00000001,
SCOPE_FUNCTION = 0b00000010,
SCOPE_ARROW = 0b00000100,
SCOPE_SIMPLE_CATCH = 0b00001000,
SCOPE_SUPER = 0b00010000,
SCOPE_DIRECT_SUPER = 0b00100000,
SCOPE_CLASS = 0b01000000,
SCOPE_TS_MODULE = 0b10000000,
export const SCOPE_OTHER = 0b000000000,
SCOPE_PROGRAM = 0b000000001,
SCOPE_FUNCTION = 0b000000010,
SCOPE_ARROW = 0b000000100,
SCOPE_SIMPLE_CATCH = 0b000001000,
SCOPE_SUPER = 0b000010000,
SCOPE_DIRECT_SUPER = 0b000100000,
SCOPE_CLASS = 0b001000000,
SCOPE_STATIC_BLOCK = 0b010000000,
SCOPE_TS_MODULE = 0b100000000,
SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION | SCOPE_TS_MODULE;

export type ScopeFlags =
Expand All @@ -22,7 +23,8 @@ export type ScopeFlags =
| typeof SCOPE_SIMPLE_CATCH
| typeof SCOPE_SUPER
| typeof SCOPE_DIRECT_SUPER
| typeof SCOPE_CLASS;
| typeof SCOPE_CLASS
| typeof SCOPE_STATIC_BLOCK;

// These flags are meant to be _only_ used inside the Scope class (or subclasses).
// prettier-ignore
Expand Down
@@ -0,0 +1,9 @@
var C;

C = class { static { function f() { await } } };

C = class { static { function f(await) {} } };

C = class { static { function f(x = await) {} } };

C = class { static { function f({ [await]: x }) {} } };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cases that await as binding will not throw.

@@ -0,0 +1,285 @@
{
"type": "File",
"start":0,"end":213,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":55}},
"program": {
"type": "Program",
"start":0,"end":213,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":55}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}},
"declarations": [
{
"type": "VariableDeclarator",
"start":4,"end":5,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":5}},
"id": {
"type": "Identifier",
"start":4,"end":5,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":5},"identifierName":"C"},
"name": "C"
},
"init": null
}
],
"kind": "var"
},
{
"type": "ExpressionStatement",
"start":8,"end":56,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":48}},
"expression": {
"type": "AssignmentExpression",
"start":8,"end":55,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":47}},
"operator": "=",
"left": {
"type": "Identifier",
"start":8,"end":9,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":1},"identifierName":"C"},
"name": "C"
},
"right": {
"type": "ClassExpression",
"start":12,"end":55,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":47}},
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start":18,"end":55,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":47}},
"body": [
{
"type": "StaticBlock",
"start":20,"end":53,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":45}},
"body": [
{
"type": "FunctionDeclaration",
"start":29,"end":51,"loc":{"start":{"line":3,"column":21},"end":{"line":3,"column":43}},
"id": {
"type": "Identifier",
"start":38,"end":39,"loc":{"start":{"line":3,"column":30},"end":{"line":3,"column":31},"identifierName":"f"},
"name": "f"
},
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":42,"end":51,"loc":{"start":{"line":3,"column":34},"end":{"line":3,"column":43}},
"body": [
{
"type": "ExpressionStatement",
"start":44,"end":49,"loc":{"start":{"line":3,"column":36},"end":{"line":3,"column":41}},
"expression": {
"type": "Identifier",
"start":44,"end":49,"loc":{"start":{"line":3,"column":36},"end":{"line":3,"column":41},"identifierName":"await"},
"name": "await"
}
}
],
"directives": []
}
}
]
}
]
}
}
}
},
{
"type": "ExpressionStatement",
"start":58,"end":104,"loc":{"start":{"line":5,"column":0},"end":{"line":5,"column":46}},
"expression": {
"type": "AssignmentExpression",
"start":58,"end":103,"loc":{"start":{"line":5,"column":0},"end":{"line":5,"column":45}},
"operator": "=",
"left": {
"type": "Identifier",
"start":58,"end":59,"loc":{"start":{"line":5,"column":0},"end":{"line":5,"column":1},"identifierName":"C"},
"name": "C"
},
"right": {
"type": "ClassExpression",
"start":62,"end":103,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":45}},
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start":68,"end":103,"loc":{"start":{"line":5,"column":10},"end":{"line":5,"column":45}},
"body": [
{
"type": "StaticBlock",
"start":70,"end":101,"loc":{"start":{"line":5,"column":12},"end":{"line":5,"column":43}},
"body": [
{
"type": "FunctionDeclaration",
"start":79,"end":99,"loc":{"start":{"line":5,"column":21},"end":{"line":5,"column":41}},
"id": {
"type": "Identifier",
"start":88,"end":89,"loc":{"start":{"line":5,"column":30},"end":{"line":5,"column":31},"identifierName":"f"},
"name": "f"
},
"generator": false,
"async": false,
"params": [
{
"type": "Identifier",
"start":90,"end":95,"loc":{"start":{"line":5,"column":32},"end":{"line":5,"column":37},"identifierName":"await"},
"name": "await"
}
],
"body": {
"type": "BlockStatement",
"start":97,"end":99,"loc":{"start":{"line":5,"column":39},"end":{"line":5,"column":41}},
"body": [],
"directives": []
}
}
]
}
]
}
}
}
},
{
"type": "ExpressionStatement",
"start":106,"end":156,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":50}},
"expression": {
"type": "AssignmentExpression",
"start":106,"end":155,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":49}},
"operator": "=",
"left": {
"type": "Identifier",
"start":106,"end":107,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":1},"identifierName":"C"},
"name": "C"
},
"right": {
"type": "ClassExpression",
"start":110,"end":155,"loc":{"start":{"line":7,"column":4},"end":{"line":7,"column":49}},
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start":116,"end":155,"loc":{"start":{"line":7,"column":10},"end":{"line":7,"column":49}},
"body": [
{
"type": "StaticBlock",
"start":118,"end":153,"loc":{"start":{"line":7,"column":12},"end":{"line":7,"column":47}},
"body": [
{
"type": "FunctionDeclaration",
"start":127,"end":151,"loc":{"start":{"line":7,"column":21},"end":{"line":7,"column":45}},
"id": {
"type": "Identifier",
"start":136,"end":137,"loc":{"start":{"line":7,"column":30},"end":{"line":7,"column":31},"identifierName":"f"},
"name": "f"
},
"generator": false,
"async": false,
"params": [
{
"type": "AssignmentPattern",
"start":138,"end":147,"loc":{"start":{"line":7,"column":32},"end":{"line":7,"column":41}},
"left": {
"type": "Identifier",
"start":138,"end":139,"loc":{"start":{"line":7,"column":32},"end":{"line":7,"column":33},"identifierName":"x"},
"name": "x"
},
"right": {
"type": "Identifier",
"start":142,"end":147,"loc":{"start":{"line":7,"column":36},"end":{"line":7,"column":41},"identifierName":"await"},
"name": "await"
}
}
],
"body": {
"type": "BlockStatement",
"start":149,"end":151,"loc":{"start":{"line":7,"column":43},"end":{"line":7,"column":45}},
"body": [],
"directives": []
}
}
]
}
]
}
}
}
},
{
"type": "ExpressionStatement",
"start":158,"end":213,"loc":{"start":{"line":9,"column":0},"end":{"line":9,"column":55}},
"expression": {
"type": "AssignmentExpression",
"start":158,"end":212,"loc":{"start":{"line":9,"column":0},"end":{"line":9,"column":54}},
"operator": "=",
"left": {
"type": "Identifier",
"start":158,"end":159,"loc":{"start":{"line":9,"column":0},"end":{"line":9,"column":1},"identifierName":"C"},
"name": "C"
},
"right": {
"type": "ClassExpression",
"start":162,"end":212,"loc":{"start":{"line":9,"column":4},"end":{"line":9,"column":54}},
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start":168,"end":212,"loc":{"start":{"line":9,"column":10},"end":{"line":9,"column":54}},
"body": [
{
"type": "StaticBlock",
"start":170,"end":210,"loc":{"start":{"line":9,"column":12},"end":{"line":9,"column":52}},
"body": [
{
"type": "FunctionDeclaration",
"start":179,"end":208,"loc":{"start":{"line":9,"column":21},"end":{"line":9,"column":50}},
"id": {
"type": "Identifier",
"start":188,"end":189,"loc":{"start":{"line":9,"column":30},"end":{"line":9,"column":31},"identifierName":"f"},
"name": "f"
},
"generator": false,
"async": false,
"params": [
{
"type": "ObjectPattern",
"start":190,"end":204,"loc":{"start":{"line":9,"column":32},"end":{"line":9,"column":46}},
"properties": [
{
"type": "ObjectProperty",
"start":192,"end":202,"loc":{"start":{"line":9,"column":34},"end":{"line":9,"column":44}},
"method": false,
"computed": true,
"key": {
"type": "Identifier",
"start":193,"end":198,"loc":{"start":{"line":9,"column":35},"end":{"line":9,"column":40},"identifierName":"await"},
"name": "await"
},
"shorthand": false,
"value": {
"type": "Identifier",
"start":201,"end":202,"loc":{"start":{"line":9,"column":43},"end":{"line":9,"column":44},"identifierName":"x"},
"name": "x"
}
}
]
}
],
"body": {
"type": "BlockStatement",
"start":206,"end":208,"loc":{"start":{"line":9,"column":48},"end":{"line":9,"column":50}},
"body": [],
"directives": []
}
}
]
}
]
}
}
}
}
],
"directives": []
}
}