@@ -35,6 +35,7 @@ import {
3535 find ,
3636 FindAllReferences ,
3737 findIndex ,
38+ findLastIndex ,
3839 firstDefined ,
3940 flatMap ,
4041 forEachKey ,
@@ -51,6 +52,7 @@ import {
5152 getRangesWhere ,
5253 getRefactorContextSpan ,
5354 getRelativePathFromFile ,
55+ getSourceFileOfNode ,
5456 getSynthesizedDeepClone ,
5557 getUniqueName ,
5658 hasJSFileExtension ,
@@ -69,6 +71,7 @@ import {
6971 isDeclarationName ,
7072 isExpressionStatement ,
7173 isExternalModuleReference ,
74+ isFunctionLikeDeclaration ,
7275 isIdentifier ,
7376 isImportDeclaration ,
7477 isImportEqualsDeclaration ,
@@ -80,6 +83,7 @@ import {
8083 isPropertyAssignment ,
8184 isRequireCall ,
8285 isSourceFile ,
86+ isStatement ,
8387 isStringLiteral ,
8488 isStringLiteralLike ,
8589 isValidTypeOnlyAliasUseSite ,
@@ -176,8 +180,8 @@ registerRefactor(refactorNameForMoveToFile, {
176180function doChange ( context : RefactorContext , oldFile : SourceFile , targetFile : string , program : Program , toMove : ToMove , changes : textChanges . ChangeTracker , host : LanguageServiceHost , preferences : UserPreferences ) : void {
177181 const checker = program . getTypeChecker ( ) ;
178182 const usage = getUsageInfo ( oldFile , toMove . all , checker ) ;
179- //For a new file or an existing blank target file
180- if ( ! host . fileExists ( targetFile ) || host . fileExists ( targetFile ) && program . getSourceFile ( targetFile ) ?. statements . length === 0 ) {
183+ //For a new file
184+ if ( ! host . fileExists ( targetFile ) ) {
181185 changes . createNewFile ( oldFile , targetFile , getNewStatementsAndRemoveFromOldFile ( oldFile , targetFile , usage , changes , toMove , program , host , preferences ) ) ;
182186 addNewFileToTsconfig ( program , changes , oldFile . fileName , targetFile , hostGetCanonicalFileName ( host ) ) ;
183187 }
@@ -189,7 +193,15 @@ function doChange(context: RefactorContext, oldFile: SourceFile, targetFile: str
189193}
190194
191195function getNewStatementsAndRemoveFromOldFile (
192- oldFile : SourceFile , targetFile : string | SourceFile , usage : UsageInfo , changes : textChanges . ChangeTracker , toMove : ToMove , program : Program , host : LanguageServiceHost , preferences : UserPreferences , importAdder ?: codefix . ImportAdder
196+ oldFile : SourceFile ,
197+ targetFile : string | SourceFile ,
198+ usage : UsageInfo ,
199+ changes : textChanges . ChangeTracker ,
200+ toMove : ToMove ,
201+ program : Program ,
202+ host : LanguageServiceHost ,
203+ preferences : UserPreferences ,
204+ importAdder ?: codefix . ImportAdder
193205) {
194206 const checker = program . getTypeChecker ( ) ;
195207 const prologueDirectives = takeWhile ( oldFile . statements , isPrologueDirective ) ;
@@ -218,6 +230,9 @@ function getNewStatementsAndRemoveFromOldFile(
218230 if ( targetFile . statements . length > 0 ) {
219231 changes . insertNodesAfter ( targetFile , targetFile . statements [ targetFile . statements . length - 1 ] , body ) ;
220232 }
233+ else {
234+ changes . insertNodesAtEndOfFile ( targetFile , body , /*blankLineBetween*/ false ) ;
235+ }
221236 if ( imports . length > 0 ) {
222237 insertImports ( changes , targetFile , imports , /*blankLineBetween*/ true , preferences ) ;
223238 }
@@ -890,6 +905,11 @@ function getRangeToMove(context: RefactorContext): RangeToMove | undefined {
890905 return { toMove : [ statements [ startNodeIndex ] ] , afterLast : statements [ startNodeIndex + 1 ] } ;
891906 }
892907
908+ const overloadRangeToMove = getOverloadRangeToMove ( file , startStatement ) ;
909+ if ( overloadRangeToMove ) {
910+ return overloadRangeToMove ;
911+ }
912+
893913 // Can't only partially include the start node or be partially into the next node
894914 if ( range . pos > startStatement . getStart ( file ) ) return undefined ;
895915 const afterEndNodeIndex = findIndex ( statements , s => s . end > range . end , startNodeIndex ) ;
@@ -1109,4 +1129,16 @@ function isNonVariableTopLevelDeclaration(node: Node): node is NonVariableTopLev
11091129 }
11101130}
11111131
1112-
1132+ function getOverloadRangeToMove ( sourceFile : SourceFile , statement : Statement ) {
1133+ if ( isFunctionLikeDeclaration ( statement ) ) {
1134+ const declarations = statement . symbol . declarations ;
1135+ if ( declarations === undefined || length ( declarations ) <= 1 || ! contains ( declarations , statement ) ) {
1136+ return undefined ;
1137+ }
1138+ const lastDecl = declarations [ length ( declarations ) - 1 ] ;
1139+ const statementsToMove = mapDefined ( declarations , d => getSourceFileOfNode ( d ) === sourceFile && isStatement ( d ) ? d : undefined ) ;
1140+ const end = findLastIndex ( sourceFile . statements , s => s . end > lastDecl . end ) ;
1141+ return { toMove : statementsToMove , afterLast : end >= 0 ? sourceFile . statements [ end ] : undefined } ;
1142+ }
1143+ return undefined ;
1144+ }
0 commit comments