Parse type imports in TSImportEqualsDeclaration (#12962)

This commit is contained in:
Huáng Jùnliàng 2021-03-14 18:34:49 -04:00 committed by GitHub
parent 1a05b81387
commit 0988c471e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 413 additions and 11 deletions

View File

@ -77,6 +77,7 @@ const TSErrors = Object.freeze({
EmptyTypeParameters: "Type parameter list cannot be empty.",
ExpectedAmbientAfterExportDeclare:
"'export declare' must be followed by an ambient declaration.",
ImportAliasHasImportType: "An import alias can not use 'import type'",
IndexSignatureHasAbstract:
"Index signatures cannot have the 'abstract' modifier",
IndexSignatureHasAccessibility:
@ -1482,7 +1483,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node.id = this.parseIdentifier();
this.checkLVal(node.id, "import equals declaration", BIND_LEXICAL);
this.expect(tt.eq);
node.moduleReference = this.tsParseModuleReference();
const moduleReference = this.tsParseModuleReference();
if (
node.importKind === "type" &&
moduleReference.type !== "TSExternalModuleReference"
) {
this.raise(moduleReference.start, TSErrors.ImportAliasHasImportType);
}
node.moduleReference = moduleReference;
this.semicolon();
return this.finishNode(node, "TSImportEqualsDeclaration");
}
@ -2052,27 +2060,27 @@ export default (superClass: Class<Parser>): Class<Parser> =>
checkDuplicateExports() {}
parseImport(node: N.Node): N.AnyImport {
node.importKind = "value";
if (this.match(tt.name) || this.match(tt.star) || this.match(tt.braceL)) {
const ahead = this.lookahead();
if (this.match(tt.name) && ahead.type === tt.eq) {
return this.tsParseImportEqualsDeclaration(node);
}
let ahead = this.lookahead();
if (
this.isContextual("type") &&
// import type, { a } from "b";
ahead.type !== tt.comma &&
// import type from "a";
!(ahead.type === tt.name && ahead.value === "from")
!(ahead.type === tt.name && ahead.value === "from") &&
// import type = require("a");
ahead.type !== tt.eq
) {
node.importKind = "type";
this.next();
}
ahead = this.lookahead();
}
if (!node.importKind) {
node.importKind = "value";
if (this.match(tt.name) && ahead.type === tt.eq) {
return this.tsParseImportEqualsDeclaration(node);
}
}
const importNode = super.parseImport(node);
@ -2097,7 +2105,16 @@ export default (superClass: Class<Parser>): Class<Parser> =>
parseExport(node: N.Node): N.AnyExport {
if (this.match(tt._import)) {
// `export import A = B;`
this.expect(tt._import);
this.next(); // eat `tt._import`
if (
this.isContextual("type") &&
this.lookaheadCharCode() !== charCodes.equalsTo
) {
node.importKind = "type";
this.next(); // eat "type"
} else {
node.importKind = "value";
}
return this.tsParseImportEqualsDeclaration(node, /* isExport */ true);
} else if (this.eat(tt.eq)) {
// `export = x;`

View File

@ -1461,6 +1461,7 @@ export type TsImportEqualsDeclaration = NodeBase & {
type: "TSImportEqualsDeclaration",
isExport: boolean,
id: Identifier,
importKind: "type" | "value",
moduleReference: TsModuleReference,
};

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":32,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":32}},
"importKind": "value",
"isExport": false,
"id": {
"type": "Identifier",

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":24,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":24}},
"importKind": "value",
"isExport": false,
"id": {
"type": "Identifier",

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":15,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":15}},
"importKind": "value",
"isExport": false,
"id": {
"type": "Identifier",

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":31,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},
"importKind": "value",
"isExport": true,
"id": {
"type": "Identifier",

View File

@ -0,0 +1 @@
export import type = require("A");

View File

@ -0,0 +1,37 @@
{
"type": "File",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":34}},
"program": {
"type": "Program",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":34}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":34}},
"importKind": "value",
"isExport": true,
"id": {
"type": "Identifier",
"start":14,"end":18,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":18},"identifierName":"type"},
"name": "type"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":21,"end":33,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":33}},
"expression": {
"type": "StringLiteral",
"start":29,"end":32,"loc":{"start":{"line":1,"column":29},"end":{"line":1,"column":32}},
"extra": {
"rawValue": "A",
"raw": "\"A\""
},
"value": "A"
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
export import type a = require("a");

View File

@ -0,0 +1,37 @@
{
"type": "File",
"start":0,"end":36,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":36}},
"program": {
"type": "Program",
"start":0,"end":36,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":36}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":36,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":36}},
"importKind": "type",
"isExport": true,
"id": {
"type": "Identifier",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20},"identifierName":"a"},
"name": "a"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":23,"end":35,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":35}},
"expression": {
"type": "StringLiteral",
"start":31,"end":34,"loc":{"start":{"line":1,"column":31},"end":{"line":1,"column":34}},
"extra": {
"rawValue": "a",
"raw": "\"a\""
},
"value": "a"
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
export import type A = B.C;

View File

@ -0,0 +1,41 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"errors": [
"SyntaxError: An import alias can not use 'import type' (1:23)"
],
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"importKind": "type",
"isExport": true,
"id": {
"type": "Identifier",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20},"identifierName":"A"},
"name": "A"
},
"moduleReference": {
"type": "TSQualifiedName",
"start":23,"end":26,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":26}},
"left": {
"type": "Identifier",
"start":23,"end":24,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":24},"identifierName":"B"},
"name": "B"
},
"right": {
"type": "Identifier",
"start":25,"end":26,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":26},"identifierName":"C"},
"name": "C"
}
}
}
],
"directives": []
}
}

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":22}},
"importKind": "value",
"isExport": true,
"id": {
"type": "Identifier",

View File

@ -10,6 +10,7 @@
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":24,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":24}},
"importKind": "value",
"isExport": false,
"id": {
"type": "Identifier",

View File

@ -0,0 +1 @@
import type = require("A");

View File

@ -0,0 +1,37 @@
{
"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": "TSImportEqualsDeclaration",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"importKind": "value",
"isExport": false,
"id": {
"type": "Identifier",
"start":7,"end":11,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":11},"identifierName":"type"},
"name": "type"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":14,"end":26,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":26}},
"expression": {
"type": "StringLiteral",
"start":22,"end":25,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":25}},
"extra": {
"rawValue": "A",
"raw": "\"A\""
},
"value": "A"
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,15 @@
import type
A = require("A");
import
type
a = require("a");
export import
type
B = require("B");
export
import
type
b = require("b");

View File

@ -0,0 +1,109 @@
{
"type": "File",
"start":0,"end":136,"loc":{"start":{"line":1,"column":0},"end":{"line":15,"column":17}},
"program": {
"type": "Program",
"start":0,"end":136,"loc":{"start":{"line":1,"column":0},"end":{"line":15,"column":17}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":17}},
"importKind": "type",
"isExport": false,
"id": {
"type": "Identifier",
"start":12,"end":13,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":1},"identifierName":"A"},
"name": "A"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":16,"end":28,"loc":{"start":{"line":2,"column":4},"end":{"line":2,"column":16}},
"expression": {
"type": "StringLiteral",
"start":24,"end":27,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":15}},
"extra": {
"rawValue": "A",
"raw": "\"A\""
},
"value": "A"
}
}
},
{
"type": "TSImportEqualsDeclaration",
"start":31,"end":60,"loc":{"start":{"line":4,"column":0},"end":{"line":6,"column":17}},
"importKind": "type",
"isExport": false,
"id": {
"type": "Identifier",
"start":43,"end":44,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":1},"identifierName":"a"},
"name": "a"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":47,"end":59,"loc":{"start":{"line":6,"column":4},"end":{"line":6,"column":16}},
"expression": {
"type": "StringLiteral",
"start":55,"end":58,"loc":{"start":{"line":6,"column":12},"end":{"line":6,"column":15}},
"extra": {
"rawValue": "a",
"raw": "\"a\""
},
"value": "a"
}
}
},
{
"type": "TSImportEqualsDeclaration",
"start":62,"end":98,"loc":{"start":{"line":8,"column":0},"end":{"line":10,"column":17}},
"importKind": "type",
"isExport": true,
"id": {
"type": "Identifier",
"start":81,"end":82,"loc":{"start":{"line":10,"column":0},"end":{"line":10,"column":1},"identifierName":"B"},
"name": "B"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":85,"end":97,"loc":{"start":{"line":10,"column":4},"end":{"line":10,"column":16}},
"expression": {
"type": "StringLiteral",
"start":93,"end":96,"loc":{"start":{"line":10,"column":12},"end":{"line":10,"column":15}},
"extra": {
"rawValue": "B",
"raw": "\"B\""
},
"value": "B"
}
}
},
{
"type": "TSImportEqualsDeclaration",
"start":100,"end":136,"loc":{"start":{"line":12,"column":0},"end":{"line":15,"column":17}},
"importKind": "type",
"isExport": true,
"id": {
"type": "Identifier",
"start":119,"end":120,"loc":{"start":{"line":15,"column":0},"end":{"line":15,"column":1},"identifierName":"b"},
"name": "b"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":123,"end":135,"loc":{"start":{"line":15,"column":4},"end":{"line":15,"column":16}},
"expression": {
"type": "StringLiteral",
"start":131,"end":134,"loc":{"start":{"line":15,"column":12},"end":{"line":15,"column":15}},
"extra": {
"rawValue": "b",
"raw": "\"b\""
},
"value": "b"
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
import type a = require("a");

View File

@ -0,0 +1,37 @@
{
"type": "File",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"program": {
"type": "Program",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"importKind": "type",
"isExport": false,
"id": {
"type": "Identifier",
"start":12,"end":13,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":13},"identifierName":"a"},
"name": "a"
},
"moduleReference": {
"type": "TSExternalModuleReference",
"start":16,"end":28,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":28}},
"expression": {
"type": "StringLiteral",
"start":24,"end":27,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":27}},
"extra": {
"rawValue": "a",
"raw": "\"a\""
},
"value": "a"
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,2 @@
import type A = B.C;
import type B = C;

View File

@ -0,0 +1,58 @@
{
"type": "File",
"start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":18}},
"errors": [
"SyntaxError: An import alias can not use 'import type' (1:16)",
"SyntaxError: An import alias can not use 'import type' (2:16)"
],
"program": {
"type": "Program",
"start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":18}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSImportEqualsDeclaration",
"start":0,"end":20,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":20}},
"importKind": "type",
"isExport": false,
"id": {
"type": "Identifier",
"start":12,"end":13,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":13},"identifierName":"A"},
"name": "A"
},
"moduleReference": {
"type": "TSQualifiedName",
"start":16,"end":19,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":19}},
"left": {
"type": "Identifier",
"start":16,"end":17,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":17},"identifierName":"B"},
"name": "B"
},
"right": {
"type": "Identifier",
"start":18,"end":19,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":19},"identifierName":"C"},
"name": "C"
}
}
},
{
"type": "TSImportEqualsDeclaration",
"start":21,"end":39,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":18}},
"importKind": "type",
"isExport": false,
"id": {
"type": "Identifier",
"start":33,"end":34,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":13},"identifierName":"B"},
"name": "B"
},
"moduleReference": {
"type": "Identifier",
"start":37,"end":38,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":17},"identifierName":"C"},
"name": "C"
}
}
],
"directives": []
}
}