From 2c7a844cb5ae285d5fc165ec103315d6eb7abb07 Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Tue, 7 Nov 2017 03:19:22 -0500 Subject: [PATCH 1/3] import fix: suggest import..require where supported if synthetic defaults are unavailable --- src/services/codefixes/importFixes.ts | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a7f0e2e0814b4..e0e57801cf850 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -180,7 +180,8 @@ namespace ts.codefix { export const enum ImportKind { Named, Default, - Namespace + Namespace, + Equals } export function getCodeActionForImport(moduleSymbol: Symbol, context: ImportCodeFixOptions): ImportCodeAction[] { @@ -252,11 +253,17 @@ namespace ts.codefix { const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); const quotedModuleSpecifier = createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes); - const importDecl = createImportDeclaration( + const importDecl = kind !== ImportKind.Equals + ? createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClauseOfKind(kind, symbolName), - quotedModuleSpecifier); + createImportClauseOfKind(kind, symbolName), + quotedModuleSpecifier) + : createImportEqualsDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createIdentifier(symbolName), + createExternalModuleReference(quotedModuleSpecifier)); const changes = ChangeTracker.with(context, changeTracker => { if (lastImportDeclaration) { @@ -267,8 +274,10 @@ namespace ts.codefix { } }); - const actionFormat = kind === ImportKind.Namespace - ? Diagnostics.Import_Asterisk_as_0_from_1 + const actionFormat = kind === ImportKind.Equals + ? Diagnostics.Import_0_require_1 + : kind === ImportKind.Namespace + ? Diagnostics.Import_Asterisk_as_0_from_1 : Diagnostics.Import_0_from_1; // if this file doesn't have any import statements, insert an import statement and then insert a new line @@ -601,6 +610,9 @@ namespace ts.codefix { return namedBindings ? undefined : ChangeTracker.with(context, t => t.replaceNode(sourceFile, importClause, createImportClause(name, createNamespaceImport(createIdentifier(symbolName))))); + case ImportKind.Equals: + return undefined; + default: Debug.assertNever(kind); } @@ -659,6 +671,12 @@ namespace ts.codefix { if (allowSyntheticDefaultImports) { return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Default }); } + const moduleKind = getEmitModuleKind(compilerOptions); + + // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it. + if (moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.CommonJS || moduleKind === ModuleKind.UMD) { + return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Equals }); + } // Fall back to the `import * as ns` style import. return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Namespace }); From 1bf4d06697c903de7cf94917397a974baac3c856 Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Tue, 7 Nov 2017 04:13:11 -0500 Subject: [PATCH 2/3] Add tests for import..require fix when targeting CommonJS, AMD, and UMD modules --- ...xNewImportAllowSyntheticDefaultImports3.ts | 19 +++++++++++++++++++ ...xNewImportAllowSyntheticDefaultImports4.ts | 19 +++++++++++++++++++ ...xNewImportAllowSyntheticDefaultImports5.ts | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts new file mode 100644 index 0000000000000..bc0ba6d816363 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: commonjs + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts new file mode 100644 index 0000000000000..c8ce87db71a32 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: amd + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts new file mode 100644 index 0000000000000..7830faaacc8ce --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: umd + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file From 555b4aec25d4fbf1500406574bd71ce406a8f2a2 Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Tue, 7 Nov 2017 04:13:47 -0500 Subject: [PATCH 3/3] fix failing tests --- .../importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts | 1 + tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts | 3 +++ tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts | 3 +++ tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts | 2 ++ tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts | 2 ++ 5 files changed, 11 insertions(+) diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts index 3421d603297b5..f6ba985715e28 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts @@ -1,5 +1,6 @@ /// // @AllowSyntheticDefaultImports: false +// @Module: system // @Filename: a/f1.ts //// [|export var x = 0; diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts index 3c780dc0af662..3208a41bba151 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts @@ -1,5 +1,8 @@ /// +// @AllowSyntheticDefaultImports: false +// @Module: es2015 + // @Filename: a/f1.ts //// [|export function test() { }; //// bar1/*0*/.bar;|] diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts index 96671ad6f91af..1beebb0477cd0 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts @@ -1,5 +1,8 @@ /// +// @AllowSyntheticDefaultImports: false +// @Module: esnext + // @Filename: a/f1.ts //// [|import { bar } from "./foo"; //// diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts index 260c34d10a604..5b6df7a517349 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts @@ -1,6 +1,8 @@ /// // @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 // @Filename: /node_modules/@types/react/index.d.ts ////export = React; diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts index ccd69c501997a..669db55342b04 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts @@ -1,6 +1,8 @@ /// // @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 // @Filename: /node_modules/@types/react/index.d.ts ////export = React;