From 04a0cc7708cba1d15dac24cd8c2f5dd187a052ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Tue, 6 Oct 2020 23:34:40 +0200 Subject: [PATCH 1/2] [ts] Add support for the "intrinsic" keyword --- .../src/generators/typescript.js | 3 + .../typescript/types-keywords/input.js | 1 + .../typescript/types-keywords/output.js | 1 + .../src/plugins/typescript/index.js | 14 +- packages/babel-parser/src/types.js | 3 +- .../types/intrinsic-identifier/input.ts | 5 + .../types/intrinsic-identifier/output.json | 161 ++++++++++++++++++ .../types/intrinsic-keyword-error/input.ts | 2 + .../intrinsic-keyword-error/options.json | 3 + .../types/intrinsic-keyword/input.ts | 2 + .../types/intrinsic-keyword/output.json | 50 ++++++ .../src/asserts/generated/index.js | 6 + .../src/builders/generated/index.js | 5 + .../babel-types/src/definitions/typescript.js | 1 + .../src/validators/generated/index.js | 16 ++ 15 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/options.json create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/output.json diff --git a/packages/babel-generator/src/generators/typescript.js b/packages/babel-generator/src/generators/typescript.js index dbdb5bce7fb4..30fa7f5d6eb3 100644 --- a/packages/babel-generator/src/generators/typescript.js +++ b/packages/babel-generator/src/generators/typescript.js @@ -162,6 +162,9 @@ export function TSNullKeyword() { export function TSNeverKeyword() { this.word("never"); } +export function TSIntrinsicKeyword() { + this.word("intrinsic"); +} export function TSThisType() { this.word("this"); diff --git a/packages/babel-generator/test/fixtures/typescript/types-keywords/input.js b/packages/babel-generator/test/fixtures/typescript/types-keywords/input.js index 0fec8f608a1c..fcb1d46a13dc 100644 --- a/packages/babel-generator/test/fixtures/typescript/types-keywords/input.js +++ b/packages/babel-generator/test/fixtures/typescript/types-keywords/input.js @@ -9,3 +9,4 @@ let st: string; let sy: symbol; let u: undefined; let v: void; +type Foo = intrinsic; diff --git a/packages/babel-generator/test/fixtures/typescript/types-keywords/output.js b/packages/babel-generator/test/fixtures/typescript/types-keywords/output.js index 0fec8f608a1c..fcb1d46a13dc 100644 --- a/packages/babel-generator/test/fixtures/typescript/types-keywords/output.js +++ b/packages/babel-generator/test/fixtures/typescript/types-keywords/output.js @@ -9,3 +9,4 @@ let st: string; let sy: symbol; let u: undefined; let v: void; +type Foo = intrinsic; diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 1b9b7f1f3e83..cd99c6abfe24 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -113,6 +113,7 @@ const TSErrors = Object.freeze({ }); // Doesn't handle "void" or "null" because those are keywords, not identifiers. +// It also doesn't handle "intrinsic", since usually it's not a keyword. function keywordTypeFromName( value: string, ): N.TsKeywordTypeType | typeof undefined { @@ -1242,7 +1243,18 @@ export default (superClass: Class): Class => this.checkLVal(node.id, BIND_TS_TYPE, undefined, "typescript type alias"); node.typeParameters = this.tsTryParseTypeParameters(); - node.typeAnnotation = this.tsExpectThenParseType(tt.eq); + node.typeAnnotation = this.tsInType(() => { + this.expect(tt.eq); + + if (this.isContextual("intrinsic")) { + const node: N.TsKeywordType = this.startNode(); + this.next(); + return this.finishNode(node, "TSIntrinsicKeyword"); + } + + return this.tsParseType(); + }); + this.semicolon(); return this.finishNode(node, "TSTypeAliasDeclaration"); } diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.js index 6d77c5c0d00d..38f2f35c05c9 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.js @@ -1215,7 +1215,8 @@ export type TsKeywordTypeType = | "TSVoidKeyword" | "TSUndefinedKeyword" | "TSNullKeyword" - | "TSNeverKeyword"; + | "TSNeverKeyword" + | "TSIntrinsicKeyword"; export type TsKeywordType = TsTypeBase & { type: TsKeywordTypeType, }; diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts new file mode 100644 index 000000000000..debd9f06bda3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts @@ -0,0 +1,5 @@ +type intrinsic = 2; +function foo(x: intrinsic): intrinsic { + var a: intrinsic = 2; + type X = 1 | intrinsic; +} diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json new file mode 100644 index 000000000000..59f9b94d5514 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json @@ -0,0 +1,161 @@ +{ + "type": "File", + "start":0,"end":111,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":111,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSTypeAliasDeclaration", + "start":0,"end":19,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":19}}, + "id": { + "type": "Identifier", + "start":5,"end":14,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":14},"identifierName":"intrinsic"}, + "name": "intrinsic" + }, + "typeAnnotation": { + "type": "TSLiteralType", + "start":17,"end":18,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":18}}, + "literal": { + "type": "NumericLiteral", + "start":17,"end":18,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":18}}, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + } + }, + { + "type": "FunctionDeclaration", + "start":20,"end":111,"loc":{"start":{"line":2,"column":0},"end":{"line":5,"column":1}}, + "id": { + "type": "Identifier", + "start":29,"end":32,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start":33,"end":45,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":25},"identifierName":"x"}, + "name": "x", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":34,"end":45,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":25}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":36,"end":45,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":25}}, + "typeName": { + "type": "Identifier", + "start":36,"end":45,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":25},"identifierName":"intrinsic"}, + "name": "intrinsic" + } + } + } + } + ], + "returnType": { + "type": "TSTypeAnnotation", + "start":46,"end":57,"loc":{"start":{"line":2,"column":26},"end":{"line":2,"column":37}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":48,"end":57,"loc":{"start":{"line":2,"column":28},"end":{"line":2,"column":37}}, + "typeName": { + "type": "Identifier", + "start":48,"end":57,"loc":{"start":{"line":2,"column":28},"end":{"line":2,"column":37},"identifierName":"intrinsic"}, + "name": "intrinsic" + } + } + }, + "body": { + "type": "BlockStatement", + "start":58,"end":111,"loc":{"start":{"line":2,"column":38},"end":{"line":5,"column":1}}, + "body": [ + { + "type": "VariableDeclaration", + "start":62,"end":83,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":23}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":66,"end":82,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":22}}, + "id": { + "type": "Identifier", + "start":66,"end":78,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":18},"identifierName":"a"}, + "name": "a", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":67,"end":78,"loc":{"start":{"line":3,"column":7},"end":{"line":3,"column":18}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":69,"end":78,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":18}}, + "typeName": { + "type": "Identifier", + "start":69,"end":78,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":18},"identifierName":"intrinsic"}, + "name": "intrinsic" + } + } + } + }, + "init": { + "type": "NumericLiteral", + "start":81,"end":82,"loc":{"start":{"line":3,"column":21},"end":{"line":3,"column":22}}, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + } + ], + "kind": "var" + }, + { + "type": "TSTypeAliasDeclaration", + "start":86,"end":109,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":25}}, + "id": { + "type": "Identifier", + "start":91,"end":92,"loc":{"start":{"line":4,"column":7},"end":{"line":4,"column":8},"identifierName":"X"}, + "name": "X" + }, + "typeAnnotation": { + "type": "TSUnionType", + "start":95,"end":108,"loc":{"start":{"line":4,"column":11},"end":{"line":4,"column":24}}, + "types": [ + { + "type": "TSLiteralType", + "start":95,"end":96,"loc":{"start":{"line":4,"column":11},"end":{"line":4,"column":12}}, + "literal": { + "type": "NumericLiteral", + "start":95,"end":96,"loc":{"start":{"line":4,"column":11},"end":{"line":4,"column":12}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "TSTypeReference", + "start":99,"end":108,"loc":{"start":{"line":4,"column":15},"end":{"line":4,"column":24}}, + "typeName": { + "type": "Identifier", + "start":99,"end":108,"loc":{"start":{"line":4,"column":15},"end":{"line":4,"column":24},"identifierName":"intrinsic"}, + "name": "intrinsic" + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/input.ts b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/input.ts new file mode 100644 index 000000000000..377c610e285c --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/input.ts @@ -0,0 +1,2 @@ +type Foo = intrinsic["foo"]; + diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/options.json b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/options.json new file mode 100644 index 000000000000..640cd6c71b99 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword-error/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected \";\" (1:20)" +} diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/input.ts b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/input.ts new file mode 100644 index 000000000000..943c60afcbb6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/input.ts @@ -0,0 +1,2 @@ +type Foo = intrinsic; +type Bar = intrinsic; diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/output.json b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/output.json new file mode 100644 index 000000000000..9b61e78eb132 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-keyword/output.json @@ -0,0 +1,50 @@ +{ + "type": "File", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":24}}, + "program": { + "type": "Program", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":24}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSTypeAliasDeclaration", + "start":0,"end":21,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":21}}, + "id": { + "type": "Identifier", + "start":5,"end":8,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":8},"identifierName":"Foo"}, + "name": "Foo" + }, + "typeAnnotation": { + "type": "TSIntrinsicKeyword", + "start":11,"end":20,"loc":{"start":{"line":1,"column":11},"end":{"line":1,"column":20}} + } + }, + { + "type": "TSTypeAliasDeclaration", + "start":22,"end":46,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":24}}, + "id": { + "type": "Identifier", + "start":27,"end":30,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":8},"identifierName":"Bar"}, + "name": "Bar" + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "start":30,"end":33,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":11}}, + "params": [ + { + "type": "TSTypeParameter", + "start":31,"end":32,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":10}}, + "name": "T" + } + ] + }, + "typeAnnotation": { + "type": "TSIntrinsicKeyword", + "start":36,"end":45,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":23}} + } + } + ], + "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 23a3e3cbb9e2..1b29fa2e376e 100644 --- a/packages/babel-types/src/asserts/generated/index.js +++ b/packages/babel-types/src/asserts/generated/index.js @@ -857,6 +857,12 @@ export function assertTSBooleanKeyword(node: Object, opts?: Object = {}): void { export function assertTSBigIntKeyword(node: Object, opts?: Object = {}): void { assert("TSBigIntKeyword", node, opts); } +export function assertTSIntrinsicKeyword( + node: Object, + opts?: Object = {}, +): void { + assert("TSIntrinsicKeyword", node, opts); +} export function assertTSNeverKeyword(node: Object, opts?: Object = {}): void { assert("TSNeverKeyword", node, opts); } diff --git a/packages/babel-types/src/builders/generated/index.js b/packages/babel-types/src/builders/generated/index.js index 44b76e7aea31..dd5b921ee20b 100644 --- a/packages/babel-types/src/builders/generated/index.js +++ b/packages/babel-types/src/builders/generated/index.js @@ -794,6 +794,11 @@ export function tsBigIntKeyword(...args: Array): Object { } export { tsBigIntKeyword as TSBigIntKeyword }; export { tsBigIntKeyword as tSBigIntKeyword }; +export function tsIntrinsicKeyword(...args: Array): Object { + return builder("TSIntrinsicKeyword", ...args); +} +export { tsIntrinsicKeyword as TSIntrinsicKeyword }; +export { tsIntrinsicKeyword as tSIntrinsicKeyword }; export function tsNeverKeyword(...args: Array): Object { return builder("TSNeverKeyword", ...args); } diff --git a/packages/babel-types/src/definitions/typescript.js b/packages/babel-types/src/definitions/typescript.js index 05e2e6f7e5f0..5ed15a6906c5 100644 --- a/packages/babel-types/src/definitions/typescript.js +++ b/packages/babel-types/src/definitions/typescript.js @@ -132,6 +132,7 @@ const tsKeywordTypes = [ "TSAnyKeyword", "TSBooleanKeyword", "TSBigIntKeyword", + "TSIntrinsicKeyword", "TSNeverKeyword", "TSNullKeyword", "TSNumberKeyword", diff --git a/packages/babel-types/src/validators/generated/index.js b/packages/babel-types/src/validators/generated/index.js index a5c5b68bdf7b..6b7d0132e715 100644 --- a/packages/babel-types/src/validators/generated/index.js +++ b/packages/babel-types/src/validators/generated/index.js @@ -2761,6 +2761,20 @@ export function isTSBigIntKeyword(node: ?Object, opts?: Object): boolean { return false; } +export function isTSIntrinsicKeyword(node: ?Object, opts?: Object): boolean { + if (!node) return false; + + const nodeType = node.type; + if (nodeType === "TSIntrinsicKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return shallowEqual(node, opts); + } + } + + return false; +} export function isTSNeverKeyword(node: ?Object, opts?: Object): boolean { if (!node) return false; @@ -4616,6 +4630,7 @@ export function isTSType(node: ?Object, opts?: Object): boolean { "TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || + "TSIntrinsicKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || @@ -4666,6 +4681,7 @@ export function isTSBaseType(node: ?Object, opts?: Object): boolean { "TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || + "TSIntrinsicKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || From 5f47c84725a035ddaf2957cc57c4b876b396327c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 7 Oct 2020 19:18:50 +0200 Subject: [PATCH 2/2] intrinsic.foo is not a keyword --- .../src/plugins/typescript/index.js | 5 ++- .../types/intrinsic-identifier/input.ts | 1 + .../types/intrinsic-identifier/output.json | 35 ++++++++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index cd99c6abfe24..a5b35d1badb4 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -1246,7 +1246,10 @@ export default (superClass: Class): Class => node.typeAnnotation = this.tsInType(() => { this.expect(tt.eq); - if (this.isContextual("intrinsic")) { + if ( + this.isContextual("intrinsic") && + this.lookahead().type !== tt.dot + ) { const node: N.TsKeywordType = this.startNode(); this.next(); return this.finishNode(node, "TSIntrinsicKeyword"); diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts index debd9f06bda3..61c4910fa7e9 100644 --- a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/input.ts @@ -2,4 +2,5 @@ type intrinsic = 2; function foo(x: intrinsic): intrinsic { var a: intrinsic = 2; type X = 1 | intrinsic; + type Foo = intrinsic.bar; } diff --git a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json index 59f9b94d5514..062e0534a46d 100644 --- a/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json +++ b/packages/babel-parser/test/fixtures/typescript/types/intrinsic-identifier/output.json @@ -1,9 +1,9 @@ { "type": "File", - "start":0,"end":111,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "start":0,"end":139,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, "program": { "type": "Program", - "start":0,"end":111,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "start":0,"end":139,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, "sourceType": "module", "interpreter": null, "body": [ @@ -31,7 +31,7 @@ }, { "type": "FunctionDeclaration", - "start":20,"end":111,"loc":{"start":{"line":2,"column":0},"end":{"line":5,"column":1}}, + "start":20,"end":139,"loc":{"start":{"line":2,"column":0},"end":{"line":6,"column":1}}, "id": { "type": "Identifier", "start":29,"end":32,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, @@ -74,7 +74,7 @@ }, "body": { "type": "BlockStatement", - "start":58,"end":111,"loc":{"start":{"line":2,"column":38},"end":{"line":5,"column":1}}, + "start":58,"end":139,"loc":{"start":{"line":2,"column":38},"end":{"line":6,"column":1}}, "body": [ { "type": "VariableDeclaration", @@ -150,6 +150,33 @@ } ] } + }, + { + "type": "TSTypeAliasDeclaration", + "start":112,"end":137,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":27}}, + "id": { + "type": "Identifier", + "start":117,"end":120,"loc":{"start":{"line":5,"column":7},"end":{"line":5,"column":10},"identifierName":"Foo"}, + "name": "Foo" + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start":123,"end":136,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":26}}, + "typeName": { + "type": "TSQualifiedName", + "start":123,"end":136,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":26}}, + "left": { + "type": "Identifier", + "start":123,"end":132,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":22},"identifierName":"intrinsic"}, + "name": "intrinsic" + }, + "right": { + "type": "Identifier", + "start":133,"end":136,"loc":{"start":{"line":5,"column":23},"end":{"line":5,"column":26},"identifierName":"bar"}, + "name": "bar" + } + } + } } ], "directives": []