From 4f394e30d2e008b7b52c5394adb2139582d60202 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Mon, 16 Mar 2020 17:00:17 -0500 Subject: [PATCH] Add support for flow's SymbolTypeAnnotation (#11077) --- .../babel-generator/src/generators/flow.js | 4 + .../fixtures/flow/declare-statements/input.js | 1 + .../flow/declare-statements/output.js | 3 +- .../fixtures/flow/type-annotations/input.js | 1 + .../fixtures/flow/type-annotations/output.js | 3 +- packages/babel-parser/src/plugins/flow.js | 3 + .../flow/declare-statements/symbol/input.js | 1 + .../declare-statements/symbol/output.json | 97 ++++++++++++ .../flow/type-annotations/symbol/input.js | 1 + .../flow/type-annotations/symbol/output.json | 148 ++++++++++++++++++ .../src/asserts/generated/index.js | 6 + .../src/builders/generated/index.js | 4 + packages/babel-types/src/definitions/flow.js | 4 + .../src/validators/generated/index.js | 17 ++ 14 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/flow/declare-statements/symbol/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/declare-statements/symbol/output.json create mode 100644 packages/babel-parser/test/fixtures/flow/type-annotations/symbol/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/type-annotations/symbol/output.json diff --git a/packages/babel-generator/src/generators/flow.js b/packages/babel-generator/src/generators/flow.js index 9a8441ba827c..b39d498eefe3 100644 --- a/packages/babel-generator/src/generators/flow.js +++ b/packages/babel-generator/src/generators/flow.js @@ -596,6 +596,10 @@ export function QualifiedTypeIdentifier(node: Object) { this.print(node.id, node); } +export function SymbolTypeAnnotation() { + this.word("symbol"); +} + function orSeparator() { this.space(); this.token("|"); diff --git a/packages/babel-generator/test/fixtures/flow/declare-statements/input.js b/packages/babel-generator/test/fixtures/flow/declare-statements/input.js index 3a2d2aa6a74e..7b2571e32867 100644 --- a/packages/babel-generator/test/fixtures/flow/declare-statements/input.js +++ b/packages/babel-generator/test/fixtures/flow/declare-statements/input.js @@ -23,3 +23,4 @@ declare opaque type Foo: Bar; declare opaque type ID; declare opaque type num: number; declare opaque type NumArray; +declare var sym: symbol; diff --git a/packages/babel-generator/test/fixtures/flow/declare-statements/output.js b/packages/babel-generator/test/fixtures/flow/declare-statements/output.js index c5f087d49ab0..beede465d3df 100644 --- a/packages/babel-generator/test/fixtures/flow/declare-statements/output.js +++ b/packages/babel-generator/test/fixtures/flow/declare-statements/output.js @@ -41,4 +41,5 @@ declare module.exports: { declare opaque type Foo: Bar; declare opaque type ID; declare opaque type num: number; -declare opaque type NumArray; \ No newline at end of file +declare opaque type NumArray; +declare var sym: symbol; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/flow/type-annotations/input.js b/packages/babel-generator/test/fixtures/flow/type-annotations/input.js index e7335c30b72a..846595e9453e 100644 --- a/packages/babel-generator/test/fixtures/flow/type-annotations/input.js +++ b/packages/babel-generator/test/fixtures/flow/type-annotations/input.js @@ -128,3 +128,4 @@ var a34: {| id(x: T): T; |}; function foo27(numVal: number = 2) {} function foo28(numVal?: number = 2) {} export type * from "foo"; +const foo29: symbol = Symbol(); diff --git a/packages/babel-generator/test/fixtures/flow/type-annotations/output.js b/packages/babel-generator/test/fixtures/flow/type-annotations/output.js index 6465359f336d..71548b99c5ab 100644 --- a/packages/babel-generator/test/fixtures/flow/type-annotations/output.js +++ b/packages/babel-generator/test/fixtures/flow/type-annotations/output.js @@ -293,4 +293,5 @@ function foo27(numVal: number = 2) {} function foo28(numVal?: number = 2) {} -export type * from "foo"; \ No newline at end of file +export type * from "foo"; +const foo29: symbol = Symbol(); \ No newline at end of file diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index 0f9958c4a66b..2f32adcb99b2 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -1333,6 +1333,9 @@ export default (superClass: Class): Class => case "string": return this.finishNode(node, "StringTypeAnnotation"); + case "symbol": + return this.finishNode(node, "SymbolTypeAnnotation"); + default: this.checkNotUnderscore(id.name); return this.flowParseGenericType(startPos, startLoc, id); diff --git a/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/input.js b/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/input.js new file mode 100644 index 000000000000..d91b81ba9d76 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/input.js @@ -0,0 +1 @@ +declare var x: symbol; diff --git a/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/output.json b/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/output.json new file mode 100644 index 000000000000..15a3bbe3f580 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/declare-statements/symbol/output.json @@ -0,0 +1,97 @@ +{ + "type": "File", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "DeclareVariable", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "id": { + "type": "Identifier", + "start": 12, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 21 + }, + "identifierName": "x" + }, + "name": "x", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 13, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "typeAnnotation": { + "type": "SymbolTypeAnnotation", + "start": 15, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 21 + } + } + } + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/input.js b/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/input.js new file mode 100644 index 000000000000..90e1dd31feb3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/input.js @@ -0,0 +1 @@ +const x: symbol = Symbol(); diff --git a/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/output.json b/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/output.json new file mode 100644 index 000000000000..cc436b3b0505 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/type-annotations/symbol/output.json @@ -0,0 +1,148 @@ +{ + "type": "File", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 7, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "typeAnnotation": { + "type": "SymbolTypeAnnotation", + "start": 9, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 15 + } + } + } + } + }, + "init": { + "type": "CallExpression", + "start": 18, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "callee": { + "type": "Identifier", + "start": 18, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 24 + }, + "identifierName": "Symbol" + }, + "name": "Symbol" + }, + "arguments": [] + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-types/src/asserts/generated/index.js b/packages/babel-types/src/asserts/generated/index.js index 9f2ebce70e4a..b6bbfa0a1b01 100644 --- a/packages/babel-types/src/asserts/generated/index.js +++ b/packages/babel-types/src/asserts/generated/index.js @@ -524,6 +524,12 @@ export function assertStringTypeAnnotation( ): void { assert("StringTypeAnnotation", node, opts); } +export function assertSymbolTypeAnnotation( + node: Object, + opts?: Object = {}, +): void { + assert("SymbolTypeAnnotation", node, opts); +} export function assertThisTypeAnnotation( node: Object, opts?: Object = {}, diff --git a/packages/babel-types/src/builders/generated/index.js b/packages/babel-types/src/builders/generated/index.js index 8aebb3a8d830..c80d440a6c90 100644 --- a/packages/babel-types/src/builders/generated/index.js +++ b/packages/babel-types/src/builders/generated/index.js @@ -469,6 +469,10 @@ export function StringTypeAnnotation(...args: Array): Object { return builder("StringTypeAnnotation", ...args); } export { StringTypeAnnotation as stringTypeAnnotation }; +export function SymbolTypeAnnotation(...args: Array): Object { + return builder("SymbolTypeAnnotation", ...args); +} +export { SymbolTypeAnnotation as symbolTypeAnnotation }; export function ThisTypeAnnotation(...args: Array): Object { return builder("ThisTypeAnnotation", ...args); } diff --git a/packages/babel-types/src/definitions/flow.js b/packages/babel-types/src/definitions/flow.js index 8620e1bbba84..182b6fec6e4e 100644 --- a/packages/babel-types/src/definitions/flow.js +++ b/packages/babel-types/src/definitions/flow.js @@ -372,6 +372,10 @@ defineType("StringTypeAnnotation", { aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); +defineType("SymbolTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], +}); + defineType("ThisTypeAnnotation", { aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); diff --git a/packages/babel-types/src/validators/generated/index.js b/packages/babel-types/src/validators/generated/index.js index 7ddf2fa31560..9eaf2d0f612e 100644 --- a/packages/babel-types/src/validators/generated/index.js +++ b/packages/babel-types/src/validators/generated/index.js @@ -1692,6 +1692,20 @@ export function isStringTypeAnnotation(node: ?Object, opts?: Object): boolean { return false; } +export function isSymbolTypeAnnotation(node: ?Object, opts?: Object): boolean { + if (!node) return false; + + const nodeType = node.type; + if (nodeType === "SymbolTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return shallowEqual(node, opts); + } + } + + return false; +} export function isThisTypeAnnotation(node: ?Object, opts?: Object): boolean { if (!node) return false; @@ -4270,6 +4284,7 @@ export function isFlow(node: ?Object, opts?: Object): boolean { "QualifiedTypeIdentifier" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || + "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || @@ -4316,6 +4331,7 @@ export function isFlowType(node: ?Object, opts?: Object): boolean { "ObjectTypeAnnotation" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || + "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || @@ -4344,6 +4360,7 @@ export function isFlowBaseAnnotation(node: ?Object, opts?: Object): boolean { "EmptyTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || + "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "VoidTypeAnnotation" === nodeType ) {