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

fix(babel-parser): delete static property from class static block for TS #13680

Merged
merged 6 commits into from Aug 25, 2021
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
48 changes: 36 additions & 12 deletions packages/babel-parser/src/plugins/typescript/index.js
Expand Up @@ -230,17 +230,22 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}

/** Parses a modifier matching one the given modifier names. */
tsParseModifier<T: TsModifier>(allowedModifiers: T[]): ?T {
tsParseModifier<T: TsModifier>(
allowedModifiers: T[],
stopOnStartOfClassStaticBlock?: boolean,
): ?T {
if (!this.match(tt.name)) {
return undefined;
}

const modifier = this.state.value;
if (
allowedModifiers.indexOf(modifier) !== -1 &&
this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))
) {
return modifier;
if (allowedModifiers.indexOf(modifier) !== -1) {
if (stopOnStartOfClassStaticBlock && this.tsIsStartOfStaticBlocks()) {
return undefined;
}
if (this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) {
return modifier;
}
}
return undefined;
}
Expand All @@ -258,6 +263,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
allowedModifiers: TsModifier[],
disallowedModifiers?: TsModifier[],
errorTemplate?: ErrorTemplate,
stopOnStartOfClassStaticBlock?: boolean,
): void {
const enforceOrder = (pos, modifier, before, after) => {
if (modifier === before && modified[after]) {
Expand All @@ -277,6 +283,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const startPos = this.state.start;
const modifier: ?TsModifier = this.tsParseModifier(
allowedModifiers.concat(disallowedModifiers ?? []),
stopOnStartOfClassStaticBlock,
);

if (!modifier) break;
Expand Down Expand Up @@ -2374,34 +2381,51 @@ export default (superClass: Class<Parser>): Class<Parser> =>
});
}

tsIsStartOfStaticBlocks() {
return (
this.isContextual("static") &&
this.lookaheadCharCode() === charCodes.leftCurlyBrace
);
}

parseClassMember(
classBody: N.ClassBody,
member: any,
state: N.ParseClassMemberState,
): void {
const invalidModifersForStaticBlocks = [
const modifiers = [
"declare",
"private",
"public",
"protected",
"override",
"abstract",
"readonly",
"static",
];
this.tsParseModifiers(
member,
invalidModifersForStaticBlocks.concat(["static"]),
modifiers,
/* disallowedModifiers */ undefined,
/* errorTemplate */ undefined,
/* stopOnStartOfClassStaticBlock */ true,
);

const callParseClassMemberWithIsStatic = () => {
const isStatic = !!member.static;
if (isStatic && this.eat(tt.braceL)) {
if (this.tsHasSomeModifiers(member, invalidModifersForStaticBlocks)) {
if (this.tsIsStartOfStaticBlocks()) {
this.next(); // eat "static"
this.next(); // eat "{"
if (this.tsHasSomeModifiers(member, modifiers)) {
this.raise(this.state.pos, TSErrors.StaticBlockCannotHaveModifier);
}
this.parseClassStaticBlock(classBody, ((member: any): N.StaticBlock));
} else {
this.parseClassMemberWithIsStatic(classBody, member, state, isStatic);
this.parseClassMemberWithIsStatic(
classBody,
member,
state,
!!member.static,
);
}
};
if (member.declare) {
Expand Down
@@ -0,0 +1,3 @@
class Foo {
private static {}
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":33,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'private' modifier must precede 'static' modifier. (2:9)",
"SyntaxError: Static class blocks cannot have any modifier. (2:19)"
],
"program": {
Expand All @@ -27,7 +26,6 @@
{
"type": "StaticBlock",
"start":14,"end":31,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":19}},
"static": true,
"accessibility": "private",
"body": []
}
Expand Down
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:17)"
}
@@ -0,0 +1,3 @@
class Foo {
protected static {}
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'protected' modifier must precede 'static' modifier. (2:9)",
"SyntaxError: Static class blocks cannot have any modifier. (2:21)"
],
"program": {
Expand All @@ -27,7 +26,6 @@
{
"type": "StaticBlock",
"start":14,"end":33,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":21}},
"static": true,
"accessibility": "protected",
"body": []
}
Expand Down
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:19)"
}
@@ -0,0 +1,3 @@
class Foo {
public static {}
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":32,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'public' modifier must precede 'static' modifier. (2:9)",
"SyntaxError: Static class blocks cannot have any modifier. (2:18)"
],
"program": {
Expand All @@ -27,7 +26,6 @@
{
"type": "StaticBlock",
"start":14,"end":30,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}},
"static": true,
"accessibility": "public",
"body": []
}
Expand Down
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:16)"
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'static' modifier cannot be used with 'abstract' modifier. (2:11)",
"SyntaxError: Static class blocks cannot have any modifier. (2:20)"
],
"program": {
Expand All @@ -28,7 +27,6 @@
"type": "StaticBlock",
"start":14,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}},
"abstract": true,
"static": true,
"body": []
}
]
Expand Down
@@ -0,0 +1,3 @@
class Foo {
static abstract {}
}
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:18)"
}
@@ -0,0 +1,3 @@
class Foo {
abstract static {}
}
@@ -0,0 +1,38 @@
{
"type": "File",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: Static class blocks cannot have any modifier. (2:20)"
],
"program": {
"type": "Program",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":34,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}},
"body": [
{
"type": "StaticBlock",
"start":14,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}},
"abstract": true,
"body": []
}
]
}
}
],
"directives": []
}
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'static' modifier must precede 'override' modifier. (2:11)",
"SyntaxError: Static class blocks cannot have any modifier. (2:20)"
],
"program": {
Expand All @@ -28,7 +27,6 @@
"type": "StaticBlock",
"start":14,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}},
"override": true,
"static": true,
"body": []
}
]
Expand Down
@@ -0,0 +1,3 @@
class Foo {
static override {}
}
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:18)"
}
Expand Up @@ -2,7 +2,7 @@
"type": "File",
"start":0,"end":32,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: Duplicate modifier: 'static'. (2:9)"
"SyntaxError: Static class blocks cannot have any modifier. (2:18)"
],
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a regression, the input is

class Foo {
  static static {}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

@JLHwung Can you review again?

"program": {
"type": "Program",
Expand Down
Expand Up @@ -27,7 +27,6 @@
"type": "StaticBlock",
"start":14,"end":31,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":19}},
"declare": true,
"static": true,
"body": []
}
]
Expand Down
@@ -0,0 +1,3 @@
class Foo {
static declare {}
}
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:17)"
}
Expand Up @@ -2,7 +2,6 @@
"type": "File",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"errors": [
"SyntaxError: 'static' modifier must precede 'readonly' modifier. (2:11)",
"SyntaxError: Static class blocks cannot have any modifier. (2:20)"
],
"program": {
Expand All @@ -28,7 +27,6 @@
"type": "StaticBlock",
"start":14,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}},
"readonly": true,
"static": true,
"body": []
}
]
Expand Down
@@ -0,0 +1,3 @@
class Foo {
static readonly {}
}
@@ -0,0 +1,12 @@
{
"plugins": [
[
"classStaticBlock"
],
[
"typescript"
]
],
"sourceType": "module",
"throws": "Unexpected token (2:18)"
}
Expand Up @@ -35,7 +35,6 @@
{
"type": "StaticBlock",
"start":24,"end":33,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":11}},
"static": true,
"body": []
}
]
Expand Down