Skip to content

Commit 4af6ca9

Browse files
authored
Extract to function (#11467)
* Extract to function.
1 parent 7e4ee25 commit 4af6ca9

File tree

10 files changed

+373
-42
lines changed

10 files changed

+373
-42
lines changed

Extension/package.json

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "cpptools",
33
"displayName": "C/C++",
44
"description": "C/C++ IntelliSense, debugging, and code browsing.",
5-
"version": "1.17.5-main",
5+
"version": "1.18.0-main",
66
"publisher": "ms-vscode",
77
"icon": "LanguageCCPP_color_128x.png",
88
"readme": "README.md",
@@ -3351,6 +3351,15 @@
33513351
"apply": "first"
33523352
},
33533353
"when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && editorTextFocus && !(config.C_Cpp.intelliSenseEngine =~ /^[dD]isabled$/)"
3354+
},
3355+
{
3356+
"command": "editor.action.codeAction",
3357+
"key": "ctrl+shift+r ctrl+e",
3358+
"args": {
3359+
"kind": "refactor.extract.function",
3360+
"apply": "first"
3361+
},
3362+
"when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && editorTextFocus && !(config.C_Cpp.intelliSenseEngine =~ /^[dD]isabled$/)"
33543363
}
33553364
],
33563365
"debuggers": [
@@ -6250,13 +6259,25 @@
62506259
"languages": [
62516260
"c",
62526261
"cpp",
6253-
"cude-cpp"
6262+
"cuda-cpp"
62546263
],
62556264
"actions": {
62566265
"kind": "refactor.inline.macro",
62576266
"title": "%c_cpp.codeActions.refactor.inline.macro.title%",
62586267
"description": "%c_cpp.codeActions.refactor.inline.macro.description%"
62596268
}
6269+
},
6270+
{
6271+
"languages": [
6272+
"c",
6273+
"cpp",
6274+
"cuda-cpp"
6275+
],
6276+
"actions": {
6277+
"kind": "refactor.extract.function",
6278+
"title": "%c_cpp.codeActions.refactor.extract.function.title%",
6279+
"description": "%c_cpp.codeActions.refactor.extract.function.description%"
6280+
}
62606281
}
62616282
]
62626283
},

Extension/package.nls.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,8 @@
997997
"c_cpp.walkthrough.customize.debugging.altText": "Image that shows Add Debug Configuration in the drop-down",
998998
"c_cpp.codeActions.refactor.inline.macro.title": "Inline macro",
999999
"c_cpp.codeActions.refactor.inline.macro.description": "Replace the macro invocation with the expanded code.",
1000+
"c_cpp.codeActions.refactor.extract.function.title": "Extract to function",
1001+
"c_cpp.codeActions.refactor.extract.function.description": "Extract the selected code to a free or member function.",
10001002
"c_cpp.configuration.refactoring.includeHeader.markdownDescription": "Controls whether to include the header file of a refactored function/symbol to its corresponding source file when doing a refactoring action, such as create declaration/definition.",
10011003
"c_cpp.configuration.refactoring.includeHeader.always.description": "Always include the header file if it is not included explicitly in its source file.",
10021004
"c_cpp.configuration.refactoring.includeHeader.ifNeeded.description": "Only include the header file if it is not included explicitly in its source file or through implicit inclusion.",

Extension/src/LanguageServer/Providers/codeActionProvider.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface CodeActionCommand {
2828
edit?: TextEdit;
2929
uri?: string;
3030
range?: Range;
31+
disabledReason?: string;
3132
}
3233

3334
interface GetCodeActionsResult {
@@ -44,6 +45,8 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
4445
}
4546

4647
private static inlineMacroKind: vscode.CodeActionKind = vscode.CodeActionKind.RefactorInline.append("macro");
48+
private static extractToFunctionKind: vscode.CodeActionKind = vscode.CodeActionKind.RefactorExtract.append("function");
49+
private static expandSelectionKind: vscode.CodeActionKind = CodeActionProvider.extractToFunctionKind.append("expandSelection");
4750

4851
public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range | vscode.Selection,
4952
context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise<(vscode.Command | vscode.CodeAction)[]> {
@@ -85,6 +88,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
8588
this.client.configuration.CurrentConfiguration?.compilerPathInCppPropertiesJson !== undefined ||
8689
!!this.client.configuration.CurrentConfiguration?.compileCommandsInCppPropertiesJson ||
8790
!!this.client.configuration.CurrentConfiguration?.configurationProviderInCppPropertiesJson;
91+
const hasExperimentalFeatures: boolean = new CppSettings().experimentalFeatures ?? false;
8892

8993
// Convert to vscode.CodeAction array
9094
let hasInlineMacro: boolean = false;
@@ -205,6 +209,20 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
205209
} else {
206210
return;
207211
}
212+
} else if (command.command === "C_Cpp.ExtractToFunction" ||
213+
command.command === "C_Cpp.ExtractToMemberFunction") {
214+
if (!hasExperimentalFeatures) {
215+
return;
216+
}
217+
codeActionKind = CodeActionProvider.extractToFunctionKind;
218+
} else if (command.command === "C_Cpp.ExtractToFreeFunction") {
219+
// TODO: https://github.com/microsoft/vscode-cpptools/issues/11473 needs to be fixed.
220+
return;
221+
} else if (command.command === "C_Cpp.ExpandSelection") {
222+
if (!hasExperimentalFeatures) {
223+
return;
224+
}
225+
codeActionKind = CodeActionProvider.expandSelectionKind;
208226
}
209227
const vscodeCodeAction: vscode.CodeAction = {
210228
title: title,
@@ -214,7 +232,8 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
214232
arguments: command.arguments
215233
},
216234
edit: wsEdit,
217-
kind: codeActionKind
235+
kind: codeActionKind,
236+
disabled: command.disabledReason ? { reason: command.disabledReason } : undefined
218237
};
219238
resultCodeActions.push(vscodeCodeAction);
220239
};
@@ -229,11 +248,11 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
229248
if (!editor) {
230249
return false;
231250
}
232-
const result: vscode.Hover[] = <vscode.Hover[]>(await vscode.commands.executeCommand('vscode.executeHoverProvider', document.uri, range.start));
251+
const result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', document.uri, range.start)) as vscode.Hover[];
233252
if (result.length === 0) {
234253
return false;
235254
}
236-
const hoverResult: vscode.MarkdownString = <vscode.MarkdownString>result[0].contents[0];
255+
const hoverResult: vscode.MarkdownString = result[0].contents[0] as vscode.MarkdownString;
237256
if (!hoverResult.value.includes(localize("expands.to", "Expands to:"))) {
238257
return false;
239258
}

Extension/src/LanguageServer/Providers/documentRangeFormattingEditProvider.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export class DocumentRangeFormattingEditProvider implements vscode.DocumentRange
1313
this.client = client;
1414
}
1515

16-
public async provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range, options: vscode.FormattingOptions, token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
16+
public async provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range,
17+
options: vscode.FormattingOptions, token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
1718
const settings: CppSettings = new CppSettings(vscode.workspace.getWorkspaceFolder(document.uri)?.uri);
1819
if (settings.formattingEngine === "disabled") {
1920
return [];
@@ -58,4 +59,12 @@ export class DocumentRangeFormattingEditProvider implements vscode.DocumentRange
5859
return configCallBack(editorConfigSettings);
5960
}
6061
}
62+
63+
// TODO: This is needed for correct Extract to function formatting.
64+
/*
65+
public async provideDocumentRangesFormattingEdits(_document: vscode.TextDocument, _ranges: vscode.Range[],
66+
_options: vscode.FormattingOptions, _token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
67+
return [];
68+
}
69+
*/
6170
}

Extension/src/LanguageServer/Providers/renameProvider.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ 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+
}
2737
await this.client.ready;
2838
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
2939

0 commit comments

Comments
 (0)