Fix decorators2 to support export @decorator class A {} (#767)

* Fix decorators2 to support `export @decorator class A {}`

* change to better error message

Also ensure that null/undefined options get default value
This commit is contained in:
Daniel Tschinder 2017-10-29 12:20:15 +01:00 committed by GitHub
parent 8f8ea04b62
commit 86abc16b37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 350 additions and 64 deletions

View File

@ -54,7 +54,7 @@ export const defaultOptions: Options = {
export function getOptions(opts: ?Options): Options {
const options: any = {};
for (const key in defaultOptions) {
options[key] = opts && key in opts ? opts[key] : defaultOptions[key];
options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key];
}
return options;
}

View File

@ -1424,7 +1424,8 @@ export default class StatementParser extends ExpressionParser {
this.state.type.keyword === "let" ||
this.state.type.keyword === "function" ||
this.state.type.keyword === "class" ||
this.isContextual("async")
this.isContextual("async") ||
(this.match(tt.at) && this.expectPlugin("decorators2"))
);
}

View File

@ -110,7 +110,7 @@ export default class UtilParser extends Tokenizer {
throw this.raise(pos != null ? pos : this.state.start, messageOrType);
}
expectPlugin(name: string, pos?: ?number): void {
expectPlugin(name: string, pos?: ?number): true {
if (!this.hasPlugin(name)) {
throw this.raise(
pos != null ? pos : this.state.start,
@ -118,6 +118,8 @@ export default class UtilParser extends Tokenizer {
[name],
);
}
return true;
}
expectOnePlugin(names: Array<string>, pos?: ?number): void {

View File

@ -0,0 +1 @@
export @bar class Foo { }

View File

@ -0,0 +1,5 @@
{
"sourceType": "module",
"throws": "This experimental syntax requires enabling the parser plugin: 'decorators2' (1:7)",
"plugins": null
}

View File

@ -1,2 +1 @@
export default
@bar class Foo { }
export @bar class Foo { }

View File

@ -1,88 +1,90 @@
{
"type": "File",
"start": 0,
"end": 34,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
"line": 1,
"column": 25
}
},
"program": {
"type": "Program",
"start": 0,
"end": 34,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
"line": 1,
"column": 25
}
},
"sourceType": "module",
"body": [
{
"type": "ExportDefaultDeclaration",
"type": "ExportNamedDeclaration",
"start": 0,
"end": 34,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
"line": 1,
"column": 25
}
},
"specifiers": [],
"source": null,
"declaration": {
"type": "ClassExpression",
"start": 16,
"end": 34,
"type": "ClassDeclaration",
"start": 7,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 0
"line": 1,
"column": 7
},
"end": {
"line": 2,
"column": 18
"line": 1,
"column": 25
}
},
"decorators": [
{
"type": "Decorator",
"start": 16,
"end": 20,
"start": 7,
"end": 11,
"loc": {
"start": {
"line": 2,
"column": 0
"line": 1,
"column": 7
},
"end": {
"line": 2,
"column": 4
"line": 1,
"column": 11
}
},
"expression": {
"type": "Identifier",
"start": 17,
"end": 20,
"start": 8,
"end": 11,
"loc": {
"start": {
"line": 2,
"column": 1
"line": 1,
"column": 8
},
"end": {
"line": 2,
"column": 4
"line": 1,
"column": 11
},
"identifierName": "bar"
},
@ -92,16 +94,16 @@
],
"id": {
"type": "Identifier",
"start": 27,
"end": 30,
"start": 18,
"end": 21,
"loc": {
"start": {
"line": 2,
"column": 11
"line": 1,
"column": 18
},
"end": {
"line": 2,
"column": 14
"line": 1,
"column": 21
},
"identifierName": "Foo"
},
@ -110,16 +112,16 @@
"superClass": null,
"body": {
"type": "ClassBody",
"start": 31,
"end": 34,
"start": 22,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 15
"line": 1,
"column": 22
},
"end": {
"line": 2,
"column": 18
"line": 1,
"column": 25
}
},
"body": []

View File

@ -0,0 +1,2 @@
export default
@bar class Foo { }

View File

@ -0,0 +1,132 @@
{
"type": "File",
"start": 0,
"end": 34,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
}
},
"program": {
"type": "Program",
"start": 0,
"end": 34,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
}
},
"sourceType": "module",
"body": [
{
"type": "ExportDefaultDeclaration",
"start": 0,
"end": 34,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 18
}
},
"declaration": {
"type": "ClassExpression",
"start": 16,
"end": 34,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 18
}
},
"decorators": [
{
"type": "Decorator",
"start": 16,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 4
}
},
"expression": {
"type": "Identifier",
"start": 17,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 4
},
"identifierName": "bar"
},
"name": "bar"
}
}
],
"id": {
"type": "Identifier",
"start": 27,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "Foo"
},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 31,
"end": 34,
"loc": {
"start": {
"line": 2,
"column": 15
},
"end": {
"line": 2,
"column": 18
}
},
"body": []
}
}
}
],
"directives": []
}
}

View File

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

View File

@ -1,2 +1,2 @@
@foo
export default class {}
export class A {}

View File

@ -1,7 +1,7 @@
{
"type": "File",
"start": 0,
"end": 28,
"end": 22,
"loc": {
"start": {
"line": 1,
@ -9,13 +9,13 @@
},
"end": {
"line": 2,
"column": 23
"column": 17
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"end": 22,
"loc": {
"start": {
"line": 1,
@ -23,15 +23,15 @@
},
"end": {
"line": 2,
"column": 23
"column": 17
}
},
"sourceType": "module",
"body": [
{
"type": "ExportDefaultDeclaration",
"type": "ExportNamedDeclaration",
"start": 5,
"end": 28,
"end": 22,
"loc": {
"start": {
"line": 2,
@ -39,13 +39,15 @@
},
"end": {
"line": 2,
"column": 23
"column": 17
}
},
"specifiers": [],
"source": null,
"declaration": {
"type": "ClassDeclaration",
"start": 0,
"end": 28,
"end": 22,
"loc": {
"start": {
"line": 1,
@ -53,7 +55,7 @@
},
"end": {
"line": 2,
"column": 23
"column": 17
}
},
"decorators": [
@ -90,20 +92,36 @@
}
}
],
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start": 26,
"end": 28,
"id": {
"type": "Identifier",
"start": 18,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 21
"column": 13
},
"end": {
"line": 2,
"column": 23
"column": 14
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 20,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 15
},
"end": {
"line": 2,
"column": 17
}
},
"body": []

View File

@ -0,0 +1,2 @@
@foo
export default class {}

View File

@ -0,0 +1,116 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"sourceType": "module",
"body": [
{
"type": "ExportDefaultDeclaration",
"start": 5,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"declaration": {
"type": "ClassDeclaration",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"decorators": [
{
"type": "Decorator",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
},
"expression": {
"type": "Identifier",
"start": 1,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 4
},
"identifierName": "foo"
},
"name": "foo"
}
}
],
"id": null,
"superClass": null,
"body": {
"type": "ClassBody",
"start": 26,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 21
},
"end": {
"line": 2,
"column": 23
}
},
"body": []
}
}
}
],
"directives": []
}
}

View File

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