Skip to content

Commit

Permalink
spec: disable await binding identifier within static block
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jan 20, 2021
1 parent 10978bb commit 8fed4f4
Show file tree
Hide file tree
Showing 11 changed files with 1,018 additions and 84 deletions.
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 @@ -2297,6 +2297,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 }) {} } };
@@ -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,
"expression": 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"
}
}
]
}
}
]
}
]
}
}
}
},
{
"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,
"expression": 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": []
}
}
]
}
]
}
}
}
},
{
"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,
"expression": 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": []
}
}
]
}
]
}
}
}
},
{
"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,
"expression": false,
"params": [
{
"type": "ObjectPattern",
"start":190,"end":204,"loc":{"start":{"line":9,"column":32},"end":{"line":9,"column":46}},
"properties": [
{
"type": "Property",
"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"
},
"kind": "init"
}
]
}
],
"body": {
"type": "BlockStatement",
"start":206,"end":208,"loc":{"start":{"line":9,"column":48},"end":{"line":9,"column":50}},
"body": []
}
}
]
}
]
}
}
}
}
]
}
}

0 comments on commit 8fed4f4

Please sign in to comment.