diff --git a/src/def/typescript.ts b/src/def/typescript.ts index c050529e..57ad9da8 100644 --- a/src/def/typescript.ts +++ b/src/def/typescript.ts @@ -503,6 +503,12 @@ export default function (fork: Fork) { def("ClassAccessorProperty") .bases("Declaration", "TSHasOptionalTypeAnnotation"); + def("CallExpression") + .bases("TSHasOptionalTypeParameterInstantiation"); + + def("NewExpression") + .bases("TSHasOptionalTypeParameterInstantiation"); + // Defined already in es6 and babel-core. def("ClassBody") .field("body", [or( diff --git a/src/gen/builders.ts b/src/gen/builders.ts index cd48c8dc..1c749b88 100644 --- a/src/gen/builders.ts +++ b/src/gen/builders.ts @@ -581,6 +581,7 @@ export interface NewExpressionBuilder { comments?: K.CommentKind[] | null; loc?: K.SourceLocationKind | null; typeArguments?: null | K.TypeParameterInstantiationKind; + typeParameters?: K.TSTypeParameterInstantiationKind | null; } ): namedTypes.NewExpression; } @@ -598,6 +599,7 @@ export interface CallExpressionBuilder { loc?: K.SourceLocationKind | null; optional?: boolean; typeArguments?: null | K.TypeParameterInstantiationKind; + typeParameters?: K.TSTypeParameterInstantiationKind | null; } ): namedTypes.CallExpression; } @@ -1206,6 +1208,7 @@ export interface OptionalCallExpressionBuilder { loc?: K.SourceLocationKind | null; optional?: boolean; typeArguments?: null | K.TypeParameterInstantiationKind; + typeParameters?: K.TSTypeParameterInstantiationKind | null; } ): namedTypes.OptionalCallExpression; } diff --git a/src/gen/kinds.ts b/src/gen/kinds.ts index 69b33d56..b464bfbc 100644 --- a/src/gen/kinds.ts +++ b/src/gen/kinds.ts @@ -50,6 +50,7 @@ export type MemberExpressionKind = namedTypes.MemberExpression | namedTypes.Opti export type UpdateExpressionKind = namedTypes.UpdateExpression; export type LogicalExpressionKind = namedTypes.LogicalExpression; export type ConditionalExpressionKind = namedTypes.ConditionalExpression; +export type TSHasOptionalTypeParameterInstantiationKind = namedTypes.NewExpression | namedTypes.CallExpression | namedTypes.OptionalCallExpression | namedTypes.TSExpressionWithTypeArguments | namedTypes.TSTypeReference | namedTypes.TSImportType | namedTypes.TSInstantiationExpression; export type NewExpressionKind = namedTypes.NewExpression; export type CallExpressionKind = namedTypes.CallExpression | namedTypes.OptionalCallExpression; export type RestElementKind = namedTypes.RestElement; @@ -126,7 +127,6 @@ export type TypeParameterInstantiationKind = namedTypes.TypeParameterInstantiati export type TSTypeParameterInstantiationKind = namedTypes.TSTypeParameterInstantiation; export type ClassImplementsKind = namedTypes.ClassImplements; export type TSTypeKind = namedTypes.TSExpressionWithTypeArguments | namedTypes.TSTypeReference | namedTypes.TSAnyKeyword | namedTypes.TSBigIntKeyword | namedTypes.TSBooleanKeyword | namedTypes.TSNeverKeyword | namedTypes.TSNullKeyword | namedTypes.TSNumberKeyword | namedTypes.TSObjectKeyword | namedTypes.TSStringKeyword | namedTypes.TSSymbolKeyword | namedTypes.TSUndefinedKeyword | namedTypes.TSUnknownKeyword | namedTypes.TSVoidKeyword | namedTypes.TSIntrinsicKeyword | namedTypes.TSThisType | namedTypes.TSArrayType | namedTypes.TSLiteralType | namedTypes.TSUnionType | namedTypes.TSIntersectionType | namedTypes.TSConditionalType | namedTypes.TSInferType | namedTypes.TSParenthesizedType | namedTypes.TSFunctionType | namedTypes.TSConstructorType | namedTypes.TSMappedType | namedTypes.TSTupleType | namedTypes.TSNamedTupleMember | namedTypes.TSRestType | namedTypes.TSOptionalType | namedTypes.TSIndexedAccessType | namedTypes.TSTypeOperator | namedTypes.TSTypePredicate | namedTypes.TSTypeQuery | namedTypes.TSImportType | namedTypes.TSTypeLiteral; -export type TSHasOptionalTypeParameterInstantiationKind = namedTypes.TSExpressionWithTypeArguments | namedTypes.TSTypeReference | namedTypes.TSImportType | namedTypes.TSInstantiationExpression; export type TSExpressionWithTypeArgumentsKind = namedTypes.TSExpressionWithTypeArguments; export type FlowKind = namedTypes.AnyTypeAnnotation | namedTypes.EmptyTypeAnnotation | namedTypes.MixedTypeAnnotation | namedTypes.VoidTypeAnnotation | namedTypes.SymbolTypeAnnotation | namedTypes.NumberTypeAnnotation | namedTypes.BigIntTypeAnnotation | namedTypes.NumberLiteralTypeAnnotation | namedTypes.NumericLiteralTypeAnnotation | namedTypes.BigIntLiteralTypeAnnotation | namedTypes.StringTypeAnnotation | namedTypes.StringLiteralTypeAnnotation | namedTypes.BooleanTypeAnnotation | namedTypes.BooleanLiteralTypeAnnotation | namedTypes.NullableTypeAnnotation | namedTypes.NullLiteralTypeAnnotation | namedTypes.NullTypeAnnotation | namedTypes.ThisTypeAnnotation | namedTypes.ExistsTypeAnnotation | namedTypes.ExistentialTypeParam | namedTypes.FunctionTypeAnnotation | namedTypes.ArrayTypeAnnotation | namedTypes.ObjectTypeAnnotation | namedTypes.GenericTypeAnnotation | namedTypes.MemberTypeAnnotation | namedTypes.IndexedAccessType | namedTypes.OptionalIndexedAccessType | namedTypes.UnionTypeAnnotation | namedTypes.IntersectionTypeAnnotation | namedTypes.TypeofTypeAnnotation | namedTypes.TypeParameter | namedTypes.InterfaceTypeAnnotation | namedTypes.TupleTypeAnnotation | namedTypes.InferredPredicate | namedTypes.DeclaredPredicate; export type FlowTypeKind = namedTypes.AnyTypeAnnotation | namedTypes.EmptyTypeAnnotation | namedTypes.MixedTypeAnnotation | namedTypes.VoidTypeAnnotation | namedTypes.SymbolTypeAnnotation | namedTypes.NumberTypeAnnotation | namedTypes.BigIntTypeAnnotation | namedTypes.NumberLiteralTypeAnnotation | namedTypes.NumericLiteralTypeAnnotation | namedTypes.BigIntLiteralTypeAnnotation | namedTypes.StringTypeAnnotation | namedTypes.StringLiteralTypeAnnotation | namedTypes.BooleanTypeAnnotation | namedTypes.BooleanLiteralTypeAnnotation | namedTypes.NullableTypeAnnotation | namedTypes.NullLiteralTypeAnnotation | namedTypes.NullTypeAnnotation | namedTypes.ThisTypeAnnotation | namedTypes.ExistsTypeAnnotation | namedTypes.ExistentialTypeParam | namedTypes.FunctionTypeAnnotation | namedTypes.ArrayTypeAnnotation | namedTypes.ObjectTypeAnnotation | namedTypes.GenericTypeAnnotation | namedTypes.MemberTypeAnnotation | namedTypes.IndexedAccessType | namedTypes.OptionalIndexedAccessType | namedTypes.UnionTypeAnnotation | namedTypes.IntersectionTypeAnnotation | namedTypes.TypeofTypeAnnotation | namedTypes.TypeParameter | namedTypes.InterfaceTypeAnnotation | namedTypes.TupleTypeAnnotation; diff --git a/src/gen/namedTypes.ts b/src/gen/namedTypes.ts index c2e481b0..c333af25 100644 --- a/src/gen/namedTypes.ts +++ b/src/gen/namedTypes.ts @@ -293,14 +293,18 @@ export namespace namedTypes { alternate: K.ExpressionKind; } - export interface NewExpression extends Omit { + export interface TSHasOptionalTypeParameterInstantiation { + typeParameters?: K.TSTypeParameterInstantiationKind | null; + } + + export interface NewExpression extends Omit, TSHasOptionalTypeParameterInstantiation { type: "NewExpression"; callee: K.ExpressionKind; arguments: (K.ExpressionKind | K.SpreadElementKind)[]; typeArguments?: null | K.TypeParameterInstantiationKind; } - export interface CallExpression extends Omit, Omit { + export interface CallExpression extends Omit, Omit, TSHasOptionalTypeParameterInstantiation { type: "CallExpression"; callee: K.ExpressionKind; arguments: (K.ExpressionKind | K.SpreadElementKind)[]; @@ -751,10 +755,6 @@ export namespace namedTypes { export interface TSType extends Node {} - export interface TSHasOptionalTypeParameterInstantiation { - typeParameters?: K.TSTypeParameterInstantiationKind | null; - } - export interface TSExpressionWithTypeArguments extends Omit, TSHasOptionalTypeParameterInstantiation { type: "TSExpressionWithTypeArguments"; expression: K.IdentifierKind | K.TSQualifiedNameKind; @@ -1773,6 +1773,7 @@ export namespace namedTypes { export let UpdateExpression: Type; export let LogicalExpression: Type; export let ConditionalExpression: Type; + export let TSHasOptionalTypeParameterInstantiation: Type; export let NewExpression: Type; export let CallExpression: Type; export let RestElement: Type; @@ -1849,7 +1850,6 @@ export namespace namedTypes { export let TSTypeParameterInstantiation: Type; export let ClassImplements: Type; export let TSType: Type; - export let TSHasOptionalTypeParameterInstantiation: Type; export let TSExpressionWithTypeArguments: Type; export let Flow: Type; export let FlowType: Type; @@ -2068,6 +2068,7 @@ export interface NamedTypes { UpdateExpression: Type; LogicalExpression: Type; ConditionalExpression: Type; + TSHasOptionalTypeParameterInstantiation: Type; NewExpression: Type; CallExpression: Type; RestElement: Type; @@ -2144,7 +2145,6 @@ export interface NamedTypes { TSTypeParameterInstantiation: Type; ClassImplements: Type; TSType: Type; - TSHasOptionalTypeParameterInstantiation: Type; TSExpressionWithTypeArguments: Type; Flow: Type; FlowType: Type; diff --git a/src/gen/visitor.ts b/src/gen/visitor.ts index 4e769902..77fab81f 100644 --- a/src/gen/visitor.ts +++ b/src/gen/visitor.ts @@ -54,6 +54,10 @@ export interface Visitor { visitUpdateExpression?(this: Context & M, path: NodePath): any; visitLogicalExpression?(this: Context & M, path: NodePath): any; visitConditionalExpression?(this: Context & M, path: NodePath): any; + visitTSHasOptionalTypeParameterInstantiation?( + this: Context & M, + path: NodePath + ): any; visitNewExpression?(this: Context & M, path: NodePath): any; visitCallExpression?(this: Context & M, path: NodePath): any; visitRestElement?(this: Context & M, path: NodePath): any; @@ -130,10 +134,6 @@ export interface Visitor { visitTSTypeParameterInstantiation?(this: Context & M, path: NodePath): any; visitClassImplements?(this: Context & M, path: NodePath): any; visitTSType?(this: Context & M, path: NodePath): any; - visitTSHasOptionalTypeParameterInstantiation?( - this: Context & M, - path: NodePath - ): any; visitTSExpressionWithTypeArguments?( this: Context & M, path: NodePath diff --git a/src/test/typescript.ts b/src/test/typescript.ts index a9c2b4c4..02563171 100644 --- a/src/test/typescript.ts +++ b/src/test/typescript.ts @@ -407,5 +407,72 @@ glob("**/*.ts", { } }); }); + + it("issue #343: CallExpression with type parameters", function () { + const program = babelParse("fn();", { + plugins: ["typescript"] + }); + + const identifiers: string[] = []; + + assertVisited(program, { + visitIdentifier(path) { + identifiers.push(path.node.name); + this.traverse(path); + } + }); + + assert.deepEqual(identifiers, ["FetchResult", "fn"]); + }); + + it("NewExpression with type parameters", function () { + const program = babelParse("new Container();", { + plugins: ["typescript"] + }); + + const identifiers: string[] = []; + + assertVisited(program, { + visitIdentifier(path) { + identifiers.push(path.node.name); + this.traverse(path); + } + }); + + assert.deepEqual(identifiers, ["Item", "Container"]); + }); + + it("OptionalCallExpression with type parameters", function () { + const program = babelParse("obj?.method();", { + plugins: ["typescript"] + }); + + const identifiers: string[] = []; + + assertVisited(program, { + visitIdentifier(path) { + identifiers.push(path.node.name); + this.traverse(path); + } + }); + + assert.deepEqual(identifiers, ["Result", "obj", "method"]); + }); + + it("Complex nested type parameters in CallExpression", function () { + const program = babelParse("func>>(data);", { + plugins: ["typescript"] + }); + + const identifiers: string[] = []; + assertVisited(program, { + visitIdentifier(path) { + identifiers.push(path.node.name); + this.traverse(path); + } + }); + + assert.deepEqual(identifiers, [ "User", "Map", "Array", "func", "data"]); + }); }); }); \ No newline at end of file