fix(50654): "Move to a new file" breaks the declaration of referenced variable (#50681)

* fix(50654): remove entire import require call instead of the name

* handle require imports in ts files
This commit is contained in:
Oleksandr T
2022-10-26 03:05:57 +03:00
committed by GitHub
parent 170a17fad5
commit 8b1ecdb701
4 changed files with 109 additions and 3 deletions

View File

@@ -133,7 +133,7 @@ namespace ts.refactor {
) {
const checker = program.getTypeChecker();
const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective);
if (!oldFile.externalModuleIndicator && !oldFile.commonJsModuleIndicator) {
if (oldFile.externalModuleIndicator === undefined && oldFile.commonJsModuleIndicator === undefined && usage.oldImportsNeededByNewFile.size() === 0) {
deleteMovedStatements(oldFile, toMove.ranges, changes);
return [...prologueDirectives, ...toMove.all];
}
@@ -402,7 +402,13 @@ namespace ts.refactor {
switch (name.kind) {
case SyntaxKind.Identifier:
if (isUnused(name)) {
changes.delete(sourceFile, name);
if (varDecl.initializer && isRequireCall(varDecl.initializer, /*requireStringLiteralLikeArgument*/ true)) {
changes.delete(sourceFile,
isVariableDeclarationList(varDecl.parent) && length(varDecl.parent.declarations) === 1 ? varDecl.parent.parent : varDecl);
}
else {
changes.delete(sourceFile, name);
}
}
break;
case SyntaxKind.ArrayBindingPattern:
@@ -641,10 +647,12 @@ namespace ts.refactor {
}
interface ReadonlySymbolSet {
size(): number;
has(symbol: Symbol): boolean;
forEach(cb: (symbol: Symbol) => void): void;
forEachEntry<T>(cb: (symbol: Symbol) => T | undefined): T | undefined;
}
class SymbolSet implements ReadonlySymbolSet {
private map = new Map<string, Symbol>();
add(symbol: Symbol): void {
@@ -667,6 +675,9 @@ namespace ts.refactor {
copyEntries(this.map, clone.map);
return clone;
}
size() {
return this.map.size;
}
}
type TopLevelExpressionStatement = ExpressionStatement & { expression: BinaryExpression & { left: PropertyAccessExpression } }; // 'exports.x = ...'
@@ -775,7 +786,8 @@ namespace ts.refactor {
if (useEs6Exports) {
return !isExpressionStatement(decl) && hasSyntacticModifier(decl, ModifierFlags.Export) || !!(name && sourceFile.symbol.exports?.has(name.escapedText));
}
return getNamesToExportInCommonJS(decl).some(name => sourceFile.symbol.exports!.has(escapeLeadingUnderscores(name)));
return !!sourceFile.symbol && !!sourceFile.symbol.exports &&
getNamesToExportInCommonJS(decl).some(name => sourceFile.symbol.exports!.has(escapeLeadingUnderscores(name)));
}
function addExport(decl: TopLevelDeclarationStatement, useEs6Exports: boolean): readonly Statement[] | undefined {