Skip to content

Commit 69e0677

Browse files
authored
Support quick fixes for UMD global (#12545)
* Support quick fixes for UMD global * refactor
1 parent 2db8d80 commit 69e0677

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/services/codefixes/importFixes.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ namespace ts.codefix {
112112
}
113113

114114
registerCodeFix({
115-
errorCodes: [Diagnostics.Cannot_find_name_0.code],
115+
errorCodes: [
116+
Diagnostics.Cannot_find_name_0.code,
117+
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
118+
],
116119
getCodeActions: (context: CodeFixContext) => {
117120
const sourceFile = context.sourceFile;
118121
const checker = context.program.getTypeChecker();
@@ -127,14 +130,19 @@ namespace ts.codefix {
127130
const cachedImportDeclarations = createMap<(ImportDeclaration | ImportEqualsDeclaration)[]>();
128131
let cachedNewImportInsertPosition: number;
129132

133+
const currentTokenMeaning = getMeaningFromLocation(token);
134+
if (context.errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) {
135+
const symbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(token));
136+
return getCodeActionForImport(symbol, /*isDefault*/ false, /*isNamespaceImport*/ true);
137+
}
138+
130139
const allPotentialModules = checker.getAmbientModules();
131140
for (const otherSourceFile of allSourceFiles) {
132141
if (otherSourceFile !== sourceFile && isExternalOrCommonJsModule(otherSourceFile)) {
133142
allPotentialModules.push(otherSourceFile.symbol);
134143
}
135144
}
136145

137-
const currentTokenMeaning = getMeaningFromLocation(token);
138146
for (const moduleSymbol of allPotentialModules) {
139147
context.cancellationToken.throwIfCancellationRequested();
140148

@@ -203,7 +211,7 @@ namespace ts.codefix {
203211
return declarations ? some(symbol.declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning)) : false;
204212
}
205213

206-
function getCodeActionForImport(moduleSymbol: Symbol, isDefault?: boolean): ImportCodeAction[] {
214+
function getCodeActionForImport(moduleSymbol: Symbol, isDefault?: boolean, isNamespaceImport?: boolean): ImportCodeAction[] {
207215
const existingDeclarations = getImportDeclarations(moduleSymbol);
208216
if (existingDeclarations.length > 0) {
209217
// With an existing import statement, there are more than one actions the user can do.
@@ -213,8 +221,6 @@ namespace ts.codefix {
213221
return [getCodeActionForNewImport()];
214222
}
215223

216-
217-
218224
function getCodeActionsForExistingImport(declarations: (ImportDeclaration | ImportEqualsDeclaration)[]): ImportCodeAction[] {
219225
const actions: ImportCodeAction[] = [];
220226

@@ -262,7 +268,7 @@ namespace ts.codefix {
262268
actions.push(getCodeActionForNamespaceImport(namespaceImportDeclaration));
263269
}
264270

265-
if (namedImportDeclaration && namedImportDeclaration.importClause &&
271+
if (!isNamespaceImport && namedImportDeclaration && namedImportDeclaration.importClause &&
266272
(namedImportDeclaration.importClause.name || namedImportDeclaration.importClause.namedBindings)) {
267273
/**
268274
* If the existing import declaration already has a named import list, just
@@ -386,7 +392,9 @@ namespace ts.codefix {
386392
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier || getModuleSpecifierForNewImport());
387393
const importStatementText = isDefault
388394
? `import ${name} from "${moduleSpecifierWithoutQuotes}"`
389-
: `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`;
395+
: isNamespaceImport
396+
? `import * as ${name} from "${moduleSpecifierWithoutQuotes}"`
397+
: `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`;
390398

391399
// if this file doesn't have any import statements, insert an import statement and then insert a new line
392400
// between the only import statement and user code. Otherwise just insert the statement because chances
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a/f1.ts
4+
//// [|export function test() { };
5+
//// bar1/*0*/.bar;|]
6+
7+
// @Filename: a/foo.d.ts
8+
//// export declare function bar(): number;
9+
//// export as namespace bar1;
10+
11+
verify.importFixAtPosition([
12+
`import * as bar1 from "./foo";
13+
14+
export function test() { };
15+
bar1.bar;`
16+
]);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a/f1.ts
4+
//// [|import { bar } from "./foo";
5+
////
6+
//// export function test() { };
7+
//// bar1/*0*/.bar();|]
8+
9+
// @Filename: a/foo.d.ts
10+
//// export declare function bar(): number;
11+
//// export as namespace bar1;
12+
13+
verify.importFixAtPosition([
14+
`import { bar } from "./foo";
15+
import * as bar1 from "./foo";
16+
17+
export function test() { };
18+
bar1.bar();`
19+
]);

0 commit comments

Comments
 (0)