Support TypeScript 4.2 abstract constructor signatures (#12628)
Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com> Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
74dc70aabb
commit
e4588bed22
@ -194,6 +194,10 @@ export function TSFunctionType(this: Printer, node: t.TSFunctionType) {
|
||||
}
|
||||
|
||||
export function TSConstructorType(this: Printer, node: t.TSConstructorType) {
|
||||
if (node.abstract) {
|
||||
this.word("abstract");
|
||||
this.space();
|
||||
}
|
||||
this.word("new");
|
||||
this.space();
|
||||
this.tsPrintFunctionOrConstructorType(node);
|
||||
|
||||
@ -0,0 +1 @@
|
||||
const x: abstract new () => void;
|
||||
@ -0,0 +1 @@
|
||||
const x: abstract new () => void;
|
||||
1
packages/babel-generator/test/fixtures/typescript/constructor-signature-types/input.js
vendored
Normal file
1
packages/babel-generator/test/fixtures/typescript/constructor-signature-types/input.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
const x: new () => void;
|
||||
1
packages/babel-generator/test/fixtures/typescript/constructor-signature-types/output.js
vendored
Normal file
1
packages/babel-generator/test/fixtures/typescript/constructor-signature-types/output.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
const x: new () => void;
|
||||
@ -790,10 +790,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
|
||||
tsParseFunctionOrConstructorType(
|
||||
type: "TSFunctionType" | "TSConstructorType",
|
||||
abstract?: boolean,
|
||||
): N.TsFunctionOrConstructorType {
|
||||
const node: N.TsFunctionOrConstructorType = this.startNode();
|
||||
if (type === "TSConstructorType") {
|
||||
this.expect(tt._new);
|
||||
// $FlowIgnore
|
||||
node.abstract = !!abstract;
|
||||
if (abstract) this.next();
|
||||
this.next(); // eat `new`
|
||||
}
|
||||
this.tsFillSignature(tt.arrow, node);
|
||||
return this.finishNode(node, type);
|
||||
@ -1219,6 +1223,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
return this.finishNode(node, "TSConditionalType");
|
||||
}
|
||||
|
||||
isAbstractConstructorSignature(): boolean {
|
||||
return this.isContextual("abstract") && this.lookahead().type === tt._new;
|
||||
}
|
||||
|
||||
tsParseNonConditionalType(): N.TsType {
|
||||
if (this.tsIsStartOfFunctionType()) {
|
||||
return this.tsParseFunctionOrConstructorType("TSFunctionType");
|
||||
@ -1226,6 +1234,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
if (this.match(tt._new)) {
|
||||
// As in `new () => Date`
|
||||
return this.tsParseFunctionOrConstructorType("TSConstructorType");
|
||||
} else if (this.isAbstractConstructorSignature()) {
|
||||
// As in `abstract new () => Date`
|
||||
return this.tsParseFunctionOrConstructorType(
|
||||
"TSConstructorType",
|
||||
/* abstract */ true,
|
||||
);
|
||||
}
|
||||
return this.tsParseUnionTypeOrHigher();
|
||||
}
|
||||
|
||||
@ -1250,6 +1250,7 @@ export type TsConstructorType = TsTypeBase &
|
||||
TsSignatureDeclarationBase & {
|
||||
type: "TSConstructorType",
|
||||
typeAnnotation: TsTypeAnnotation,
|
||||
abstract: boolean,
|
||||
};
|
||||
|
||||
export type TsTypeReference = TsTypeBase & {
|
||||
|
||||
@ -0,0 +1 @@
|
||||
let x: abstract new () => void = X;
|
||||
52
packages/babel-parser/test/fixtures/typescript/types/abstract-constructor-signatures/output.json
vendored
Normal file
52
packages/babel-parser/test/fixtures/typescript/types/abstract-constructor-signatures/output.json
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start":4,"end":34,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":34}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":4,"end":30,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":30},"identifierName":"x"},
|
||||
"name": "x",
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeAnnotation",
|
||||
"start":5,"end":30,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":30}},
|
||||
"typeAnnotation": {
|
||||
"type": "TSConstructorType",
|
||||
"start":7,"end":30,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":30}},
|
||||
"abstract": true,
|
||||
"parameters": [],
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeAnnotation",
|
||||
"start":23,"end":30,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":30}},
|
||||
"typeAnnotation": {
|
||||
"type": "TSVoidKeyword",
|
||||
"start":26,"end":30,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":30}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"init": {
|
||||
"type": "Identifier",
|
||||
"start":33,"end":34,"loc":{"start":{"line":1,"column":33},"end":{"line":1,"column":34},"identifierName":"X"},
|
||||
"name": "X"
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "let"
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
1
packages/babel-parser/test/fixtures/typescript/types/constructor-signatures/input.ts
vendored
Normal file
1
packages/babel-parser/test/fixtures/typescript/types/constructor-signatures/input.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
let x: new () => void = X;
|
||||
52
packages/babel-parser/test/fixtures/typescript/types/constructor-signatures/output.json
vendored
Normal file
52
packages/babel-parser/test/fixtures/typescript/types/constructor-signatures/output.json
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start":4,"end":25,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":25}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":4,"end":21,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":21},"identifierName":"x"},
|
||||
"name": "x",
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeAnnotation",
|
||||
"start":5,"end":21,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":21}},
|
||||
"typeAnnotation": {
|
||||
"type": "TSConstructorType",
|
||||
"start":7,"end":21,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":21}},
|
||||
"abstract": false,
|
||||
"parameters": [],
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeAnnotation",
|
||||
"start":14,"end":21,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":21}},
|
||||
"typeAnnotation": {
|
||||
"type": "TSVoidKeyword",
|
||||
"start":17,"end":21,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":21}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"init": {
|
||||
"type": "Identifier",
|
||||
"start":24,"end":25,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":25},"identifierName":"X"},
|
||||
"name": "X"
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "let"
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
2
packages/babel-parser/test/fixtures/typescript/types/types-named-abstract/input.ts
vendored
Normal file
2
packages/babel-parser/test/fixtures/typescript/types/types-named-abstract/input.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
type abstract = "abstract";
|
||||
let x: abstract;
|
||||
65
packages/babel-parser/test/fixtures/typescript/types/types-named-abstract/output.json
vendored
Normal file
65
packages/babel-parser/test/fixtures/typescript/types/types-named-abstract/output.json
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":16}},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":16}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "TSTypeAliasDeclaration",
|
||||
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":5,"end":13,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":13},"identifierName":"abstract"},
|
||||
"name": "abstract"
|
||||
},
|
||||
"typeAnnotation": {
|
||||
"type": "TSLiteralType",
|
||||
"start":16,"end":26,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":26}},
|
||||
"literal": {
|
||||
"type": "StringLiteral",
|
||||
"start":16,"end":26,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":26}},
|
||||
"extra": {
|
||||
"rawValue": "abstract",
|
||||
"raw": "\"abstract\""
|
||||
},
|
||||
"value": "abstract"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"start":28,"end":44,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":16}},
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"start":32,"end":43,"loc":{"start":{"line":2,"column":4},"end":{"line":2,"column":15}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":32,"end":43,"loc":{"start":{"line":2,"column":4},"end":{"line":2,"column":15},"identifierName":"x"},
|
||||
"name": "x",
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeAnnotation",
|
||||
"start":33,"end":43,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":15}},
|
||||
"typeAnnotation": {
|
||||
"type": "TSTypeReference",
|
||||
"start":35,"end":43,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":15}},
|
||||
"typeName": {
|
||||
"type": "Identifier",
|
||||
"start":35,"end":43,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":15},"identifierName":"abstract"},
|
||||
"name": "abstract"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"init": null
|
||||
}
|
||||
],
|
||||
"kind": "let"
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
@ -1772,6 +1772,7 @@ export interface TSConstructorType extends BaseNode {
|
||||
typeParameters?: TSTypeParameterDeclaration | null;
|
||||
parameters: Array<Identifier | RestElement>;
|
||||
typeAnnotation?: TSTypeAnnotation | null;
|
||||
abstract?: boolean | null;
|
||||
}
|
||||
|
||||
export interface TSTypeReference extends BaseNode {
|
||||
|
||||
@ -157,14 +157,22 @@ defineType("TSThisType", {
|
||||
fields: {},
|
||||
});
|
||||
|
||||
const fnOrCtr = {
|
||||
const fnOrCtrBase = {
|
||||
aliases: ["TSType"],
|
||||
visitor: ["typeParameters", "parameters", "typeAnnotation"],
|
||||
fields: signatureDeclarationCommon,
|
||||
};
|
||||
|
||||
defineType("TSFunctionType", fnOrCtr);
|
||||
defineType("TSConstructorType", fnOrCtr);
|
||||
defineType("TSFunctionType", {
|
||||
...fnOrCtrBase,
|
||||
fields: signatureDeclarationCommon,
|
||||
});
|
||||
defineType("TSConstructorType", {
|
||||
...fnOrCtrBase,
|
||||
fields: {
|
||||
...signatureDeclarationCommon,
|
||||
abstract: validateOptional(bool),
|
||||
},
|
||||
});
|
||||
|
||||
defineType("TSTypeReference", {
|
||||
aliases: ["TSType"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user