diff --git a/packages/babel-generator/test/fixtures/flow/declare-field/input.js b/packages/babel-generator/test/fixtures/flow/declare-field/input.js new file mode 100644 index 0000000000..f0db8dde17 --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/declare-field/input.js @@ -0,0 +1,4 @@ +class A { + declare x + declare static y +} diff --git a/packages/babel-generator/test/fixtures/flow/declare-field/options.json b/packages/babel-generator/test/fixtures/flow/declare-field/options.json new file mode 100644 index 0000000000..65c79d81c7 --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/declare-field/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["flow", "classProperties"] +} diff --git a/packages/babel-generator/test/fixtures/flow/declare-field/output.js b/packages/babel-generator/test/fixtures/flow/declare-field/output.js new file mode 100644 index 0000000000..7d405964d2 --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/declare-field/output.js @@ -0,0 +1,4 @@ +class A { + declare x; + declare static y; +} \ No newline at end of file diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 7c435b4aa1..794667bb35 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -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( diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index 2f32adcb99..e445df729f 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -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): Class => } } + 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); diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/input.js b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/input.js new file mode 100644 index 0000000000..7f38766c9f --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/input.js @@ -0,0 +1,3 @@ +class A { + declare #foo = 2 +} diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/output.json b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/output.json new file mode 100644 index 0000000000..d8b704a351 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field-initializer/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/input.js b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/input.js new file mode 100644 index 0000000000..bc3b7c37d3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/input.js @@ -0,0 +1,3 @@ +class A { + declare #foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/output.json b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/output.json new file mode 100644 index 0000000000..0b28665941 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-field/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/input.js b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/input.js new file mode 100644 index 0000000000..edfd99fe60 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/input.js @@ -0,0 +1,3 @@ +class A { + declare #foo() {} +} diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/options.json b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/options.json new file mode 100644 index 0000000000..3bec5045a3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/options.json @@ -0,0 +1,8 @@ +{ + "sourceType": "module", + "plugins": [ + "flow", + "classPrivateProperties", + "classPrivateMethods" + ] +} diff --git a/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/output.json b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/output.json new file mode 100644 index 0000000000..14ff0e5a49 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-private-property/declare-method/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/input.js new file mode 100644 index 0000000000..6075fd0137 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/input.js @@ -0,0 +1,3 @@ +class A { + @dec declare foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/options.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/options.json new file mode 100644 index 0000000000..71e345f908 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/options.json @@ -0,0 +1,8 @@ +{ + "sourceType": "module", + "plugins": [ + "flow", + "classProperties", + ["decorators", { "decoratorsBeforeExport": false }] + ] +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/output.json new file mode 100644 index 0000000000..8750916dc0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-after-decorators/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/input.js new file mode 100644 index 0000000000..069fd4fb33 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/input.js @@ -0,0 +1,3 @@ +class A { + declare @dec foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/options.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/options.json new file mode 100644 index 0000000000..43ca4a74f8 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-before-decorators/options.json @@ -0,0 +1,9 @@ +{ + "sourceType": "module", + "plugins": [ + "flow", + "classProperties", + ["decorators", { "decoratorsBeforeExport": false }] + ], + "throws": "Unexpected token (2:10)" +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/input.js new file mode 100644 index 0000000000..ad173f3e1a --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/input.js @@ -0,0 +1,3 @@ +class A { + declare constructor() {} +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/output.json new file mode 100644 index 0000000000..af984299b9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-constructor/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/input.js new file mode 100644 index 0000000000..14a7727471 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/input.js @@ -0,0 +1,3 @@ +class A { + declare [foo] +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/output.json new file mode 100644 index 0000000000..722c81c068 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-computed/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/input.js new file mode 100644 index 0000000000..7d9387f547 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/input.js @@ -0,0 +1,3 @@ +class A { + declare foo = 2 +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/output.json new file mode 100644 index 0000000000..0de5fd4795 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-initializer/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/input.js new file mode 100644 index 0000000000..c746a01c76 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/input.js @@ -0,0 +1,3 @@ +class A { + declare static +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/output.json new file mode 100644 index 0000000000..bcba26999c --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-named-static/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/input.js new file mode 100644 index 0000000000..80b1bbb04e --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/input.js @@ -0,0 +1,3 @@ +class A { + declare foo: string +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/output.json new file mode 100644 index 0000000000..03de79fdb3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field-with-type/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/input.js new file mode 100644 index 0000000000..9e7ac1ffb0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/input.js @@ -0,0 +1,3 @@ +class A { + declare foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/output.json new file mode 100644 index 0000000000..ea95861352 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-field/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/input.js new file mode 100644 index 0000000000..0e539a84a2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/input.js @@ -0,0 +1,3 @@ +class A { + declare foo() {} +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/output.json new file mode 100644 index 0000000000..863648b54e --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-method/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/input.js new file mode 100644 index 0000000000..00d59b89a1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/input.js @@ -0,0 +1,3 @@ +class A { + declare static foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/output.json new file mode 100644 index 0000000000..d9c35eafd5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/declare-static-field/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/input.js new file mode 100644 index 0000000000..596b91c311 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/input.js @@ -0,0 +1,3 @@ +class A { + declare: string +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/output.json new file mode 100644 index 0000000000..183b79323c --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare-with-type/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/input.js new file mode 100644 index 0000000000..4d078b4c0c --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/input.js @@ -0,0 +1,3 @@ +class A { + declare +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/output.json new file mode 100644 index 0000000000..87652a453f --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/field-named-declare/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/input.js new file mode 100644 index 0000000000..a1c623ac12 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/input.js @@ -0,0 +1,3 @@ +class A { + declare() {} +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/output.json new file mode 100644 index 0000000000..e11d3c6e16 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/method-named-declare/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/options.json b/packages/babel-parser/test/fixtures/flow/class-properties/options.json new file mode 100644 index 0000000000..f7dcfe201b --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/options.json @@ -0,0 +1,4 @@ +{ + "sourceType": "module", + "plugins": ["flow", "classProperties"] +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/input.js new file mode 100644 index 0000000000..e7eae9b78e --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/input.js @@ -0,0 +1,3 @@ +class A { + static declare foo +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/options.json b/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/options.json new file mode 100644 index 0000000000..43a82ec8a1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/static-declare-field/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (2:17)" +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/input.js b/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/input.js new file mode 100644 index 0000000000..79644eb64f --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/input.js @@ -0,0 +1,3 @@ +class A { + static declare +} diff --git a/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/output.json b/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/output.json new file mode 100644 index 0000000000..5cbe8625f5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/class-properties/static-field-named-declare/output.json @@ -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": [] + } +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-flow-strip-types/src/index.js b/packages/babel-plugin-transform-flow-strip-types/src/index.js index bf4e5acaff..7779fd7523 100644 --- a/packages/babel-plugin-transform-flow-strip-types/src/index.js +++ b/packages/babel-plugin-transform-flow-strip-types/src/index.js @@ -2,13 +2,15 @@ import { declare } from "@babel/helper-plugin-utils"; import syntaxFlow from "@babel/plugin-syntax-flow"; import { types as t } from "@babel/core"; -export default declare(api => { +export default declare((api, opts) => { api.assertVersion(7); const FLOW_DIRECTIVE = /(@flow(\s+(strict(-local)?|weak))?|@noflow)/; let skipStrip = false; + const { requireDirective = false, allowDeclareFields = false } = opts; + return { name: "transform-flow-strip-types", inherits: syntaxFlow, @@ -20,7 +22,6 @@ export default declare(api => { file: { ast: { comments }, }, - opts, }, ) { skipStrip = false; @@ -42,7 +43,7 @@ export default declare(api => { } } - if (!directiveFound && opts.requireDirective) { + if (!directiveFound && requireDirective) { skipStrip = true; } }, @@ -74,13 +75,6 @@ export default declare(api => { path.remove(); }, - ClassProperty(path) { - if (skipStrip) return; - path.node.variance = null; - path.node.typeAnnotation = null; - if (!path.node.value) path.remove(); - }, - ClassPrivateProperty(path) { if (skipStrip) return; path.node.typeAnnotation = null; @@ -94,8 +88,25 @@ export default declare(api => { // would transform the class before we reached the class property. path.get("body.body").forEach(child => { if (child.isClassProperty()) { - child.node.typeAnnotation = null; - if (!child.node.value) child.remove(); + const { node } = child; + + if (!allowDeclareFields && node.declare) { + throw child.buildCodeFrameError( + `The 'declare' modifier is only allowed when the ` + + `'allowDeclareFields' option of ` + + `@babel/plugin-transform-flow-strip-types or ` + + `@babel/preset-flow is enabled.`, + ); + } + + if (node.declare) { + child.remove(); + } else if (!allowDeclareFields && !node.value && !node.decorators) { + child.remove(); + } else { + node.variance = null; + node.typeAnnotation = null; + } } }); }, diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/input.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/input.js new file mode 100644 index 0000000000..3cb9d54665 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/input.js @@ -0,0 +1,3 @@ +class A { + declare x; +} diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/options.json b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/options.json new file mode 100644 index 0000000000..73835049c4 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare-not-enabled/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "transform-flow-strip-types", + "syntax-class-properties" + ], + "throws": "The 'declare' modifier is only allowed when the 'allowDeclareFields' option of @babel/plugin-transform-flow-strip-types or @babel/preset-flow is enabled." +} diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/input.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/input.js new file mode 100644 index 0000000000..7ab37b71fb --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/input.js @@ -0,0 +1,3 @@ +class A { + declare x; +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/options.json b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/options.json new file mode 100644 index 0000000000..f5bedcb81a --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["transform-flow-strip-types", { "allowDeclareFields": true }], + "syntax-class-properties" + ] +} diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/output.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/output.js new file mode 100644 index 0000000000..a869c28495 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/class/declare/output.js @@ -0,0 +1 @@ +class A {} diff --git a/packages/babel-preset-flow/src/index.js b/packages/babel-preset-flow/src/index.js index 6fbd56a196..da02e7e6c0 100644 --- a/packages/babel-preset-flow/src/index.js +++ b/packages/babel-preset-flow/src/index.js @@ -1,10 +1,10 @@ import { declare } from "@babel/helper-plugin-utils"; import transformFlowStripTypes from "@babel/plugin-transform-flow-strip-types"; -export default declare((api, { all }) => { +export default declare((api, { all, allowDeclareFields }) => { api.assertVersion(7); return { - plugins: [[transformFlowStripTypes, { all }]], + plugins: [[transformFlowStripTypes, { all, allowDeclareFields }]], }; });