Implement support for declare on class fields with Flow (#11178)

* Add parser support for Flow declare fields

* Add generator test

* Add "allowDeclareFields" option to flow-strip-types

* Add test

* Update error messages

* More tests
This commit is contained in:
Nicolò Ribaudo
2020-03-16 23:08:26 +01:00
committed by GitHub
parent 286aaeadd9
commit 5c1a8210da
51 changed files with 2439 additions and 51 deletions

View File

@@ -1240,50 +1240,59 @@ export default class StatementParser extends ExpressionParser {
return this.finishNode(classBody, "ClassBody");
}
// returns true if the current identifier is a method/field name,
// false if it is a modifier
parseClassMemberFromModifier(
classBody: N.ClassBody,
member: N.ClassMember,
): boolean {
const containsEsc = this.state.containsEsc;
const key = this.parseIdentifier(true); // eats the modifier
if (this.isClassMethod()) {
const method: N.ClassMethod = (member: any);
// a method named like the modifier
method.kind = "method";
method.computed = false;
method.key = key;
method.static = false;
this.pushClassMethod(
classBody,
method,
false,
false,
/* isConstructor */ false,
false,
);
return true;
} else if (this.isClassProperty()) {
const prop: N.ClassProperty = (member: any);
// a property named like the modifier
prop.computed = false;
prop.key = key;
prop.static = false;
classBody.body.push(this.parseClassProperty(prop));
return true;
} else if (containsEsc) {
throw this.unexpected();
}
return false;
}
parseClassMember(
classBody: N.ClassBody,
member: N.ClassMember,
state: { hadConstructor: boolean },
constructorAllowsSuper: boolean,
): void {
let isStatic = false;
const containsEsc = this.state.containsEsc;
const isStatic = this.isContextual("static");
if (this.match(tt.name) && this.state.value === "static") {
const key = this.parseIdentifier(true); // eats 'static'
if (this.isClassMethod()) {
const method: N.ClassMethod = (member: any);
// a method named 'static'
method.kind = "method";
method.computed = false;
method.key = key;
method.static = false;
this.pushClassMethod(
classBody,
method,
false,
false,
/* isConstructor */ false,
false,
);
return;
} else if (this.isClassProperty()) {
const prop: N.ClassProperty = (member: any);
// a property named 'static'
prop.computed = false;
prop.key = key;
prop.static = false;
classBody.body.push(this.parseClassProperty(prop));
return;
} else if (containsEsc) {
throw this.unexpected();
}
// otherwise something static
isStatic = true;
if (isStatic && this.parseClassMemberFromModifier(classBody, member)) {
// a class element named 'static'
return;
}
this.parseClassMemberWithIsStatic(

View File

@@ -51,6 +51,10 @@ const FlowErrors = Object.freeze({
AmbiguousDeclareModuleKind:
"Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module",
AssignReservedType: "Cannot overwrite reserved type %0",
DeclareClassElement:
"The `declare` modifier can only appear on class fields.",
DeclareClassFieldInitializer:
"Initializers are not allowed in fields with the `declare` modifier.",
DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement",
EnumBooleanMemberNotInitialized:
"Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.",
@@ -2085,6 +2089,39 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
parseClassMember(
classBody: N.ClassBody,
member: any,
state: { hadConstructor: boolean },
constructorAllowsSuper: boolean,
): void {
const pos = this.state.start;
if (this.isContextual("declare")) {
if (this.parseClassMemberFromModifier(classBody, member)) {
// 'declare' is a class element name
return;
}
member.declare = true;
}
super.parseClassMember(classBody, member, state, constructorAllowsSuper);
if (member.declare) {
if (
member.type !== "ClassProperty" &&
member.type !== "ClassPrivateProperty"
) {
this.raise(pos, FlowErrors.DeclareClassElement);
} else if (member.value) {
this.raise(
member.value.start,
FlowErrors.DeclareClassFieldInitializer,
);
}
}
}
// ensure that inside flow types, we bypass the jsx parser plugin
getTokenFromCode(code: number): void {
const next = this.input.charCodeAt(this.state.pos + 1);

View File

@@ -0,0 +1,3 @@
class A {
declare #foo = 2
}

View File

@@ -0,0 +1,158 @@
{
"type": "File",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"errors": [
"SyntaxError: Initializers are not allowed in fields with the `declare` modifier. (2:17)"
],
"program": {
"type": "Program",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassPrivateProperty",
"start": 12,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 18
}
},
"declare": true,
"static": false,
"key": {
"type": "PrivateName",
"start": 20,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 14
}
},
"id": {
"type": "Identifier",
"start": 21,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "foo"
},
"name": "foo"
}
},
"variance": null,
"value": {
"type": "NumericLiteral",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 17
},
"end": {
"line": 2,
"column": 18
}
},
"extra": {
"rawValue": 2,
"raw": "2"
},
"value": 2
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare #foo
}

View File

@@ -0,0 +1,136 @@
{
"type": "File",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassPrivateProperty",
"start": 12,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 14
}
},
"declare": true,
"static": false,
"key": {
"type": "PrivateName",
"start": 20,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 14
}
},
"id": {
"type": "Identifier",
"start": 21,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "foo"
},
"name": "foo"
}
},
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare #foo() {}
}

View File

@@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"flow",
"classPrivateProperties",
"classPrivateMethods"
]
}

View File

@@ -0,0 +1,159 @@
{
"type": "File",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"errors": [
"SyntaxError: The `declare` modifier can only appear on class fields. (2:2)"
],
"program": {
"type": "Program",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassPrivateMethod",
"start": 12,
"end": 29,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 19
}
},
"declare": true,
"static": false,
"key": {
"type": "PrivateName",
"start": 20,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 14
}
},
"id": {
"type": "Identifier",
"start": 21,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "foo"
},
"name": "foo"
}
},
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 27,
"end": 29,
"loc": {
"start": {
"line": 2,
"column": 17
},
"end": {
"line": 2,
"column": 19
}
},
"body": [],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
@dec declare foo
}

View File

@@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"flow",
"classProperties",
["decorators", { "decoratorsBeforeExport": false }]
]
}

View File

@@ -0,0 +1,156 @@
{
"type": "File",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 18
}
},
"decorators": [
{
"type": "Decorator",
"start": 12,
"end": 16,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 6
}
},
"expression": {
"type": "Identifier",
"start": 13,
"end": 16,
"loc": {
"start": {
"line": 2,
"column": 3
},
"end": {
"line": 2,
"column": 6
},
"identifierName": "dec"
},
"name": "dec"
}
}
],
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 25,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 15
},
"end": {
"line": 2,
"column": 18
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare @dec foo
}

View File

@@ -0,0 +1,9 @@
{
"sourceType": "module",
"plugins": [
"flow",
"classProperties",
["decorators", { "decoratorsBeforeExport": false }]
],
"throws": "Unexpected token (2:10)"
}

View File

@@ -0,0 +1,3 @@
class A {
declare constructor() {}
}

View File

@@ -0,0 +1,145 @@
{
"type": "File",
"start": 0,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"errors": [
"SyntaxError: The `declare` modifier can only appear on class fields. (2:2)"
],
"program": {
"type": "Program",
"start": 0,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 38,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassMethod",
"start": 12,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 26
}
},
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 21
},
"identifierName": "constructor"
},
"name": "constructor"
},
"computed": false,
"kind": "constructor",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 34,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 24
},
"end": {
"line": 2,
"column": 26
}
},
"body": [],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare [foo]
}

View File

@@ -0,0 +1,122 @@
{
"type": "File",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 15
}
},
"declare": true,
"static": false,
"computed": true,
"key": {
"type": "Identifier",
"start": 21,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "foo"
},
"name": "foo"
},
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare foo = 2
}

View File

@@ -0,0 +1,144 @@
{
"type": "File",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"errors": [
"SyntaxError: Initializers are not allowed in fields with the `declare` modifier. (2:16)"
],
"program": {
"type": "Program",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 17
}
},
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 13
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"variance": null,
"value": {
"type": "NumericLiteral",
"start": 26,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 16
},
"end": {
"line": 2,
"column": 17
}
},
"extra": {
"rawValue": 2,
"raw": "2"
},
"value": 2
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare static
}

View File

@@ -0,0 +1,121 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 26,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 16
}
},
"declare": true,
"computed": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 26,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 16
},
"identifierName": "static"
},
"name": "static"
},
"static": false,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare foo: string
}

View File

@@ -0,0 +1,152 @@
{
"type": "File",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 21
}
},
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 13
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"variance": null,
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 23,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 21
}
},
"typeAnnotation": {
"type": "StringTypeAnnotation",
"start": 25,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 15
},
"end": {
"line": 2,
"column": 21
}
}
}
},
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare foo
}

View File

@@ -0,0 +1,122 @@
{
"type": "File",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 13
}
},
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 13
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare foo() {}
}

View File

@@ -0,0 +1,145 @@
{
"type": "File",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"errors": [
"SyntaxError: The `declare` modifier can only appear on class fields. (2:2)"
],
"program": {
"type": "Program",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassMethod",
"start": 12,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 18
}
},
"declare": true,
"static": false,
"key": {
"type": "Identifier",
"start": 20,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 13
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 26,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 16
},
"end": {
"line": 2,
"column": 18
}
},
"body": [],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare static foo
}

View File

@@ -0,0 +1,122 @@
{
"type": "File",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 20
}
},
"declare": true,
"static": true,
"key": {
"type": "Identifier",
"start": 27,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 17
},
"end": {
"line": 2,
"column": 20
},
"identifierName": "foo"
},
"name": "foo"
},
"computed": false,
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare: string
}

View File

@@ -0,0 +1,150 @@
{
"type": "File",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 29,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 17
}
},
"computed": false,
"key": {
"type": "Identifier",
"start": 12,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 9
},
"identifierName": "declare"
},
"name": "declare"
},
"static": false,
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 19,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 17
}
},
"typeAnnotation": {
"type": "StringTypeAnnotation",
"start": 21,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 17
}
}
}
},
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare
}

View File

@@ -0,0 +1,120 @@
{
"type": "File",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 9
}
},
"computed": false,
"key": {
"type": "Identifier",
"start": 12,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 9
},
"identifierName": "declare"
},
"name": "declare"
},
"static": false,
"value": null
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,3 @@
class A {
declare() {}
}

View File

@@ -0,0 +1,141 @@
{
"type": "File",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassMethod",
"start": 12,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 14
}
},
"kind": "method",
"computed": false,
"key": {
"type": "Identifier",
"start": 12,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 9
},
"identifierName": "declare"
},
"name": "declare"
},
"static": false,
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 22,
"end": 24,
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 14
}
},
"body": [],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1,4 @@
{
"sourceType": "module",
"plugins": ["flow", "classProperties"]
}

View File

@@ -0,0 +1,3 @@
class A {
static declare foo
}

View File

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

View File

@@ -0,0 +1,3 @@
class A {
static declare
}

View File

@@ -0,0 +1,121 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "A"
},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ClassProperty",
"start": 12,
"end": 26,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 16
}
},
"static": true,
"key": {
"type": "Identifier",
"start": 19,
"end": 26,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 16
},
"identifierName": "declare"
},
"name": "declare"
},
"computed": false,
"variance": null,
"value": null
}
]
}
}
],
"directives": []
}
}