Support quick fixes for UMD global (#12545)

* Support quick fixes for UMD global

* refactor
This commit is contained in:
Zhengbo Li 2016-12-28 15:04:15 -08:00 committed by GitHub
parent 2db8d80860
commit 69e0677ea1
3 changed files with 50 additions and 7 deletions

View File

@ -112,7 +112,10 @@ namespace ts.codefix {
}
registerCodeFix({
errorCodes: [Diagnostics.Cannot_find_name_0.code],
errorCodes: [
Diagnostics.Cannot_find_name_0.code,
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
],
getCodeActions: (context: CodeFixContext) => {
const sourceFile = context.sourceFile;
const checker = context.program.getTypeChecker();
@ -127,6 +130,12 @@ namespace ts.codefix {
const cachedImportDeclarations = createMap<(ImportDeclaration | ImportEqualsDeclaration)[]>();
let cachedNewImportInsertPosition: number;
const currentTokenMeaning = getMeaningFromLocation(token);
if (context.errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) {
const symbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(token));
return getCodeActionForImport(symbol, /*isDefault*/ false, /*isNamespaceImport*/ true);
}
const allPotentialModules = checker.getAmbientModules();
for (const otherSourceFile of allSourceFiles) {
if (otherSourceFile !== sourceFile && isExternalOrCommonJsModule(otherSourceFile)) {
@ -134,7 +143,6 @@ namespace ts.codefix {
}
}
const currentTokenMeaning = getMeaningFromLocation(token);
for (const moduleSymbol of allPotentialModules) {
context.cancellationToken.throwIfCancellationRequested();
@ -203,7 +211,7 @@ namespace ts.codefix {
return declarations ? some(symbol.declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning)) : false;
}
function getCodeActionForImport(moduleSymbol: Symbol, isDefault?: boolean): ImportCodeAction[] {
function getCodeActionForImport(moduleSymbol: Symbol, isDefault?: boolean, isNamespaceImport?: boolean): ImportCodeAction[] {
const existingDeclarations = getImportDeclarations(moduleSymbol);
if (existingDeclarations.length > 0) {
// With an existing import statement, there are more than one actions the user can do.
@ -213,8 +221,6 @@ namespace ts.codefix {
return [getCodeActionForNewImport()];
}
function getCodeActionsForExistingImport(declarations: (ImportDeclaration | ImportEqualsDeclaration)[]): ImportCodeAction[] {
const actions: ImportCodeAction[] = [];
@ -262,7 +268,7 @@ namespace ts.codefix {
actions.push(getCodeActionForNamespaceImport(namespaceImportDeclaration));
}
if (namedImportDeclaration && namedImportDeclaration.importClause &&
if (!isNamespaceImport && namedImportDeclaration && namedImportDeclaration.importClause &&
(namedImportDeclaration.importClause.name || namedImportDeclaration.importClause.namedBindings)) {
/**
* If the existing import declaration already has a named import list, just
@ -386,7 +392,9 @@ namespace ts.codefix {
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier || getModuleSpecifierForNewImport());
const importStatementText = isDefault
? `import ${name} from "${moduleSpecifierWithoutQuotes}"`
: `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`;
: isNamespaceImport
? `import * as ${name} from "${moduleSpecifierWithoutQuotes}"`
: `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`;
// if this file doesn't have any import statements, insert an import statement and then insert a new line
// between the only import statement and user code. Otherwise just insert the statement because chances

View File

@ -0,0 +1,16 @@
/// <reference path="fourslash.ts" />
// @Filename: a/f1.ts
//// [|export function test() { };
//// bar1/*0*/.bar;|]
// @Filename: a/foo.d.ts
//// export declare function bar(): number;
//// export as namespace bar1;
verify.importFixAtPosition([
`import * as bar1 from "./foo";
export function test() { };
bar1.bar;`
]);

View File

@ -0,0 +1,19 @@
/// <reference path="fourslash.ts" />
// @Filename: a/f1.ts
//// [|import { bar } from "./foo";
////
//// export function test() { };
//// bar1/*0*/.bar();|]
// @Filename: a/foo.d.ts
//// export declare function bar(): number;
//// export as namespace bar1;
verify.importFixAtPosition([
`import { bar } from "./foo";
import * as bar1 from "./foo";
export function test() { };
bar1.bar();`
]);