Add more parser test cases (#11923)

* remove unused codes

* refactor: remove unused parseAccessModifier

* refactor: remove redundant async function checks

* refactor: remove redundant class check in checkExport

* add more parser test cases

* Update packages/babel-parser/src/parser/statement.js

Co-authored-by: Brian Ng <bng412@gmail.com>

* chore: add sourceType: unambiguous test

Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
Huáng Jùnliàng 2020-08-14 11:53:17 -04:00 committed by GitHub
parent 9c565a97d5
commit 66c6b3b949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 246 additions and 37 deletions

View File

@ -1258,20 +1258,6 @@ export default class StatementParser extends ExpressionParser {
return this.finishNode(classBody, "ClassBody"); return this.finishNode(classBody, "ClassBody");
} }
// Check grammar production:
// IdentifierName *_opt ClassElementName
// It is used in `parsePropertyDefinition` to detect AsyncMethod and Accessors
maybeClassModifier(prop: N.ObjectProperty): boolean {
return (
!prop.computed &&
prop.key.type === "Identifier" &&
(this.isLiteralPropertyName() ||
this.match(tt.bracketL) ||
this.match(tt.star) ||
this.match(tt.hash))
);
}
// returns true if the current identifier is a method/field name, // returns true if the current identifier is a method/field name,
// false if it is a modifier // false if it is a modifier
parseClassMemberFromModifier( parseClassMemberFromModifier(
@ -1611,11 +1597,6 @@ export default class StatementParser extends ExpressionParser {
methodOrProp: N.ClassMethod | N.ClassProperty, methodOrProp: N.ClassMethod | N.ClassProperty,
): void {} ): void {}
// Overridden in typescript.js
parseAccessModifier(): ?N.Accessibility {
return undefined;
}
parseClassPrivateProperty( parseClassPrivateProperty(
node: N.ClassPrivateProperty, node: N.ClassPrivateProperty,
): N.ClassPrivateProperty { ): N.ClassPrivateProperty {
@ -1784,19 +1765,9 @@ export default class StatementParser extends ExpressionParser {
maybeParseExportDeclaration(node: N.Node): boolean { maybeParseExportDeclaration(node: N.Node): boolean {
if (this.shouldParseExportDeclaration()) { if (this.shouldParseExportDeclaration()) {
if (this.isContextual("async")) {
const next = this.nextTokenStart();
// export async;
if (!this.isUnparsedContextual(next, "function")) {
this.unexpected(next, tt._function);
}
}
node.specifiers = []; node.specifiers = [];
node.source = null; node.source = null;
node.declaration = this.parseExportDeclaration(node); node.declaration = this.parseExportDeclaration(node);
return true; return true;
} }
return false; return false;
@ -1999,16 +1970,11 @@ export default class StatementParser extends ExpressionParser {
const currentContextDecorators = this.state.decoratorStack[ const currentContextDecorators = this.state.decoratorStack[
this.state.decoratorStack.length - 1 this.state.decoratorStack.length - 1
]; ];
// If node.declaration is a class, it will take all decorators in the current context.
// Thus we should throw if we see non-empty decorators here.
if (currentContextDecorators.length) { if (currentContextDecorators.length) {
const isClass =
node.declaration &&
(node.declaration.type === "ClassDeclaration" ||
node.declaration.type === "ClassExpression");
if (!node.declaration || !isClass) {
throw this.raise(node.start, Errors.UnsupportedDecoratorExport); throw this.raise(node.start, Errors.UnsupportedDecoratorExport);
} }
this.takeDecorators(node.declaration);
}
} }
checkDeclaration(node: N.Pattern | N.ObjectProperty): void { checkDeclaration(node: N.Pattern | N.ObjectProperty): void {

View File

@ -0,0 +1,2 @@
// prettier-ignore
await +42

View File

@ -0,0 +1,3 @@
{
"sourceType": "module"
}

View File

@ -0,0 +1,33 @@
{
"type": "AwaitExpression",
"start":19,"end":28,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":9}},
"argument": {
"type": "UnaryExpression",
"start":25,"end":28,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9}},
"operator": "+",
"prefix": true,
"argument": {
"type": "NumericLiteral",
"start":26,"end":28,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":9}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
}
},
"leadingComments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
],
"comments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
]
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["topLevelAwait"]
}

View File

@ -0,0 +1,2 @@
// prettier-ignore
await +42

View File

@ -0,0 +1,3 @@
{
"sourceType": "script"
}

View File

@ -0,0 +1,33 @@
{
"type": "BinaryExpression",
"start":19,"end":28,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":9}},
"left": {
"type": "Identifier",
"start":19,"end":24,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5},"identifierName":"await"},
"name": "await"
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start":26,"end":28,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":9}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
},
"leadingComments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
],
"comments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
]
}

View File

@ -0,0 +1,2 @@
// prettier-ignore
await +42

View File

@ -0,0 +1,3 @@
{
"sourceType": "unambiguous"
}

View File

@ -0,0 +1,33 @@
{
"type": "BinaryExpression",
"start":19,"end":28,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":9}},
"left": {
"type": "Identifier",
"start":19,"end":24,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5},"identifierName":"await"},
"name": "await"
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start":26,"end":28,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":9}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
},
"leadingComments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
],
"comments": [
{
"type": "CommentLine",
"value": " prettier-ignore",
"start":0,"end":18,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":18}}
}
]
}

View File

@ -0,0 +1 @@
const { foo() {} } = foo();

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token (1:11)"
}

View File

@ -0,0 +1 @@
export * as foo,

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \"{\" (1:16)"
}

View File

@ -0,0 +1,6 @@
{
"plugins": [
"functionBind"
],
"throws": "Binding should be performed on object property. (1:2)"
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["functionBind"]
}

View File

@ -0,0 +1 @@
({ @foo ...foo });

View File

@ -0,0 +1,4 @@
{
"plugins": ["decorators-legacy"],
"throws": "Unexpected token (1:8)"
}

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \"{\" (1:15)"
}

View File

@ -0,0 +1,3 @@
{
"plugins": [["pipelineOperator", { "proposal": "fsharp" }]]
}

View File

@ -0,0 +1,49 @@
{
"type": "File",
"start":0,"end":10,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":10}},
"errors": [
"SyntaxError: Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option. (1:5)",
"SyntaxError: Topic reference was used in a lexical context without topic binding (1:5)"
],
"program": {
"type": "Program",
"start":0,"end":10,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":10}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":10,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":10}},
"expression": {
"type": "BinaryExpression",
"start":0,"end":10,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":10}},
"left": {
"type": "Identifier",
"start":0,"end":1,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":1},"identifierName":"x"},
"name": "x"
},
"operator": "|>",
"right": {
"type": "BinaryExpression",
"start":5,"end":10,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":10}},
"left": {
"type": "PipelinePrimaryTopicReference",
"start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6}}
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start":9,"end":10,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":10}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
#{ __proto__: null }

View File

@ -0,0 +1,3 @@
{
"plugins": [["recordAndTuple", { "syntaxType": "hash" }]]
}

View File

@ -0,0 +1,42 @@
{
"type": "File",
"start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}},
"errors": [
"SyntaxError: '__proto__' is not allowed in Record expressions (1:3)"
],
"program": {
"type": "Program",
"start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}},
"expression": {
"type": "RecordExpression",
"start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}},
"properties": [
{
"type": "ObjectProperty",
"start":3,"end":18,"loc":{"start":{"line":1,"column":3},"end":{"line":1,"column":18}},
"method": false,
"key": {
"type": "Identifier",
"start":3,"end":12,"loc":{"start":{"line":1,"column":3},"end":{"line":1,"column":12},"identifierName":"__proto__"},
"name": "__proto__"
},
"computed": false,
"shorthand": false,
"value": {
"type": "NullLiteral",
"start":14,"end":18,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":18}}
}
}
]
}
}
],
"directives": []
}
}