Skip to content

Commit

Permalink
Merge pull request #11607 from microsoft/main
Browse files Browse the repository at this point in the history
Merge for 1.18.1
  • Loading branch information
sean-mcmanus authored Nov 2, 2023
2 parents 43aad3f + c26054a commit 4149493
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 61 deletions.
20 changes: 18 additions & 2 deletions Extension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# C/C++ for Visual Studio Code Changelog

## Version 1.18.1: November 2, 2023
### New Feature
* Add `#include` code action suggestions for some IntelliSense errors related to symbols not being found. [#10791](https://github.com/microsoft/vscode-cpptools/issues/10791)
* Since C code doesn't give an error for an undefined symbol, it usually won't be available for C.

### Enhancements
* Improve the walkthrough wording. [#11320](https://github.com/microsoft/vscode-cpptools/issues/11320)
* Change 'Extract to Function' to prompt for the name instead of doing a rename afterwards. [#11531](https://github.com/microsoft/vscode-cpptools/issues/11531)
* Add a pre-release available notification. [PR #11569](https://github.com/microsoft/vscode-cpptools/pull/11569)

### Bug Fixes
* Fix no error message getting shown if 'Extract to Function' creation fails. [#11567](https://github.com/microsoft/vscode-cpptools/issues/11567)
* Fix an autocomplete crash bug (primarily on Mac).
* Fix an IntelliSense crash when selecting code.

## Version 1.18.0: October 12, 2023
### New Features
* Add an 'Extract to Function' (or Member Function) code action after selecting code. [#1162](https://github.com/microsoft/vscode-cpptools/issues/1162)
* Currently, it's only enabled when `C_Cpp.experimentFeatures` is `true`. Also, 'Extract to Free Function' is disabled.
* Add the option to install a compiler, accessible through the walkthrough. [PR #11286](https://github.com/microsoft/vscode-cpptools/pull/11286)
* Currently, it's only enabled when `C_Cpp.experimentFeatures` is set to `enabled`. Also, 'Extract to Free Function' is disabled.
* Compiler acquisition improvements. [#10525](https://github.com/microsoft/vscode-cpptools/issues/10525)

### Enhancements
* Add setting `C_Cpp.refactoring.includeHeader` to customize whether or not to add an include header when doing a refactoring code action. [#11271](https://github.com/microsoft/vscode-cpptools/issues/11271)
Expand All @@ -13,6 +28,7 @@
### Bug Fixes
* Fix the debugger truncating long strings when inspecting values. [#1786](https://github.com/microsoft/vscode-cpptools/issues/1786)
* Switch to using `XDG_CACHE_HOME` on Linux for the default database path. [#10191](https://github.com/microsoft/vscode-cpptools/issues/10191)
* Fix an IntelliSense error with std::is_trivially_copyable_v. [#10712](https://github.com/microsoft/vscode-cpptools/issues/10712)
* Fix incorrect status and commands with the tag parsing language status UI. [#10749](https://github.com/microsoft/vscode-cpptools/issues/10749)
* Fix an empty (`""`) `compilerPath` in a base configuration overriding the compiler specified by a custom configuration provider or a `compile_commands.json`. [#11373](https://github.com/microsoft/vscode-cpptools/issues/11373)
* Fix a startup crash when reading values from JSON (settings) that are not the type expected. [#11375](https://github.com/microsoft/vscode-cpptools/issues/11375)
Expand Down
2 changes: 1 addition & 1 deletion Extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "1.18.0-main",
"version": "1.18.1-main",
"publisher": "ms-vscode",
"icon": "LanguageCCPP_color_128x.png",
"readme": "README.md",
Expand Down
6 changes: 3 additions & 3 deletions Extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,9 @@
"c_cpp.walkthrough.run.debug.windows.description": "Open your C++ file and click on the play button in the top right corner of the editor, or press F5 when on the file. Select \"cl.exe - Build and debug active file\" to run with the debugger.",
"c_cpp.walkthrough.run.debug.windows.altText": "Image showing a breakpoint in a C++ file, the f5 buttobn, and the run symbol in the top right",
"c_cpp.walkthrough.customize.debugging.title": "Customize debugging",
"c_cpp.walkthrough.customize.debugging.mac.description": "You can customize your debug configuration (e.g. to pass arguments to your program at run time) by selecting \"Add Debug Configuration\" to the right of the play button. The custom debug configuration is saved in your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-linux#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.linux.description": "You can customize your debug configuration (e.g. to pass arguments to your program at run time) by selecting \"Add Debug Configuration\" to the right of the play button. The custom debug configuration is saved in your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-msvc#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.windows.description": "You can customize your debug configuration (e.g. to pass arguments to your program at run time) by selecting \"Add Debug Configuration\" to the right of the play button. The custom debug configuration is saved in your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-clang-mac#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.mac.description": "To customize your debug configuration, select the Explorer in the activity bar and open a folder that includes your C++ file. Open the C++ file, and select \"Add Debug Configuration\" to the right of the play button. The new debug configuration is saved to your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-linux#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.linux.description": "To customize your debug configuration, select the Explorer in the activity bar and open a folder that includes your C++ file. Open the C++ file, and select \"Add Debug Configuration\" to the right of the play button. The new debug configuration is saved to your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-msvc#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.windows.description": "To customize your debug configuration, select the Explorer in the activity bar and open a folder that includes your C++ file. Open the C++ file, and select \"Add Debug Configuration\" to the right of the play button. The new debug configuration is saved to your project's launch.json file. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-clang-mac#_debug-helloworldcpp)",
"c_cpp.walkthrough.customize.debugging.altText": "Image that shows Add Debug Configuration in the drop-down",
"c_cpp.codeActions.refactor.inline.macro.title": "Inline macro",
"c_cpp.codeActions.refactor.inline.macro.description": "Replace the macro invocation with the expanded code.",
Expand Down
11 changes: 8 additions & 3 deletions Extension/src/LanguageServer/Providers/codeActionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,16 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
let wsEdit: vscode.WorkspaceEdit | undefined;
let codeActionKind: vscode.CodeActionKind = vscode.CodeActionKind.QuickFix;
if (command.edit) {
// Inline macro feature.
codeActionKind = CodeActionProvider.inlineMacroKind;
wsEdit = new vscode.WorkspaceEdit();
if (command.command === 'C_Cpp.AddMissingInclude') {
command.edit.newText += "\n";
}
wsEdit.replace(document.uri, makeVscodeRange(command.edit.range), command.edit.newText);
hasInlineMacro = true;
if (command.command === "edit") {
// Inline macro feature.
codeActionKind = CodeActionProvider.inlineMacroKind;
hasInlineMacro = true;
}
} else if (command.command === "C_Cpp.RemoveAllCodeAnalysisProblems" && command.uri !== undefined) {
// The "RemoveAll" message is sent for all code analysis squiggles.
const vsCodeRange: vscode.Range = makeVscodeRange(r);
Expand Down
10 changes: 0 additions & 10 deletions Extension/src/LanguageServer/Providers/renameProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ export class RenameProvider implements vscode.RenameProvider {
}

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

Expand Down
82 changes: 40 additions & 42 deletions Extension/src/LanguageServer/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export interface CreateDeclarationOrDefinitionResult extends WorkspaceEditResult

export interface ExtractToFunctionParams extends SelectionParams {
extractAsGlobal: boolean;
name: string;
}

interface ShowMessageWindowParams {
Expand Down Expand Up @@ -3452,10 +3453,14 @@ export class DefaultClient implements Client {
return;
}

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

if (functionName === undefined || functionName === "") {
functionName = "NewFunction";
}

const params: ExtractToFunctionParams = {
uri: editor.document.uri.toString(),
Expand All @@ -3469,7 +3474,8 @@ export class DefaultClient implements Client {
line: editor.selection.end.line
}
},
extractAsGlobal
extractAsGlobal,
name: functionName
};

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

// Handle error messaging
if (result.errorText) {
void vscode.window.showErrorMessage(result.errorText);
void vscode.window.showErrorMessage(`${localize("handle.extract.error",
"Extract to function failed: {0}", result.errorText)}`);
return;
}

let workspaceEdits: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
let replaceEditRange: vscode.Range | undefined;
let hasProcessedReplace: boolean = false;
const formatUriAndRanges: VsCodeUriAndRange[] = [];
this.renameDataForExtractToFunction = [];
let lineOffset: number = 0;
let headerFileLineOffset: number = 0;
let isSourceFile: boolean = true;
Expand All @@ -3515,7 +3521,7 @@ export class DefaultClient implements Client {
range = new vscode.Range(new vscode.Position(range.start.line + headerFileLineOffset, range.start.character),
new vscode.Position(range.end.line + headerFileLineOffset, range.end.character));
}
const isReplace: boolean = !range.isEmpty;
const isReplace: boolean = !range.isEmpty && isSourceFile;
lineOffset += nextLineOffset;
nextLineOffset = (edit.newText.match(/\n/g) ?? []).length;
let rangeStartLine: number = range.start.line + lineOffset;
Expand Down Expand Up @@ -3559,36 +3565,32 @@ export class DefaultClient implements Client {
new vscode.Position(rangeStartLine + (nextLineOffset < 0 ? 0 : nextLineOffset),
isReplace ? range.end.character :
range.end.character + edit.newText.length - rangeStartCharacter))});
const newFunctionString: string = "NewFunction";

// Handle additional declaration lines added before the new function call.
let currentText: string = edit.newText.substring(rangeStartCharacter);
let currentTextNextLineStart: number = currentText.indexOf("\n");
let currentTextNewFunctionStart: number = currentText.indexOf(newFunctionString);
let currentTextNextLineStartUpdated: boolean = false;
while (currentTextNextLineStart !== -1 && currentTextNextLineStart < currentTextNewFunctionStart) {
++rangeStartLine;
currentText = currentText.substring(currentTextNextLineStart + 1);
currentTextNextLineStart = currentText.indexOf("\n");
currentTextNewFunctionStart = currentText.indexOf(newFunctionString);
currentTextNextLineStartUpdated = true;
}
rangeStartCharacter = (rangeStartCharacter === 0 && !currentTextNextLineStartUpdated ? range.start.character : 0) +
currentTextNewFunctionStart;
if (rangeStartCharacter < 0) {
// newFunctionString is missing -- unexpected error.
void vscode.window.showErrorMessage(`${localize("invalid.edit",
"Extract to function failed. An invalid edit was generated: '{0}'", edit.newText)}`);
continue;
}
const currentEditRange: vscode.Range = new vscode.Range(
new vscode.Position(rangeStartLine, rangeStartCharacter),
new vscode.Position(rangeStartLine, rangeStartCharacter + newFunctionString.length));
if (isReplace) {
replaceEditRange = currentEditRange;
// Handle additional declaration lines added before the new function call.
let currentText: string = edit.newText.substring(rangeStartCharacter);
let currentTextNextLineStart: number = currentText.indexOf("\n");
let currentTextNewFunctionStart: number = currentText.indexOf(functionName);
let currentTextNextLineStartUpdated: boolean = false;
while (currentTextNextLineStart !== -1 && currentTextNextLineStart < currentTextNewFunctionStart) {
++rangeStartLine;
currentText = currentText.substring(currentTextNextLineStart + 1);
currentTextNextLineStart = currentText.indexOf("\n");
currentTextNewFunctionStart = currentText.indexOf(functionName);
currentTextNextLineStartUpdated = true;
}
rangeStartCharacter = (rangeStartCharacter === 0 && !currentTextNextLineStartUpdated ? range.start.character : 0) +
currentTextNewFunctionStart;
if (rangeStartCharacter < 0) {
// functionName is missing -- unexpected error.
void vscode.window.showErrorMessage(`${localize("invalid.edit",
"Extract to function failed. An invalid edit was generated: '{0}'", edit.newText)}`);
continue;
}
replaceEditRange = new vscode.Range(
new vscode.Position(rangeStartLine, rangeStartCharacter),
new vscode.Position(rangeStartLine, rangeStartCharacter + functionName.length));
nextLineOffset -= range.end.line - range.start.line;
}
this.renameDataForExtractToFunction.push({ uri, range: currentEditRange });
}
}

Expand All @@ -3601,15 +3603,15 @@ export class DefaultClient implements Client {

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

// Format the new text edits.
const formatEdits: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
for (const formatUriAndRange of formatUriAndRanges) {
const settings: OtherSettings = new OtherSettings(vscode.workspace.getWorkspaceFolder(formatUriAndRange.uri)?.uri);
const formatOptions: vscode.FormattingOptions = {
insertSpaces: settings.editorInsertSpaces ?? true,
tabSize: settings.editorTabSize ?? 4
tabSize: settings.editorTabSize ?? 4,
onChanges: true
};

const doFormat = async () => {
Expand All @@ -3618,10 +3620,8 @@ export class DefaultClient implements Client {
return true;
}

// TODO: Somehow invoke multiple range formatting (see https://github.com/microsoft/vscode/issues/193836).
// Maybe call DocumentRangeFormattingEditProvider.provideDocumentRangesFormattingEdits directly.
const formatTextEdits: vscode.TextEdit[] | undefined = await vscode.commands.executeCommand<vscode.TextEdit[] | undefined>(
"vscode.executeFormatRangeProvider", formatUriAndRange.uri, formatUriAndRange.range, formatOptions);
"vscode.executeFormatDocumentProvider", formatUriAndRange.uri, formatOptions);
if (!formatTextEdits || formatTextEdits.length === 0 || versionBeforeFormatting === undefined) {
return true;
}
Expand All @@ -3645,8 +3645,6 @@ export class DefaultClient implements Client {
}
}

public renameDataForExtractToFunction: VsCodeUriAndRange[] = [];

public onInterval(): void {
// These events can be discarded until the language client is ready.
// Don't queue them up with this.notifyWhenLanguageClientReady calls.
Expand Down
Loading

0 comments on commit 4149493

Please sign in to comment.