Support parsing export default abstract class {} (#7075)
This commit is contained in:
@@ -2,5 +2,6 @@ abstract class C {}
|
||||
declare abstract class C {}
|
||||
export abstract class C {}
|
||||
// `export abstract class { }` is not valid.
|
||||
// `export default abstract class C { }` is not valid.
|
||||
export default abstract class { }
|
||||
export default abstract class C { }
|
||||
// `abstract class` is not valid as an expression.
|
||||
|
||||
@@ -3,5 +3,6 @@ abstract class C {}
|
||||
declare abstract class C {}
|
||||
|
||||
export abstract class C {} // `export abstract class { }` is not valid.
|
||||
// `export default abstract class C { }` is not valid.
|
||||
// `abstract class` is not valid as an expression.
|
||||
|
||||
export default abstract class {}
|
||||
export default abstract class C {} // `abstract class` is not valid as an expression.
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"sourceType": "module",
|
||||
"plugins": ["typescript", "classProperties"]
|
||||
"plugins": ["typescript"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export default abstract class {}
|
||||
@@ -0,0 +1 @@
|
||||
export default class {}
|
||||
@@ -1328,26 +1328,7 @@ export default class StatementParser extends ExpressionParser {
|
||||
this.parseExportFrom(node, true);
|
||||
} else if (this.eat(tt._default)) {
|
||||
// export default ...
|
||||
let expr = this.startNode();
|
||||
let needsSemi = false;
|
||||
if (this.eat(tt._function)) {
|
||||
expr = this.parseFunction(expr, true, false, false, true);
|
||||
} else if (
|
||||
this.isContextual("async") &&
|
||||
this.lookahead().type === tt._function
|
||||
) {
|
||||
// async function declaration
|
||||
this.eatContextual("async");
|
||||
this.eat(tt._function);
|
||||
expr = this.parseFunction(expr, true, false, true, true);
|
||||
} else if (this.match(tt._class)) {
|
||||
expr = this.parseClass(expr, true, true);
|
||||
} else {
|
||||
needsSemi = true;
|
||||
expr = this.parseMaybeAssign();
|
||||
}
|
||||
node.declaration = expr;
|
||||
if (needsSemi) this.semicolon();
|
||||
node.declaration = this.parseExportDefaultExpression();
|
||||
this.checkExport(node, true, true);
|
||||
return this.finishNode(node, "ExportDefaultDeclaration");
|
||||
} else if (this.shouldParseExportDeclaration()) {
|
||||
@@ -1373,6 +1354,27 @@ export default class StatementParser extends ExpressionParser {
|
||||
return this.finishNode(node, "ExportNamedDeclaration");
|
||||
}
|
||||
|
||||
parseExportDefaultExpression(): N.Expression | N.Declaration {
|
||||
const expr = this.startNode();
|
||||
if (this.eat(tt._function)) {
|
||||
return this.parseFunction(expr, true, false, false, true);
|
||||
} else if (
|
||||
this.isContextual("async") &&
|
||||
this.lookahead().type === tt._function
|
||||
) {
|
||||
// async function declaration
|
||||
this.eatContextual("async");
|
||||
this.eat(tt._function);
|
||||
return this.parseFunction(expr, true, false, true, true);
|
||||
} else if (this.match(tt._class)) {
|
||||
return this.parseClass(expr, true, true);
|
||||
} else {
|
||||
const res = this.parseMaybeAssign();
|
||||
this.semicolon();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
|
||||
return this.parseStatement(true);
|
||||
|
||||
@@ -1426,6 +1426,20 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
}
|
||||
}
|
||||
|
||||
parseExportDefaultExpression(): N.Expression | N.Declaration {
|
||||
if (
|
||||
this.isContextual("abstract") &&
|
||||
this.lookahead().type === tt._class
|
||||
) {
|
||||
const cls = this.startNode();
|
||||
this.next(); // Skip "abstract"
|
||||
this.parseClass(cls, true, true);
|
||||
cls.abstract = true;
|
||||
return cls;
|
||||
}
|
||||
return super.parseExportDefaultExpression();
|
||||
}
|
||||
|
||||
parseStatementContent(
|
||||
declaration: boolean,
|
||||
topLevel: ?boolean,
|
||||
|
||||
2
packages/babylon/test/fixtures/typescript/class/abstract-false-positive/actual.js
vendored
Normal file
2
packages/babylon/test/fixtures/typescript/class/abstract-false-positive/actual.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Exports an identifier, doesn't try parsing `abstract class`
|
||||
export default abstract;
|
||||
103
packages/babylon/test/fixtures/typescript/class/abstract-false-positive/expected.json
vendored
Normal file
103
packages/babylon/test/fixtures/typescript/class/abstract-false-positive/expected.json
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start": 0,
|
||||
"end": 87,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start": 0,
|
||||
"end": 87,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"sourceType": "module",
|
||||
"body": [
|
||||
{
|
||||
"type": "ExportDefaultDeclaration",
|
||||
"start": 63,
|
||||
"end": 87,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 24
|
||||
}
|
||||
},
|
||||
"declaration": {
|
||||
"type": "Identifier",
|
||||
"start": 78,
|
||||
"end": 86,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 15
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 23
|
||||
},
|
||||
"identifierName": "abstract"
|
||||
},
|
||||
"name": "abstract",
|
||||
"leadingComments": null
|
||||
},
|
||||
"leadingComments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " Exports an identifier, doesn't try parsing `abstract class`",
|
||||
"start": 0,
|
||||
"end": 62,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 62
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
},
|
||||
"comments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " Exports an identifier, doesn't try parsing `abstract class`",
|
||||
"start": 0,
|
||||
"end": 62,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 62
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
abstract class C {}
|
||||
declare abstract class C {}
|
||||
export abstract class C {}
|
||||
// `export abstract class { }` is not valid.
|
||||
// `export default abstract class C { }` is not valid.
|
||||
// `export abstract class {}` is not valid TypeScript.
|
||||
export default abstract class { }
|
||||
export default abstract class C { }
|
||||
// `abstract class` is not valid as an expression.
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start": 0,
|
||||
"end": 225,
|
||||
"end": 250,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"line": 7,
|
||||
"column": 50
|
||||
}
|
||||
},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start": 0,
|
||||
"end": 225,
|
||||
"end": 250,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"line": 7,
|
||||
"column": 50
|
||||
}
|
||||
},
|
||||
@@ -201,9 +201,9 @@
|
||||
"trailingComments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `export abstract class { }` is not valid.",
|
||||
"value": " `export abstract class {}` is not valid TypeScript.",
|
||||
"start": 75,
|
||||
"end": 119,
|
||||
"end": 129,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
@@ -211,38 +211,161 @@
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"column": 44
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `export default abstract class C { }` is not valid.",
|
||||
"start": 120,
|
||||
"end": 174,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 54
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExportDefaultDeclaration",
|
||||
"start": 130,
|
||||
"end": 163,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"column": 0
|
||||
},
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `abstract class` is not valid as an expression.",
|
||||
"start": 175,
|
||||
"end": 225,
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 33
|
||||
}
|
||||
},
|
||||
"declaration": {
|
||||
"type": "ClassDeclaration",
|
||||
"start": 145,
|
||||
"end": 163,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"column": 15
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 33
|
||||
}
|
||||
},
|
||||
"id": null,
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"type": "ClassBody",
|
||||
"start": 160,
|
||||
"end": 163,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"line": 5,
|
||||
"column": 30
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 33
|
||||
}
|
||||
},
|
||||
"body": [],
|
||||
"leadingComments": null
|
||||
},
|
||||
"leadingComments": null,
|
||||
"abstract": true
|
||||
},
|
||||
"leadingComments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `export abstract class {}` is not valid TypeScript.",
|
||||
"start": 75,
|
||||
"end": 129,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"column": 54
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExportDefaultDeclaration",
|
||||
"start": 164,
|
||||
"end": 199,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"column": 35
|
||||
}
|
||||
},
|
||||
"declaration": {
|
||||
"type": "ClassDeclaration",
|
||||
"start": 179,
|
||||
"end": 199,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"column": 15
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"column": 35
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start": 194,
|
||||
"end": 195,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"column": 30
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"column": 31
|
||||
},
|
||||
"identifierName": "C"
|
||||
},
|
||||
"name": "C"
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"type": "ClassBody",
|
||||
"start": 196,
|
||||
"end": 199,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"column": 32
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"column": 35
|
||||
}
|
||||
},
|
||||
"body": [],
|
||||
"leadingComments": null,
|
||||
"trailingComments": null
|
||||
},
|
||||
"trailingComments": null,
|
||||
"abstract": true
|
||||
},
|
||||
"trailingComments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `abstract class` is not valid as an expression.",
|
||||
"start": 200,
|
||||
"end": 250,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 7,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 7,
|
||||
"column": 50
|
||||
}
|
||||
}
|
||||
@@ -255,9 +378,9 @@
|
||||
"comments": [
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `export abstract class { }` is not valid.",
|
||||
"value": " `export abstract class {}` is not valid TypeScript.",
|
||||
"start": 75,
|
||||
"end": 119,
|
||||
"end": 129,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 4,
|
||||
@@ -265,22 +388,6 @@
|
||||
},
|
||||
"end": {
|
||||
"line": 4,
|
||||
"column": 44
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `export default abstract class C { }` is not valid.",
|
||||
"start": 120,
|
||||
"end": 174,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 5,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 54
|
||||
}
|
||||
}
|
||||
@@ -288,15 +395,15 @@
|
||||
{
|
||||
"type": "CommentLine",
|
||||
"value": " `abstract class` is not valid as an expression.",
|
||||
"start": 175,
|
||||
"end": 225,
|
||||
"start": 200,
|
||||
"end": 250,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 6,
|
||||
"line": 7,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 6,
|
||||
"line": 7,
|
||||
"column": 50
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user