From a44e2d925cdf3bfa51b8b65ca15f9007d1fde979 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 17 Jul 2024 16:41:58 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#59160=20(Fixed=20cr?= =?UTF-8?q?ash=20on=20authored=20import=20type...)=20into=20release-5.5=20?= =?UTF-8?q?(#59226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz BurzyƄski --- src/services/codefixes/helpers.ts | 6 +++ ...ionsClassMemberImportTypeNodeParameter1.ts | 34 +++++++++++++++++ ...ionsClassMemberImportTypeNodeParameter2.ts | 31 ++++++++++++++++ ...ionsClassMemberImportTypeNodeParameter3.ts | 37 +++++++++++++++++++ ...ionsClassMemberImportTypeNodeParameter4.ts | 34 +++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter1.ts create mode 100644 tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter2.ts create mode 100644 tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter3.ts create mode 100644 tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter4.ts diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index aaa2df431f2..f17e7333798 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -902,6 +902,12 @@ export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNo if (isLiteralImportTypeNode(node) && node.qualifier) { // Symbol for the left-most thing after the dot const firstIdentifier = getFirstIdentifier(node.qualifier); + if (!firstIdentifier.symbol) { + // if symbol is missing then this doesn't come from a synthesized import type node + // it has to be an import type node authored by the user and thus it has to be valid + // it can't refer to reserved internal symbol names and such + return visitEachChild(node, visit, /*context*/ undefined); + } const name = getNameForExportedSymbol(firstIdentifier.symbol, scriptTarget); const qualifier = name !== firstIdentifier.text ? replaceFirstIdentifierOfEntityName(node.qualifier, factory.createIdentifier(name)) diff --git a/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter1.ts b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter1.ts new file mode 100644 index 00000000000..65ee02dcf8d --- /dev/null +++ b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter1.ts @@ -0,0 +1,34 @@ +/// + +// @module: nodenext + +// @Filename: /generation.d.ts +//// export type GenerationConfigType = { max_length?: number }; + +// @FileName: /index.d.ts +//// export declare class PreTrainedModel { +//// _get_generation_config( +//// param: import("./generation.js").GenerationConfigType, +//// ): import("./generation.js").GenerationConfigType; +//// } +//// +//// export declare class BlenderbotSmallPreTrainedModel extends PreTrainedModel { +//// /*1*/ +//// } + +verify.completions({ + marker: "1", + includes: [ + { + name: "_get_generation_config", + insertText: `_get_generation_config(param: import("./generation.js").GenerationConfigType): import("./generation.js").GenerationConfigType;`, + filterText: "_get_generation_config", + hasAction: undefined, + }, + ], + preferences: { + includeCompletionsWithClassMemberSnippets: true, + includeCompletionsWithInsertText: true, + }, + isNewIdentifierLocation: true, +}); diff --git a/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter2.ts b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter2.ts new file mode 100644 index 00000000000..764075a757b --- /dev/null +++ b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter2.ts @@ -0,0 +1,31 @@ +/// + +// @module: nodenext + +// @FileName: /index.d.ts +//// export declare class Cls { +//// method( +//// param: import("./doesntexist.js").Foo, +//// ): import("./doesntexist.js").Foo; +//// } +//// +//// export declare class Derived extends Cls { +//// /*1*/ +//// } + +verify.completions({ + marker: "1", + includes: [ + { + name: "method", + insertText: `method(param: import("./doesntexist.js").Foo);`, + filterText: "method", + hasAction: undefined, + }, + ], + preferences: { + includeCompletionsWithClassMemberSnippets: true, + includeCompletionsWithInsertText: true, + }, + isNewIdentifierLocation: true, +}); diff --git a/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter3.ts b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter3.ts new file mode 100644 index 00000000000..5edb4d7478e --- /dev/null +++ b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter3.ts @@ -0,0 +1,37 @@ +/// + +// @module: nodenext + +// @FileName: /other/foo.d.ts +//// export declare type Bar = { baz: string }; + +// @FileName: /other/cls.d.ts +//// export declare class Cls { +//// method( +//// param: import("./foo.js").Bar, +//// ): import("./foo.js").Bar; +//// } + +// @FileName: /index.d.ts +//// import { Cls } from "./other/cls.js"; +//// +//// export declare class Derived extends Cls { +//// /*1*/ +//// } + +verify.completions({ + marker: "1", + includes: [ + { + name: "method", + insertText: `method(param: import("./other/foo.js").Bar): import("./other/foo.js").Bar;`, + filterText: "method", + hasAction: undefined, + }, + ], + preferences: { + includeCompletionsWithClassMemberSnippets: true, + includeCompletionsWithInsertText: true, + }, + isNewIdentifierLocation: true, +}); diff --git a/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter4.ts b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter4.ts new file mode 100644 index 00000000000..072725ac2f7 --- /dev/null +++ b/tests/cases/fourslash/completionsClassMemberImportTypeNodeParameter4.ts @@ -0,0 +1,34 @@ +/// + +// @module: nodenext + +// @FileName: /other/cls.d.ts +//// export declare class Cls { +//// method( +//// param: import("./doesntexist.js").Foo, +//// ): import("./doesntexist.js").Foo; +//// } + +// @FileName: /index.d.ts +//// import { Cls } from "./other/cls.js"; +//// +//// export declare class Derived extends Cls { +//// /*1*/ +//// } + +verify.completions({ + marker: "1", + includes: [ + { + name: "method", + insertText: `method(param: import("./doesntexist.js").Foo);`, + filterText: "method", + hasAction: undefined, + }, + ], + preferences: { + includeCompletionsWithClassMemberSnippets: true, + includeCompletionsWithInsertText: true, + }, + isNewIdentifierLocation: true, +});