fix(54155): "Move to file" does not carry all function overload and implementation signatures (#54164)

This commit is contained in:
Oleksandr T 2023-05-25 02:17:43 +03:00 committed by GitHub
parent f4c2a227a7
commit 8ea3887f70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 237 additions and 1 deletions

View File

@ -35,6 +35,7 @@ import {
find,
FindAllReferences,
findIndex,
findLastIndex,
firstDefined,
flatMap,
forEachKey,
@ -51,6 +52,7 @@ import {
getRangesWhere,
getRefactorContextSpan,
getRelativePathFromFile,
getSourceFileOfNode,
getSynthesizedDeepClone,
getUniqueName,
hasJSFileExtension,
@ -69,6 +71,7 @@ import {
isDeclarationName,
isExpressionStatement,
isExternalModuleReference,
isFunctionLikeDeclaration,
isIdentifier,
isImportDeclaration,
isImportEqualsDeclaration,
@ -80,6 +83,7 @@ import {
isPropertyAssignment,
isRequireCall,
isSourceFile,
isStatement,
isStringLiteral,
isStringLiteralLike,
isValidTypeOnlyAliasUseSite,
@ -901,6 +905,11 @@ function getRangeToMove(context: RefactorContext): RangeToMove | undefined {
return { toMove: [statements[startNodeIndex]], afterLast: statements[startNodeIndex + 1] };
}
const overloadRangeToMove = getOverloadRangeToMove(file, startStatement);
if (overloadRangeToMove) {
return overloadRangeToMove;
}
// Can't only partially include the start node or be partially into the next node
if (range.pos > startStatement.getStart(file)) return undefined;
const afterEndNodeIndex = findIndex(statements, s => s.end > range.end, startNodeIndex);
@ -1120,4 +1129,16 @@ function isNonVariableTopLevelDeclaration(node: Node): node is NonVariableTopLev
}
}
function getOverloadRangeToMove(sourceFile: SourceFile, statement: Statement) {
if (isFunctionLikeDeclaration(statement)) {
const declarations = statement.symbol.declarations;
if (declarations === undefined || length(declarations) <= 1 || !contains(declarations, statement)) {
return undefined;
}
const lastDecl = declarations[length(declarations) - 1];
const statementsToMove = mapDefined(declarations, d => getSourceFileOfNode(d) === sourceFile && isStatement(d) ? d : undefined);
const end = findLastIndex(sourceFile.statements, s => s.end > lastDecl.end);
return { toMove: statementsToMove, afterLast: end >= 0 ? sourceFile.statements[end] : undefined };
}
return undefined;
}

View File

@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
// @Filename: /add.ts
////
// @Filename: /a.ts
////[|function add(x: number, y: number): number;|]
////function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}
verify.moveToFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
interactiveRefactorArguments: { targetFile: "/add.ts" }
});

View File

@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
// @Filename: /add.ts
////
// @Filename: /a.ts
////function add(x: number, y: number): number;
////function add(x: string, y: string): string;
////[|function add(x: any, y: any) {
//// return x + y;
////}|]
verify.moveToFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
interactiveRefactorArguments: { targetFile: "/add.ts" }
});

View File

@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
// @Filename: /add.ts
////
// @Filename: /a.ts
////function add(x: number, y: number): number;
////[|function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}|]
verify.moveToFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
interactiveRefactorArguments: { targetFile: "/add.ts" },
});

View File

@ -0,0 +1,26 @@
/// <reference path='fourslash.ts' />
// @Filename: /add.ts
////
// @Filename: /a.ts
////function add(x: number, y: number): number;
////[|function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}|]
////function remove() {}
verify.moveToFile({
newFileContents: {
"/a.ts": "function remove() {}",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
interactiveRefactorArguments: { targetFile: "/add.ts" },
});

View File

@ -0,0 +1,29 @@
/// <reference path='fourslash.ts' />
// @Filename: /add.ts
////
// @Filename: /a.ts
////function add(x: number, y: number): number;
////[|function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}|]
////export const a = add();
verify.moveToFile({
newFileContents: {
"/a.ts":
`import { add } from "./add";
export const a = add();`,
"/add.ts":
`export function add(x: number, y: number): number;
export function add(x: string, y: string): string;
export function add(x: any, y: any) {
return x + y;
}
`
},
interactiveRefactorArguments: { targetFile: "/add.ts" },
});

View File

@ -0,0 +1,21 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////[|function add(x: number, y: number): number;|]
////function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}
verify.moveToNewFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
});

View File

@ -0,0 +1,21 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////function add(x: number, y: number): number;
////function add(x: string, y: string): string;
////[|function add(x: any, y: any) {
//// return x + y;
////}|]
verify.moveToNewFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
});

View File

@ -0,0 +1,21 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////function add(x: number, y: number): number;
////[|function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}|]
verify.moveToNewFile({
newFileContents: {
"/a.ts": "",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
});

View File

@ -0,0 +1,22 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////function add(x: number, y: number): number;
////[|function add(x: string, y: string): string;
////function add(x: any, y: any) {
//// return x + y;
////}|]
////function remove() {}
verify.moveToNewFile({
newFileContents: {
"/a.ts": "function remove() {}",
"/add.ts":
`function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
`
},
});