From 5d233054c36b1e4b9180dcfba04920dcd80723e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Thu, 17 May 2018 16:35:11 +0800 Subject: [PATCH] add quick fix for import type missing typeof --- src/compiler/diagnosticMessages.json | 4 +++ src/harness/tsconfig.json | 1 + src/server/tsconfig.json | 1 + src/server/tsconfig.library.json | 1 + .../fixAddModuleReferTypeMissingTypeof.ts | 32 +++++++++++++++++++ src/services/tsconfig.json | 1 + .../fourslash/codeFixAddMissingTypeof1.ts | 16 ++++++++++ .../fourslash/codeFixAddMissingTypeof2.ts | 13 ++++++++ 8 files changed, 69 insertions(+) create mode 100644 src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingTypeof1.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingTypeof2.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2956faef0b3ba..6196191328016 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4257,5 +4257,9 @@ "Remove all unreachable code": { "category": "Message", "code": 95051 + }, + "Add missing typeof": { + "category": "Message", + "code": 95052 } } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 4a95cd4492824..4fb96dbe93dc1 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -116,6 +116,7 @@ "../services/codefixes/moduleSpecifiers.ts", "../services/codefixes/requireInTs.ts", "../services/codefixes/useDefaultImport.ts", + "../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index fee3a8723708d..50e06eb3f2339 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -112,6 +112,7 @@ "../services/codefixes/moduleSpecifiers.ts", "../services/codefixes/requireInTs.ts", "../services/codefixes/useDefaultImport.ts", + "../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", diff --git a/src/server/tsconfig.library.json b/src/server/tsconfig.library.json index b87bf9b5e92d2..43e8fd1857b9a 100644 --- a/src/server/tsconfig.library.json +++ b/src/server/tsconfig.library.json @@ -118,6 +118,7 @@ "../services/codefixes/moduleSpecifiers.ts", "../services/codefixes/requireInTs.ts", "../services/codefixes/useDefaultImport.ts", + "../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", diff --git a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts new file mode 100644 index 0000000000000..8b58dba5450aa --- /dev/null +++ b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts @@ -0,0 +1,32 @@ +/* @internal */ +namespace ts.codefix { + const fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof"; + const fixId = fixIdAddMissingTypeof; + const errorCodes = [Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here.code]; + registerCodeFix({ + errorCodes, + getCodeActions: context => { + const { sourceFile, span } = context; + const typeContainer = getImportTypeNode(sourceFile, span.start); + if (!typeContainer) return undefined; + + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, typeContainer)); + return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_typeof, fixId, Diagnostics.Add_missing_typeof)]; + }, + fixIds: [fixId], + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => + doChange(changes, context.sourceFile, getImportTypeNode(diag.file, diag.start!))), + }); + + function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode | undefined { + const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false); + Debug.assert(token.kind === SyntaxKind.ImportKeyword); + Debug.assert(token.parent.kind === SyntaxKind.ImportType); + return token.parent; + } + + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, typeContainer: ImportTypeNode) { + const newTypeNode = updateImportTypeNode(typeContainer, typeContainer.argument, typeContainer.qualifier, typeContainer.typeArguments, /* isTypeOf */ true); + changes.replaceNode(sourceFile, typeContainer, newTypeNode); + } +} diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 0fe4b16e2acf0..d78086504c926 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -109,6 +109,7 @@ "codefixes/moduleSpecifiers.ts", "codefixes/requireInTs.ts", "codefixes/useDefaultImport.ts", + "codefixes/fixAddModuleReferTypeMissingTypeof.ts", "refactors/extractSymbol.ts", "refactors/generateGetAccessorAndSetAccessor.ts", "refactors/moveToNewFile.ts", diff --git a/tests/cases/fourslash/codeFixAddMissingTypeof1.ts b/tests/cases/fourslash/codeFixAddMissingTypeof1.ts new file mode 100644 index 0000000000000..ab728c07455b6 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingTypeof1.ts @@ -0,0 +1,16 @@ +/// + +//// declare module "foo" { +//// const a = "foo" +//// export = a +//// } +//// const x: import("foo") = import("foo"); + +verify.codeFix({ + description: "Add missing typeof", + newFileContent: `declare module "foo" { + const a = "foo" + export = a +} +const x: typeof import("foo") = import("foo");` +}); diff --git a/tests/cases/fourslash/codeFixAddMissingTypeof2.ts b/tests/cases/fourslash/codeFixAddMissingTypeof2.ts new file mode 100644 index 0000000000000..bb863e8db3725 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingTypeof2.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: a.ts +//// export = 1; + +// @Filename: b.ts +//// const a: import("./a") = import("./a") + +goTo.file("b.ts") +verify.codeFix({ + description: "Add missing typeof", + newFileContent: `const a: typeof import("./a") = import("./a")` +});