1+ import  {  getModuleSpecifier  }  from  "../../compiler/moduleSpecifiers" ; 
12import  { 
23    AnyImportOrRequireStatement , 
34    append , 
@@ -16,13 +17,13 @@ import {
1617    concatenate , 
1718    contains , 
1819    copyEntries , 
20+     createModuleSpecifierResolutionHost , 
1921    createTextRangeFromSpan , 
2022    Debug , 
2123    Declaration , 
2224    DeclarationStatement , 
2325    Diagnostics , 
2426    emptyArray , 
25-     ensurePathIsNonModuleName , 
2627    EnumDeclaration , 
2728    escapeLeadingUnderscores , 
2829    Expression , 
@@ -102,9 +103,9 @@ import {
102103    rangeContainsRange , 
103104    RefactorContext , 
104105    RefactorEditInfo , 
105-     removeFileExtension , 
106106    RequireOrImportCall , 
107107    RequireVariableStatement , 
108+     resolvePath , 
108109    ScriptTarget , 
109110    skipAlias , 
110111    some , 
@@ -191,13 +192,12 @@ function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes
191192
192193    const  currentDirectory  =  getDirectoryPath ( oldFile . fileName ) ; 
193194    const  extension  =  extensionFromPath ( oldFile . fileName ) ; 
194-     const  newModuleName  =  makeUniqueModuleName ( getNewModuleName ( usage . oldFileImportsFromNewFile ,  usage . movedSymbols ) ,  extension ,  currentDirectory ,  host ) ; 
195-     const  newFileNameWithExtension  =  newModuleName  +  extension ; 
195+     const  newFileBasename  =  makeUniqueModuleName ( getNewModuleName ( usage . oldFileImportsFromNewFile ,  usage . movedSymbols ) ,  extension ,  currentDirectory ,  host ) ; 
196196
197197    // If previous file was global, this is easy. 
198-     changes . createNewFile ( oldFile ,  combinePaths ( currentDirectory ,  newFileNameWithExtension ) ,  getNewStatementsAndRemoveFromOldFile ( oldFile ,  usage ,  changes ,  toMove ,  program ,  newModuleName ,  preferences ) ) ; 
198+     changes . createNewFile ( oldFile ,  combinePaths ( currentDirectory ,  newFileBasename   +   extension ) ,  getNewStatementsAndRemoveFromOldFile ( oldFile ,  usage ,  changes ,  toMove ,  program ,  host ,   newFileBasename ,   extension ,  preferences ) ) ; 
199199
200-     addNewFileToTsconfig ( program ,  changes ,  oldFile . fileName ,  newFileNameWithExtension ,  hostGetCanonicalFileName ( host ) ) ; 
200+     addNewFileToTsconfig ( program ,  changes ,  oldFile . fileName ,  newFileBasename   +   extension ,  hostGetCanonicalFileName ( host ) ) ; 
201201} 
202202
203203interface  StatementRange  { 
@@ -258,7 +258,7 @@ function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTrack
258258} 
259259
260260function  getNewStatementsAndRemoveFromOldFile ( 
261-     oldFile : SourceFile ,  usage : UsageInfo ,  changes : textChanges . ChangeTracker ,  toMove : ToMove ,  program : Program ,  newModuleName : string ,  preferences : UserPreferences , 
261+     oldFile : SourceFile ,  usage : UsageInfo ,  changes : textChanges . ChangeTracker ,  toMove : ToMove ,  program : Program ,  host :  LanguageServiceHost ,   newModuleName :  string ,   extension : string ,  preferences : UserPreferences , 
262262)  { 
263263    const  checker  =  program . getTypeChecker ( ) ; 
264264    const  prologueDirectives  =  takeWhile ( oldFile . statements ,  isPrologueDirective ) ; 
@@ -269,16 +269,16 @@ function getNewStatementsAndRemoveFromOldFile(
269269
270270    const  useEsModuleSyntax  =  ! ! oldFile . externalModuleIndicator ; 
271271    const  quotePreference  =  getQuotePreference ( oldFile ,  preferences ) ; 
272-     const  importsFromNewFile  =  createOldFileImportsFromNewFile ( usage . oldFileImportsFromNewFile ,  newModuleName ,  useEsModuleSyntax ,  quotePreference ) ; 
272+     const  importsFromNewFile  =  createOldFileImportsFromNewFile ( oldFile ,   usage . oldFileImportsFromNewFile ,  newModuleName   +   extension ,   program ,   host ,  useEsModuleSyntax ,  quotePreference ) ; 
273273    if  ( importsFromNewFile )  { 
274274        insertImports ( changes ,  oldFile ,  importsFromNewFile ,  /*blankLineBetween*/  true ) ; 
275275    } 
276276
277277    deleteUnusedOldImports ( oldFile ,  toMove . all ,  changes ,  usage . unusedImportsFromOldFile ,  checker ) ; 
278278    deleteMovedStatements ( oldFile ,  toMove . ranges ,  changes ) ; 
279-     updateImportsInOtherFiles ( changes ,  program ,  oldFile ,  usage . movedSymbols ,  newModuleName ) ; 
279+     updateImportsInOtherFiles ( changes ,  program ,  host ,   oldFile ,  usage . movedSymbols ,  newModuleName ,   extension ) ; 
280280
281-     const  imports  =  getNewFileImportsAndAddExportInOldFile ( oldFile ,  usage . oldImportsNeededByNewFile ,  usage . newFileImportsFromOldFile ,  changes ,  checker ,  useEsModuleSyntax ,  quotePreference ) ; 
281+     const  imports  =  getNewFileImportsAndAddExportInOldFile ( oldFile ,  usage . oldImportsNeededByNewFile ,  usage . newFileImportsFromOldFile ,  changes ,  checker ,  program ,   host ,   useEsModuleSyntax ,  quotePreference ) ; 
282282    const  body  =  addExports ( oldFile ,  toMove . all ,  usage . oldFileImportsFromNewFile ,  useEsModuleSyntax ) ; 
283283    if  ( imports . length  &&  body . length )  { 
284284        return  [ 
@@ -309,7 +309,9 @@ function deleteUnusedOldImports(oldFile: SourceFile, toMove: readonly Statement[
309309    } 
310310} 
311311
312- function  updateImportsInOtherFiles ( changes : textChanges . ChangeTracker ,  program : Program ,  oldFile : SourceFile ,  movedSymbols : ReadonlySymbolSet ,  newModuleName : string ) : void { 
312+ function  updateImportsInOtherFiles ( 
313+     changes : textChanges . ChangeTracker ,  program : Program ,  host : LanguageServiceHost ,  oldFile : SourceFile ,  movedSymbols : ReadonlySymbolSet ,  newModuleName : string ,  extension : string 
314+ ) : void { 
313315    const  checker  =  program . getTypeChecker ( ) ; 
314316    for  ( const  sourceFile  of  program . getSourceFiles ( ) )  { 
315317        if  ( sourceFile  ===  oldFile )  continue ; 
@@ -324,7 +326,9 @@ function updateImportsInOtherFiles(changes: textChanges.ChangeTracker, program:
324326                    return  ! ! symbol  &&  movedSymbols . has ( symbol ) ; 
325327                } ; 
326328                deleteUnusedImports ( sourceFile ,  importNode ,  changes ,  shouldMove ) ;  // These will be changed to imports from the new file 
327-                 const  newModuleSpecifier  =  combinePaths ( getDirectoryPath ( moduleSpecifierFromImport ( importNode ) . text ) ,  newModuleName ) ; 
329+ 
330+                 const  pathToNewFileWithExtension  =  resolvePath ( getDirectoryPath ( oldFile . path ) ,  newModuleName  +  extension ) ; 
331+                 const  newModuleSpecifier  =  getModuleSpecifier ( program . getCompilerOptions ( ) ,  sourceFile ,  sourceFile . path ,  pathToNewFileWithExtension ,  createModuleSpecifierResolutionHost ( program ,  host ) ) ; 
328332                const  newImportDeclaration  =  filterImport ( importNode ,  factory . createStringLiteral ( newModuleSpecifier ) ,  shouldMove ) ; 
329333                if  ( newImportDeclaration )  changes . insertNodeAfter ( sourceFile ,  statement ,  newImportDeclaration ) ; 
330334
@@ -431,7 +435,15 @@ type SupportedImportStatement =
431435    |  ImportEqualsDeclaration 
432436    |  VariableStatement ; 
433437
434- function  createOldFileImportsFromNewFile ( newFileNeedExport : ReadonlySymbolSet ,  newFileNameWithExtension : string ,  useEs6Imports : boolean ,  quotePreference : QuotePreference ) : AnyImportOrRequireStatement  |  undefined  { 
438+ function  createOldFileImportsFromNewFile ( 
439+     sourceFile : SourceFile , 
440+     newFileNeedExport : ReadonlySymbolSet , 
441+     newFileNameWithExtension : string , 
442+     program : Program , 
443+     host : LanguageServiceHost , 
444+     useEs6Imports : boolean , 
445+     quotePreference : QuotePreference 
446+ ) : AnyImportOrRequireStatement  |  undefined  { 
435447    let  defaultImport : Identifier  |  undefined ; 
436448    const  imports : string [ ]  =  [ ] ; 
437449    newFileNeedExport . forEach ( symbol  =>  { 
@@ -442,20 +454,31 @@ function createOldFileImportsFromNewFile(newFileNeedExport: ReadonlySymbolSet, n
442454            imports . push ( symbol . name ) ; 
443455        } 
444456    } ) ; 
445-     return  makeImportOrRequire ( defaultImport ,  imports ,  newFileNameWithExtension ,  useEs6Imports ,  quotePreference ) ; 
457+     return  makeImportOrRequire ( sourceFile ,   defaultImport ,  imports ,  newFileNameWithExtension ,   program ,   host ,  useEs6Imports ,  quotePreference ) ; 
446458} 
447459
448- function  makeImportOrRequire ( defaultImport : Identifier  |  undefined ,  imports : readonly  string [ ] ,  path : string ,  useEs6Imports : boolean ,  quotePreference : QuotePreference ) : AnyImportOrRequireStatement  |  undefined  { 
449-     path  =  ensurePathIsNonModuleName ( path ) ; 
460+ function  makeImportOrRequire ( 
461+     sourceFile : SourceFile , 
462+     defaultImport : Identifier  |  undefined , 
463+     imports : readonly  string [ ] , 
464+     newFileNameWithExtension : string , 
465+     program : Program , 
466+     host : LanguageServiceHost , 
467+     useEs6Imports : boolean , 
468+     quotePreference : QuotePreference 
469+ ) : AnyImportOrRequireStatement  |  undefined  { 
470+     const  pathToNewFile  =  resolvePath ( getDirectoryPath ( sourceFile . path ) ,  newFileNameWithExtension ) ; 
471+     const  pathToNewFileWithCorrectExtension  =  getModuleSpecifier ( program . getCompilerOptions ( ) ,  sourceFile ,  sourceFile . path ,  pathToNewFile ,  createModuleSpecifierResolutionHost ( program ,  host ) ) ; 
472+ 
450473    if  ( useEs6Imports )  { 
451474        const  specifiers  =  imports . map ( i  =>  factory . createImportSpecifier ( /*isTypeOnly*/  false ,  /*propertyName*/  undefined ,  factory . createIdentifier ( i ) ) ) ; 
452-         return  makeImportIfNecessary ( defaultImport ,  specifiers ,  path ,  quotePreference ) ; 
475+         return  makeImportIfNecessary ( defaultImport ,  specifiers ,  pathToNewFileWithCorrectExtension ,  quotePreference ) ; 
453476    } 
454477    else  { 
455478        Debug . assert ( ! defaultImport ,  "No default import should exist" ) ;  // If there's a default export, it should have been an es6 module. 
456479        const  bindingElements  =  imports . map ( i  =>  factory . createBindingElement ( /*dotDotDotToken*/  undefined ,  /*propertyName*/  undefined ,  i ) ) ; 
457480        return  bindingElements . length 
458-             ? makeVariableStatement ( factory . createObjectBindingPattern ( bindingElements ) ,  /*type*/  undefined ,  createRequireCall ( factory . createStringLiteral ( path ) ) )  as  RequireVariableStatement 
481+             ? makeVariableStatement ( factory . createObjectBindingPattern ( bindingElements ) ,  /*type*/  undefined ,  createRequireCall ( factory . createStringLiteral ( pathToNewFileWithCorrectExtension ) ) )  as  RequireVariableStatement 
459482            : undefined ; 
460483    } 
461484} 
@@ -564,6 +587,8 @@ function getNewFileImportsAndAddExportInOldFile(
564587    newFileImportsFromOldFile : ReadonlySymbolSet , 
565588    changes : textChanges . ChangeTracker , 
566589    checker : TypeChecker , 
590+     program : Program , 
591+     host : LanguageServiceHost , 
567592    useEsModuleSyntax : boolean , 
568593    quotePreference : QuotePreference , 
569594) : readonly  SupportedImportStatement [ ]  { 
@@ -600,7 +625,7 @@ function getNewFileImportsAndAddExportInOldFile(
600625        } 
601626    } ) ; 
602627
603-     append ( copiedOldImports ,  makeImportOrRequire ( oldFileDefault ,  oldFileNamedImports ,  removeFileExtension ( getBaseFileName ( oldFile . fileName ) ) ,  useEsModuleSyntax ,  quotePreference ) ) ; 
628+     append ( copiedOldImports ,  makeImportOrRequire ( oldFile ,   oldFileDefault ,  oldFileNamedImports ,  getBaseFileName ( oldFile . fileName ) ,   program ,   host ,  useEsModuleSyntax ,  quotePreference ) ) ; 
604629    return  copiedOldImports ; 
605630} 
606631
0 commit comments