diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index 27859eca573..b1810cd1b5b 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -75,25 +75,24 @@ export function addTargetFileImports( * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). * So in that case, fall back to copying the import verbatim. */ - importsToCopy.forEach(([isValidTypeOnlyUseSite, declaration], symbol) => { - const targetSymbol = skipAlias(symbol, checker); - if (checker.isUnknownSymbol(targetSymbol)) { - importAdder.addVerbatimImport(Debug.checkDefined(declaration ?? findAncestor(symbol.declarations?.[0], isAnyImportOrRequireStatement))); - } - else if (targetSymbol.parent === undefined) { - Debug.assert(declaration !== undefined, "expected module symbol to have a declaration"); - const aliasedSymbol = checker.getAliasedSymbol(symbol); - if (aliasedSymbol.flags & SymbolFlags.Module) { - importAdder.addImportForModuleSymbol(symbol, isValidTypeOnlyUseSite, declaration); - } - else { - // If the aliased symbol is not a module, fall back to verbatim import - importAdder.addVerbatimImport(Debug.checkDefined(declaration ?? findAncestor(symbol.declarations?.[0], isAnyImportOrRequireStatement))); - } - } - else { - importAdder.addImportFromExportedSymbol(targetSymbol, isValidTypeOnlyUseSite, declaration); - } + importsToCopy.forEach(([isValidTypeOnlyUseSite, declaration], symbol) => { + const targetSymbol = skipAlias(symbol, checker); + if (checker.isUnknownSymbol(targetSymbol)) { + importAdder.addVerbatimImport(Debug.checkDefined(declaration ?? findAncestor(symbol.declarations?.[0], isAnyImportOrRequireStatement))); + } + else if (targetSymbol.parent === undefined) { + if (targetSymbol.flags & SymbolFlags.Module) { + Debug.assert(declaration !== undefined, "expected module symbol to have a declaration"); + importAdder.addImportForModuleSymbol(symbol, isValidTypeOnlyUseSite, declaration); + } + else { + // If the target symbol has no parent but isn't a module, fall back to verbatim import + importAdder.addVerbatimImport(Debug.checkDefined(declaration ?? findAncestor(symbol.declarations?.[0], isAnyImportOrRequireStatement))); + } + } + else { + importAdder.addImportFromExportedSymbol(targetSymbol, isValidTypeOnlyUseSite, declaration); + } }); addImportsForMovedSymbols(targetFileImportsFromOldFile, oldFile.fileName, importAdder, program); diff --git a/tests/cases/fourslash/moveToNewFileSymbolWithoutParent.ts b/tests/cases/fourslash/moveToNewFileSymbolWithoutParent.ts new file mode 100644 index 00000000000..ea38f3227bf --- /dev/null +++ b/tests/cases/fourslash/moveToNewFileSymbolWithoutParent.ts @@ -0,0 +1,27 @@ +/// + +// Test case to reproduce the debug assertion failure +// When moving symbols that don't have a parent but aren't modules +// This reproduces the scenario with symbols exported separately from declaration + +// @Filename: /lib.ts +////const Component = function() { return "component"; }; +////export { Component }; + +// @Filename: /main.ts +////import { Component } from "./lib"; +////[|function useComponent() { +//// return Component(); +////}|] + +verify.moveToNewFile({ + newFileContents: { + "/main.ts": ``, + "/useComponent.ts": `import { Component } from "./lib"; + +function useComponent() { + return Component(); +} +` + } +}); \ No newline at end of file