Skip to content

Commit 16f6cf9

Browse files
authored
Change Extract to Function to name earlier. (#11568)
* Change Extract to Function to name earlier.
1 parent 45addfd commit 16f6cf9

File tree

2 files changed

+37
-48
lines changed

2 files changed

+37
-48
lines changed

Extension/src/LanguageServer/Providers/renameProvider.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,6 @@ export class RenameProvider implements vscode.RenameProvider {
2424
}
2525

2626
public async provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string, _token: vscode.CancellationToken): Promise<vscode.WorkspaceEdit | undefined> {
27-
// Bypass the normal rename processing during Extract to function,
28-
// since we already know the locations of the required edits.
29-
if (this.client.renameDataForExtractToFunction.length > 0) {
30-
const workspaceEditResult: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
31-
for (const renameData of this.client.renameDataForExtractToFunction) {
32-
workspaceEditResult.replace(renameData.uri, renameData.range, newName);
33-
}
34-
this.client.renameDataForExtractToFunction = [];
35-
return workspaceEditResult;
36-
}
3727
await this.client.ready;
3828
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
3929

Extension/src/LanguageServer/client.ts

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ export interface CreateDeclarationOrDefinitionResult extends WorkspaceEditResult
342342

343343
export interface ExtractToFunctionParams extends SelectionParams {
344344
extractAsGlobal: boolean;
345+
name: string;
345346
}
346347

347348
interface ShowMessageWindowParams {
@@ -3452,10 +3453,14 @@ export class DefaultClient implements Client {
34523453
return;
34533454
}
34543455

3455-
// TODO: Show a quick pick to get the name before generating the code.
3456-
// That would allow the formatting to be done without waiting for the rename.
3457-
// Also, it's less error prone and eliminates a class of bugs in which the
3458-
// rename position can be incorrect.
3456+
let functionName: string | undefined = await vscode.window.showInputBox({
3457+
title: localize('handle.extract.name', 'Name the extracted function'),
3458+
placeHolder: localize('handle.extract.new.function', 'NewFunction')
3459+
});
3460+
3461+
if (functionName === undefined || functionName === "") {
3462+
functionName = "NewFunction";
3463+
}
34593464

34603465
const params: ExtractToFunctionParams = {
34613466
uri: editor.document.uri.toString(),
@@ -3469,7 +3474,8 @@ export class DefaultClient implements Client {
34693474
line: editor.selection.end.line
34703475
}
34713476
},
3472-
extractAsGlobal
3477+
extractAsGlobal,
3478+
name: functionName
34733479
};
34743480

34753481
const result: WorkspaceEditResult = await this.languageClient.sendRequest(ExtractToFunctionRequest, params);
@@ -3482,15 +3488,15 @@ export class DefaultClient implements Client {
34823488

34833489
// Handle error messaging
34843490
if (result.errorText) {
3485-
void vscode.window.showErrorMessage(result.errorText);
3491+
void vscode.window.showErrorMessage(`${localize("handle.extract.error",
3492+
"Extract to function failed: {0}", result.errorText)}`);
34863493
return;
34873494
}
34883495

34893496
let workspaceEdits: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
34903497
let replaceEditRange: vscode.Range | undefined;
34913498
let hasProcessedReplace: boolean = false;
34923499
const formatUriAndRanges: VsCodeUriAndRange[] = [];
3493-
this.renameDataForExtractToFunction = [];
34943500
let lineOffset: number = 0;
34953501
let headerFileLineOffset: number = 0;
34963502
let isSourceFile: boolean = true;
@@ -3515,7 +3521,7 @@ export class DefaultClient implements Client {
35153521
range = new vscode.Range(new vscode.Position(range.start.line + headerFileLineOffset, range.start.character),
35163522
new vscode.Position(range.end.line + headerFileLineOffset, range.end.character));
35173523
}
3518-
const isReplace: boolean = !range.isEmpty;
3524+
const isReplace: boolean = !range.isEmpty && isSourceFile;
35193525
lineOffset += nextLineOffset;
35203526
nextLineOffset = (edit.newText.match(/\n/g) ?? []).length;
35213527
let rangeStartLine: number = range.start.line + lineOffset;
@@ -3559,36 +3565,32 @@ export class DefaultClient implements Client {
35593565
new vscode.Position(rangeStartLine + (nextLineOffset < 0 ? 0 : nextLineOffset),
35603566
isReplace ? range.end.character :
35613567
range.end.character + edit.newText.length - rangeStartCharacter))});
3562-
const newFunctionString: string = "NewFunction";
3563-
3564-
// Handle additional declaration lines added before the new function call.
3565-
let currentText: string = edit.newText.substring(rangeStartCharacter);
3566-
let currentTextNextLineStart: number = currentText.indexOf("\n");
3567-
let currentTextNewFunctionStart: number = currentText.indexOf(newFunctionString);
3568-
let currentTextNextLineStartUpdated: boolean = false;
3569-
while (currentTextNextLineStart !== -1 && currentTextNextLineStart < currentTextNewFunctionStart) {
3570-
++rangeStartLine;
3571-
currentText = currentText.substring(currentTextNextLineStart + 1);
3572-
currentTextNextLineStart = currentText.indexOf("\n");
3573-
currentTextNewFunctionStart = currentText.indexOf(newFunctionString);
3574-
currentTextNextLineStartUpdated = true;
3575-
}
3576-
rangeStartCharacter = (rangeStartCharacter === 0 && !currentTextNextLineStartUpdated ? range.start.character : 0) +
3577-
currentTextNewFunctionStart;
3578-
if (rangeStartCharacter < 0) {
3579-
// newFunctionString is missing -- unexpected error.
3580-
void vscode.window.showErrorMessage(`${localize("invalid.edit",
3581-
"Extract to function failed. An invalid edit was generated: '{0}'", edit.newText)}`);
3582-
continue;
3583-
}
3584-
const currentEditRange: vscode.Range = new vscode.Range(
3585-
new vscode.Position(rangeStartLine, rangeStartCharacter),
3586-
new vscode.Position(rangeStartLine, rangeStartCharacter + newFunctionString.length));
35873568
if (isReplace) {
3588-
replaceEditRange = currentEditRange;
3569+
// Handle additional declaration lines added before the new function call.
3570+
let currentText: string = edit.newText.substring(rangeStartCharacter);
3571+
let currentTextNextLineStart: number = currentText.indexOf("\n");
3572+
let currentTextNewFunctionStart: number = currentText.indexOf(functionName);
3573+
let currentTextNextLineStartUpdated: boolean = false;
3574+
while (currentTextNextLineStart !== -1 && currentTextNextLineStart < currentTextNewFunctionStart) {
3575+
++rangeStartLine;
3576+
currentText = currentText.substring(currentTextNextLineStart + 1);
3577+
currentTextNextLineStart = currentText.indexOf("\n");
3578+
currentTextNewFunctionStart = currentText.indexOf(functionName);
3579+
currentTextNextLineStartUpdated = true;
3580+
}
3581+
rangeStartCharacter = (rangeStartCharacter === 0 && !currentTextNextLineStartUpdated ? range.start.character : 0) +
3582+
currentTextNewFunctionStart;
3583+
if (rangeStartCharacter < 0) {
3584+
// functionName is missing -- unexpected error.
3585+
void vscode.window.showErrorMessage(`${localize("invalid.edit",
3586+
"Extract to function failed. An invalid edit was generated: '{0}'", edit.newText)}`);
3587+
continue;
3588+
}
3589+
replaceEditRange = new vscode.Range(
3590+
new vscode.Position(rangeStartLine, rangeStartCharacter),
3591+
new vscode.Position(rangeStartLine, rangeStartCharacter + functionName.length));
35893592
nextLineOffset -= range.end.line - range.start.line;
35903593
}
3591-
this.renameDataForExtractToFunction.push({ uri, range: currentEditRange });
35923594
}
35933595
}
35943596

@@ -3601,7 +3603,6 @@ export class DefaultClient implements Client {
36013603

36023604
const firstUri: vscode.Uri = formatUriAndRanges[0].uri;
36033605
await vscode.window.showTextDocument(firstUri, { selection: replaceEditRange });
3604-
await vscode.commands.executeCommand("editor.action.rename", firstUri, replaceEditRange.start);
36053606

36063607
// Format the new text edits.
36073608
const formatEdits: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
@@ -3645,8 +3646,6 @@ export class DefaultClient implements Client {
36453646
}
36463647
}
36473648

3648-
public renameDataForExtractToFunction: VsCodeUriAndRange[] = [];
3649-
36503649
public onInterval(): void {
36513650
// These events can be discarded until the language client is ready.
36523651
// Don't queue them up with this.notifyWhenLanguageClientReady calls.

0 commit comments

Comments
 (0)