Allow qualified name for convert namespace import (#41592)

This commit is contained in:
Wenlu Wang 2020-12-02 07:23:57 +08:00 committed by GitHub
parent 0da5a7e4ba
commit 55810095f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 9 deletions

View File

@ -73,34 +73,33 @@ namespace ts.refactor {
function doChangeNamespaceToNamed(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, toConvert: NamespaceImport, allowSyntheticDefaultImports: boolean): void {
let usedAsNamespaceOrDefault = false;
const nodesToReplace: PropertyAccessExpression[] = [];
const nodesToReplace: (PropertyAccessExpression | QualifiedName)[] = [];
const conflictingNames = new Map<string, true>();
FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => {
if (!isPropertyAccessExpression(id.parent)) {
if (!isPropertyAccessOrQualifiedName(id.parent)) {
usedAsNamespaceOrDefault = true;
}
else {
const parent = cast(id.parent, isPropertyAccessExpression);
const exportName = parent.name.text;
const exportName = getRightOfPropertyAccessOrQualifiedName(id.parent).text;
if (checker.resolveName(exportName, id, SymbolFlags.All, /*excludeGlobals*/ true)) {
conflictingNames.set(exportName, true);
}
Debug.assert(parent.expression === id, "Parent expression should match id");
nodesToReplace.push(parent);
Debug.assert(getLeftOfPropertyAccessOrQualifiedName(id.parent) === id, "Parent expression should match id");
nodesToReplace.push(id.parent);
}
});
// We may need to change `mod.x` to `_x` to avoid a name conflict.
const exportNameToImportName = new Map<string, string>();
for (const propertyAccess of nodesToReplace) {
const exportName = propertyAccess.name.text;
for (const propertyAccessOrQualifiedName of nodesToReplace) {
const exportName = getRightOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName).text;
let importName = exportNameToImportName.get(exportName);
if (importName === undefined) {
exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? getUniqueName(exportName, sourceFile) : exportName);
}
changes.replaceNode(sourceFile, propertyAccess, factory.createIdentifier(importName));
changes.replaceNode(sourceFile, propertyAccessOrQualifiedName, factory.createIdentifier(importName));
}
const importSpecifiers: ImportSpecifier[] = [];
@ -118,6 +117,14 @@ namespace ts.refactor {
}
}
function getRightOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: PropertyAccessExpression | QualifiedName) {
return isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.name : propertyAccessOrQualifiedName.right;
}
function getLeftOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: PropertyAccessExpression | QualifiedName) {
return isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.expression : propertyAccessOrQualifiedName.left;
}
function doChangeNamedToNamespace(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, toConvert: NamedImports): void {
const importDecl = toConvert.parent.parent;
const { moduleSpecifier } = importDecl;

View File

@ -0,0 +1,16 @@
/// <reference path='fourslash.ts' />
/////*a*/import * as m from "m";/*b*/
////declare const a: m.aa;
////declare const b: m.b;
goTo.select("a", "b");
edit.applyRefactor({
refactorName: "Convert import",
actionName: "Convert namespace import to named imports",
actionDescription: "Convert namespace import to named imports",
newContent:
`import { aa, b as b_1 } from "m";
declare const a: aa;
declare const b: b_1;`,
});