Compare commits

...
17 Commits
Author SHA1 Message Date
Sean McManus c549c07fa6 Merge pull request #10153 from microsoft/main
Merge for 1.13.4 (again)
2022-11-16 18:11:45 -08:00
Sean McManus 340c00dc92 Update date. (#10152) 2022-11-16 17:52:33 -08:00
Sean McManus 53b6bb29ec Update loader-utils. (#10150) 2022-11-16 11:25:41 -08:00
Michelle Matias ed51a08388 Merge pull request #10148 from microsoft/main
update version 1.13.4 (#10147)
2022-11-14 15:25:57 -08:00
Michelle Matias 140eb83f73 update version 1.13.4 (#10147) 2022-11-14 15:23:55 -08:00
Sean McManus f1d9211b92 Merge pull request #10146 from microsoft/main
Merge for 1.13.4
2022-11-14 14:14:02 -08:00
Michelle Matias 64b429c9a0 1.13.4 change log (#10144) 2022-11-14 13:12:25 -08:00
Michelle Matias 8a81837bd4 Create declaration or definition feature (#10123) 2022-11-14 10:18:33 -08:00
Bernardin-MS 716979e1e3 Prepending workspace path to relative paths from CppProperties (#10045)
* Relative paths of compileCommands to workspacePath

* Address issue

* Fix lint

* Change rootUri for undefined

* Minor fix
2022-11-11 13:28:37 -05:00
Sean McManus 117ec80611 Update loader-utils. (#10122) 2022-11-08 16:12:37 -08:00
Andrew Wang 6379d6e799 Fix buffer size exceeded with NativeAttach (#10119)
* Fix BufferOverflow with NativeAttach

This PR migrates the nativeAttach child_process calls to use 'spawn'
instead of 'exec'. This allows the extension to deal with large process
listing output via input/output streams instead of using a single
hardcoded buffer.

Added support for canceling and timeout if the spawned process does not
exit within 30 seconds.
2022-11-08 10:26:01 -08:00
Michael 373e7face5 Added IAR problem matcher (#10054) (#10085) 2022-11-01 14:18:38 -07:00
Michael 50eb6f94dd Added ARMCC problem matcher (#10054) (#10101) 2022-11-01 14:16:56 -07:00
Sean McManus 801c8dd5d4 Fix doxygen generation with a selection. (#10079) 2022-10-31 10:10:57 -07:00
Bernardin-MS 27abc63d1c Adding subheaders to Extension settings (#9985) 2022-10-28 11:34:58 -07:00
Colen Garoutte-Carson 0a23125ae5 Remove direct WSL support in favor of the WSL extension (#10066) 2022-10-27 13:55:51 -07:00
Colen Garoutte-Carson e8a33ff410 Fix issue with call to cpptools-wordexp with invalid arguments (#10070) 2022-10-26 15:10:12 -07:00
14 changed files with 3027 additions and 2625 deletions
+24
View File
@@ -1,5 +1,29 @@
# C/C++ for Visual Studio Code Changelog
## Version 1.13.4: November 17, 2022
### New Features
* Add the ability to generate definitions from declarations and vice versa. [#664](https://github.com/microsoft/vscode-cpptools/issues/664)
### Enhancements
* Add sections to settings. [#8237](https://github.com/microsoft/vscode-cpptools/issues/8237)
* Check for MSVC environment variables for configuring IntelliSense. [#9745](https://github.com/microsoft/vscode-cpptools/issues/9745)
* Add "iar" and "armcc5" problem matchers. [#10054](https://github.com/microsoft/vscode-cpptools/issues/10054)
* Michael (@morsisko) [PR #10085](https://github.com/microsoft/vscode-cpptools/pull/10085), [PR #10101](https://github.com/microsoft/vscode-cpptools/pull/10101)
* Pass `--Wno-error=unknown` to clang-format to avoid failing on unsupported settings. [#10072](https://github.com/microsoft/vscode-cpptools/issues/10072)
* Add support for `/cygdrive` paths returned by some versions of Cygwin. [#10112](https://github.com/microsoft/vscode-cpptools/issues/10112)
### Bug Fixes
* Fix updates to compile_commands.json not being handled if specified using a relative path. [#7610](https://github.com/microsoft/vscode-cpptools/issues/7610)
* Fix code analysis errors related to SSE2 being enabled. [#9898](https://github.com/microsoft/vscode-cpptools/issues/9898)
* Fix Doxygen code action from appearing on a function that already has a `*/` comment. [#10009](https://github.com/microsoft/vscode-cpptools/issues/10009)
* Fix Doxygen comment generation when there's a selection. [#10028](https://github.com/microsoft/vscode-cpptools/issues/10028)
* Fixed crash on Linux/Mac when a full command line is specified in `compilerPath` containing invalid arguments. [PR #10070](https://github.com/microsoft/vscode-cpptools/pull/10070)
* Fix random "Failed to spawn IntelliSense process: 65520" on Mac. [#10091](https://github.com/microsoft/vscode-cpptools/issues/10091)
### Removed Features
* Removed explicit WSL support in favor of using the WSL extension. [#10066](https://github.com/microsoft/vscode-cpptools/pull/10066)
* The fix for an IntelliSense crash with the seqan3 library [#8956](https://github.com/microsoft/vscode-cpptools/issues/8956) in 1.13.3 was removed because it caused a regression. [#10075](https://github.com/microsoft/vscode-cpptools/issues/10075)
## Version 1.13.3: October 26, 2022
### Enhancements
* Make Doxygen hover comments customizable with `C_Cpp.doxygen.sectionTags`. [#8525](https://github.com/microsoft/vscode-cpptools/issues/8525)
+2616 -2531
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -1,4 +1,11 @@
{
"c_cpp.subheaders.intelliSense.title" : "IntelliSense",
"c_cpp.subheaders.formatting.title" : "Formatting",
"c_cpp.subheaders.codeDocumentation.title" : "Code Documentation",
"c_cpp.subheaders.codeAnalysis.title" : "Code Analysis",
"c_cpp.subheaders.debugging.title" : "Debugging",
"c_cpp.subheaders.resourceManagement.title" : "Resource Management",
"c_cpp.subheaders.miscellaneous.title" : "Miscellaneous",
"c_cpp.capabilities.untrustedWorkspaces.description": "Multiple settings can cause processes local to the workspace to be executed, e.g. C_Cpp.clang_format_path, C_Cpp.codeAnalysis.clangTidy.path, C_Cpp.addNodeAddonIncludePaths, C_Cpp.default.compilerPath, C_Cpp.default.configurationProvider, and C_Cpp.default.compileCommands, and the equivalent properties in c_cpp_properties.json.",
"c_cpp.command.configurationSelect.title": "Select a Configuration...",
"c_cpp.command.configurationProviderSelect.title": "Change Configuration Provider...",
@@ -21,6 +28,7 @@
"c_cpp.command.generateEditorConfig.title": "Generate EditorConfig contents from VC Format settings",
"c_cpp.command.GoToNextDirectiveInGroup.title": "Go to next preprocessor directive in conditional group",
"c_cpp.command.GoToPrevDirectiveInGroup.title": "Go to previous preprocessor directive in conditional group",
"c_cpp.command.CreateDeclarationOrDefinition.title": "Create Declaration / Definition",
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "Run Code Analysis on Active File",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "Run Code Analysis on Open Files",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "Run Code Analysis on All Files",
+3 -3
View File
@@ -18,15 +18,15 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
export interface AttachItemsProvider {
getAttachItems(): Promise<AttachItem[]>;
getAttachItems(token?: vscode.CancellationToken): Promise<AttachItem[]>;
}
export class AttachPicker {
constructor(private attachItemsProvider: AttachItemsProvider) { }
// We should not await on this function.
public async ShowAttachEntries(): Promise<string | undefined> {
return showQuickPick(() => this.attachItemsProvider.getAttachItems());
public async ShowAttachEntries(token?: vscode.CancellationToken): Promise<string | undefined> {
return showQuickPick(() => this.attachItemsProvider.getAttachItems(token));
}
}
@@ -353,7 +353,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
} else {
const attachItemsProvider: AttachItemsProvider = NativeAttachItemsProviderFactory.Get();
const attacher: AttachPicker = new AttachPicker(attachItemsProvider);
processId = await attacher.ShowAttachEntries();
processId = await attacher.ShowAttachEntries(token);
}
if (processId) {
+97 -26
View File
@@ -9,6 +9,7 @@ import { AttachItemsProvider } from './attachToProcess';
import { AttachItem } from './attachQuickPick';
import * as nls from 'vscode-nls';
import { findPowerShell } from '../common';
import * as vscode from 'vscode';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
@@ -38,10 +39,10 @@ export class NativeAttachItemsProviderFactory {
}
abstract class NativeAttachItemsProvider implements AttachItemsProvider {
protected abstract getInternalProcessEntries(): Promise<Process[]>;
protected abstract getInternalProcessEntries(token?: vscode.CancellationToken): Promise<Process[]>;
async getAttachItems(): Promise<AttachItem[]> {
const processEntries: Process[] = await this.getInternalProcessEntries();
async getAttachItems(token?: vscode.CancellationToken): Promise<AttachItem[]> {
const processEntries: Process[] = await this.getInternalProcessEntries(token);
// localeCompare is significantly slower than < and > (2000 ms vs 80 ms for 10,000 elements)
// We can change to localeCompare if this becomes an issue
processEntries.sort((a, b) => {
@@ -91,7 +92,7 @@ export class PsAttachItemsProvider extends NativeAttachItemsProvider {
// characters. 50 was chosen because that's the maximum length of a "label" in the
// QuickPick UI in VSCode.
protected async getInternalProcessEntries(): Promise<Process[]> {
protected async getInternalProcessEntries(token?: vscode.CancellationToken): Promise<Process[]> {
let processCmd: string = '';
switch (os.platform()) {
case 'darwin':
@@ -103,7 +104,7 @@ export class PsAttachItemsProvider extends NativeAttachItemsProvider {
default:
throw new Error(localize("os.not.supported", 'Operating system "{0}" not supported.', os.platform()));
}
const processes: string = await execChildProcess(processCmd, undefined);
const processes: string = await spawnChildProcess(processCmd, token);
return PsProcessParser.ParseProcessFromPs(processes);
}
}
@@ -164,30 +165,100 @@ export class PsProcessParser {
}
}
/**
* Originally from common.ts. Due to test code not having vscode, it was refactored to not have vscode.OutputChannel.
*/
function execChildProcess(process: string, workingDirectory?: string): Promise<string> {
function spawnChildProcess(command: string, token?: vscode.CancellationToken): Promise<string> {
return new Promise<string>((resolve, reject) => {
child_process.exec(process, { cwd: workingDirectory, maxBuffer: 500 * 1024 }, (error: Error | null, stdout: string, stderr: string) => {
const process: child_process.ChildProcess = child_process.spawn(command, { shell: true });
let stdout: string = "";
let stderr: string = "";
if (error) {
reject(error);
if (process) {
let cancellationTokenListener: vscode.Disposable | undefined; // eslint-disable-line prefer-const
// Handle timeout
const seconds: number = 30;
const processTimeout: NodeJS.Timeout = setTimeout(() => {
process.removeAllListeners();
if (cancellationTokenListener) {
cancellationTokenListener.dispose();
}
try {
process.kill();
} catch (e) {
// Failed to kill process.
}
reject(new Error(localize("timeout.processList.spawn", '"{0}" timed out after {1} seconds.', command, seconds)));
return;
}, seconds * 1000);
// Handle cancellation
cancellationTokenListener = token?.onCancellationRequested(() => {
clearTimeout(processTimeout);
process.removeAllListeners();
try {
process.kill();
} catch (e) {
// Failed to kill process.
}
reject(new Error(localize("cancel.processList.spawn", '"{0}" canceled.', command)));
return;
});
const cleanUpCallbacks = () => {
clearTimeout(processTimeout);
process.removeAllListeners();
if (cancellationTokenListener) {
cancellationTokenListener.dispose();
}
};
// Handle data streams
if (process.stdout) {
process.stdout.on('data', (data: string) => {
stdout += data.toString();
});
}
if (stderr && stderr.length > 0) {
if (stderr.indexOf('screen size is bogus') >= 0) {
// ignore this error silently; see https://github.com/microsoft/vscode/issues/75932
// see similar fix for the Node - Debug (Legacy) Extension at https://github.com/microsoft/vscode-node-debug/commit/5298920
} else {
reject(new Error(stderr));
if (process.stderr) {
process.stderr.on('data', (data: string) => {
stderr += data.toString();
});
}
// Handle process exit
process.on('close', (code: number) => {
cleanUpCallbacks();
if (code !== 0) {
let errorMessage: string = localize("error.processList.spawn", '"{0}" exited with code: "{1}".', command, code);
if (stderr && stderr.length > 0) {
errorMessage += os.EOL;
errorMessage += stderr;
}
reject(new Error(errorMessage));
return;
}
}
resolve(stdout);
});
if (stderr && stderr.length > 0) {
if (stderr.indexOf('screen size is bogus') >= 0) {
// ignore this error silently; see https://github.com/microsoft/vscode/issues/75932
// see similar fix for the Node - Debug (Legacy) Extension at https://github.com/microsoft/vscode-node-debug/commit/5298920
} else {
reject(new Error(stderr));
return;
}
}
resolve(stdout);
});
// Handle process error
process.on('error', error => {
cleanUpCallbacks();
reject(error);
});
} else {
reject(new Error(localize("failed.processList.spawn", 'Failed to spawn "{0}".', command)));
}
});
}
@@ -200,9 +271,9 @@ export class WmicAttachItemsProvider extends NativeAttachItemsProvider {
// | 887 | 746 |
// | 1308 | 1132 |
protected async getInternalProcessEntries(): Promise<Process[]> {
protected async getInternalProcessEntries(token?: vscode.CancellationToken): Promise<Process[]> {
const wmicCommand: string = 'wmic process get Name,ProcessId,CommandLine /FORMAT:list';
const processes: string = await execChildProcess(wmicCommand, undefined);
const processes: string = await spawnChildProcess(wmicCommand, token);
return WmicProcessParser.ParseProcessFromWmic(processes);
}
}
@@ -263,10 +334,10 @@ export class CimAttachItemsProvider extends NativeAttachItemsProvider {
// Perf numbers on Win10:
// TODO
protected async getInternalProcessEntries(): Promise<Process[]> {
protected async getInternalProcessEntries(token?: vscode.CancellationToken): Promise<Process[]> {
const pwshCommand: string = `${this.pwsh} -NoProfile -Command`;
const cimCommand: string = 'Get-CimInstance Win32_Process | Select-Object Name,ProcessId,CommandLine | ConvertTo-JSON';
const processes: string = await execChildProcess(`${pwshCommand} "${cimCommand}"`, undefined);
const cimCommand: string = 'Get-CimInstance Win32_Process | Select-Object Name,ProcessId,CommandLine | ConvertTo-JSON -Compress';
const processes: string = await spawnChildProcess(`${pwshCommand} "${cimCommand}"`, token);
return CimProcessParser.ParseProcessFromCim(processes);
}
}
+124 -6
View File
@@ -67,6 +67,7 @@ const languageClientCrashTimes: number[] = [];
let pendingTask: util.BlockingTask<any> | undefined;
let compilerDefaults: configs.CompilerDefaults;
let diagnosticsCollectionIntelliSense: vscode.DiagnosticCollection;
let diagnosticsCollectionRefactor: vscode.DiagnosticCollection;
let workspaceDisposables: vscode.Disposable[] = [];
export let workspaceReferences: refs.ReferencesManager;
@@ -144,6 +145,31 @@ function publishIntelliSenseDiagnostics(params: PublishIntelliSenseDiagnosticsPa
clients.timeTelemetryCollector.setUpdateRangeTime(realUri);
}
function publishRefactorDiagnostics(params: PublishRefactorDiagnosticsParams): void {
if (!diagnosticsCollectionRefactor) {
diagnosticsCollectionRefactor = vscode.languages.createDiagnosticCollection(CppSourceStr);
}
const newDiagnostics: vscode.Diagnostic[] = [];
params.diagnostics.forEach((d) => {
const message: string = getLocalizedString(d.localizeStringParams);
const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(makeVscodeRange(d.range), message, d.severity);
diagnostic.code = d.code;
diagnostic.source = CppSourceStr;
if (d.relatedInformation) {
diagnostic.relatedInformation = [];
for (const info of d.relatedInformation) {
diagnostic.relatedInformation.push(new vscode.DiagnosticRelatedInformation(makeVscodeLocation(info.location), info.message));
}
}
newDiagnostics.push(diagnostic);
});
const fileUri: vscode.Uri = vscode.Uri.parse(params.uri);
diagnosticsCollectionRefactor.set(fileUri, newDiagnostics);
}
interface WorkspaceFolderParams {
workspaceFolderUri?: string;
}
@@ -239,6 +265,11 @@ interface IntelliSenseDiagnosticRelatedInformation {
message: string;
}
interface RefactorDiagnosticRelatedInformation {
location: Location;
message: string;
}
interface IntelliSenseDiagnostic {
range: Range;
code?: number;
@@ -247,11 +278,33 @@ interface IntelliSenseDiagnostic {
relatedInformation?: IntelliSenseDiagnosticRelatedInformation[];
}
interface RefactorDiagnostic {
range: Range;
code?: number;
severity: vscode.DiagnosticSeverity;
localizeStringParams: LocalizeStringParams;
relatedInformation?: RefactorDiagnosticRelatedInformation[];
}
interface PublishIntelliSenseDiagnosticsParams {
uri: string;
diagnostics: IntelliSenseDiagnostic[];
}
interface PublishRefactorDiagnosticsParams {
uri: string;
diagnostics: RefactorDiagnostic[];
}
export interface CreateDeclarationOrDefinitionParams {
uri: string;
range: Range;
}
export interface CreateDeclarationOrDefinitionResult {
changes: { [key: string]: any[] };
}
interface ShowMessageWindowParams {
type: number;
localizeStringParams: LocalizeStringParams;
@@ -475,6 +528,7 @@ export const GetSemanticTokensRequest: RequestType<GetSemanticTokensParams, GetS
export const FormatDocumentRequest: RequestType<FormatParams, TextEdit[], void> = new RequestType<FormatParams, TextEdit[], void>('cpptools/formatDocument');
export const FormatRangeRequest: RequestType<FormatParams, TextEdit[], void> = new RequestType<FormatParams, TextEdit[], void>('cpptools/formatRange');
export const FormatOnTypeRequest: RequestType<FormatParams, TextEdit[], void> = new RequestType<FormatParams, TextEdit[], void>('cpptools/formatOnType');
const CreateDeclarationOrDefinitionRequest: RequestType<CreateDeclarationOrDefinitionParams, CreateDeclarationOrDefinitionResult, void> = new RequestType<CreateDeclarationOrDefinitionParams, CreateDeclarationOrDefinitionResult, void>('cpptools/createDeclDef');
const GoToDirectiveInGroupRequest: RequestType<GoToDirectiveInGroupParams, Position | undefined, void> = new RequestType<GoToDirectiveInGroupParams, Position | undefined, void>('cpptools/goToDirectiveInGroup');
const GenerateDoxygenCommentRequest: RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult | undefined, void> = new RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult, void>('cpptools/generateDoxygenComment');
@@ -524,6 +578,7 @@ const ReferencesNotification: NotificationType<refs.ReferencesResult> = new Noti
const ReportReferencesProgressNotification: NotificationType<refs.ReportReferencesProgressNotification> = new NotificationType<refs.ReportReferencesProgressNotification>('cpptools/reportReferencesProgress');
const RequestCustomConfig: NotificationType<string> = new NotificationType<string>('cpptools/requestCustomConfig');
const PublishIntelliSenseDiagnosticsNotification: NotificationType<PublishIntelliSenseDiagnosticsParams> = new NotificationType<PublishIntelliSenseDiagnosticsParams>('cpptools/publishIntelliSenseDiagnostics');
const PublishRefactorDiagnosticsNotification: NotificationType<PublishRefactorDiagnosticsParams> = new NotificationType<PublishRefactorDiagnosticsParams>('cpptools/publishRefactorDiagnostics');
const ShowMessageWindowNotification: NotificationType<ShowMessageWindowParams> = new NotificationType<ShowMessageWindowParams>('cpptools/showMessageWindow');
const ShowWarningNotification: NotificationType<ShowWarningParams> = new NotificationType<ShowWarningParams>('cpptools/showWarning');
const ReportTextDocumentLanguage: NotificationType<string> = new NotificationType<string>('cpptools/reportTextDocumentLanguage');
@@ -691,6 +746,7 @@ export interface Client {
handleRemoveCodeAnalysisProblems(refreshSquigglesOnSave: boolean, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void>;
handleFixCodeAnalysisProblems(workspaceEdit: vscode.WorkspaceEdit, refreshSquigglesOnSave: boolean, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void>;
handleDisableAllTypeCodeAnalysisProblems(code: string, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void>;
handleCreateDeclarationOrDefinition(): Promise<void>;
onInterval(): void;
dispose(): void;
addFileAssociations(fileAssociations: string, languageId: string): void;
@@ -1841,6 +1897,7 @@ export class DefaultClient implements Client {
}
});
this.languageClient.onNotification(PublishIntelliSenseDiagnosticsNotification, publishIntelliSenseDiagnostics);
this.languageClient.onNotification(PublishRefactorDiagnosticsNotification, publishRefactorDiagnostics);
RegisterCodeAnalysisNotifications(this.languageClient);
this.languageClient.onNotification(ShowMessageWindowNotification, showMessageWindow);
this.languageClient.onNotification(ShowWarningNotification, showWarning);
@@ -2351,8 +2408,8 @@ export class DefaultClient implements Client {
const currentFileVersion: number | undefined = openFileVersions.get(editor.document.uri.toString());
// Insert the comment only if the cursor has not moved
if (result.fileVersion === currentFileVersion &&
result.initPosition.line === editor.selection.active.line &&
result.initPosition.character === editor.selection.active.character &&
result.initPosition.line === editor.selection.start.line &&
result.initPosition.character === editor.selection.start.character &&
result.contents.length > 1) {
const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
const edits: vscode.TextEdit[] = [];
@@ -2397,6 +2454,10 @@ export class DefaultClient implements Client {
} else {
modifiedConfig.compilerArgs = compilerPathAndArgs.allCompilerArgs;
}
if (modifiedConfig.compileCommands) {
modifiedConfig.compileCommands = cppProperties.resolvePath(modifiedConfig.compileCommands, os.platform() === "win32");
}
params.configurations.push(modifiedConfig);
});
@@ -2748,10 +2809,10 @@ export class DefaultClient implements Client {
if (args !== undefined && !(args instanceof vscode.Uri)) {
codeActionArguments = args;
}
const initCursorPosition: vscode.Position = (codeActionArguments !== undefined) ? new vscode.Position(codeActionArguments.initialCursor.line, codeActionArguments.initialCursor.character) : editor.selection.active;
const initCursorPosition: vscode.Position = (codeActionArguments !== undefined) ? new vscode.Position(codeActionArguments.initialCursor.line, codeActionArguments.initialCursor.character) : editor.selection.start;
const params: GenerateDoxygenCommentParams = {
uri: editor.document.uri.toString(),
position: (codeActionArguments !== undefined) ? new vscode.Position(codeActionArguments.adjustedCursor.line, codeActionArguments.adjustedCursor.character) : editor.selection.active,
position: (codeActionArguments !== undefined) ? new vscode.Position(codeActionArguments.adjustedCursor.line, codeActionArguments.adjustedCursor.character) : editor.selection.start,
isCodeAction: codeActionArguments !== undefined,
isCursorAboveSignatureLine: codeActionArguments?.isCursorAboveSignatureLine
};
@@ -2763,8 +2824,8 @@ export class DefaultClient implements Client {
const result: GenerateDoxygenCommentResult | undefined = await this.languageClient.sendRequest(GenerateDoxygenCommentRequest, params);
// Insert the comment only if the comment has contents and the cursor has not moved
if (result !== undefined &&
initCursorPosition.line === editor.selection.active.line &&
initCursorPosition.character === editor.selection.active.character &&
initCursorPosition.line === editor.selection.start.line &&
initCursorPosition.character === editor.selection.start.character &&
result.fileVersion !== undefined &&
result.fileVersion === currentFileVersion &&
result.contents && result.contents.length > 1) {
@@ -2903,6 +2964,62 @@ export class DefaultClient implements Client {
this.handleRemoveCodeAnalysisProblems(false, identifiersAndUris);
}
public async handleCreateDeclarationOrDefinition(): Promise<void> {
let range: vscode.Range | undefined;
let uri: vscode.Uri | undefined;
// range is based on the cursor position.
const editor: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
if (editor) {
uri = editor.document.uri;
if (editor.selection.isEmpty) {
range = new vscode.Range(editor.selection.active, editor.selection.active);
} else if (editor.selection.isReversed) {
range = new vscode.Range(editor.selection.active, editor.selection.anchor);
} else {
range = new vscode.Range(editor.selection.anchor, editor.selection.active);
}
}
if (uri && range) {
const params: CreateDeclarationOrDefinitionParams = {
uri: uri.toString(),
range: {
start: {
character: range.start.character,
line: range.start.line
},
end: {
character: range.end.character,
line: range.end.line
}
}
};
const result: CreateDeclarationOrDefinitionResult = await this.languageClient.sendRequest(CreateDeclarationOrDefinitionRequest, params);
// TODO: return specific errors info in result.
if (result.changes) {
const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
let modifiedDocument: vscode.Uri | undefined;
let lastEdit: vscode.TextEdit | undefined;
for (const file in result.changes) {
const uri: vscode.Uri = vscode.Uri.file(file);
const edits: vscode.TextEdit[] = [];
for (const edit of result.changes[file]) {
const range: vscode.Range = makeVscodeRange(edit.range);
lastEdit = new vscode.TextEdit(range, edit.newText);
edits.push(lastEdit);
}
workspaceEdit.set(uri, edits);
modifiedDocument = uri;
};
if (modifiedDocument && lastEdit) {
await vscode.workspace.applyEdit(workspaceEdit);
const selectionRange: vscode.Range = lastEdit.range; // TODO: range should be the new range after text edit was applied.
await vscode.window.showTextDocument(modifiedDocument, { selection: selectionRange });
}
}
}
}
public onInterval(): void {
// These events can be discarded until the language client is ready.
// Don't queue them up with this.notifyWhenLanguageClientReady calls.
@@ -3089,6 +3206,7 @@ class NullClient implements Client {
handleRemoveCodeAnalysisProblems(refreshSquigglesOnSave: boolean, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void> { return Promise.resolve(); }
handleFixCodeAnalysisProblems(workspaceEdit: vscode.WorkspaceEdit, refreshSquigglesOnSave: boolean, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void> { return Promise.resolve(); }
handleDisableAllTypeCodeAnalysisProblems(code: string, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void> { return Promise.resolve(); }
handleCreateDeclarationOrDefinition(): Promise<void> { return Promise.resolve(); }
onInterval(): void { }
dispose(): void {
this.booleanEvent.dispose();
+9 -21
View File
@@ -115,7 +115,6 @@ export interface CompilerDefaults {
frameworks: string[];
windowsSdkVersion: string;
intelliSenseMode: string;
rootfs: string;
}
export class CppProperties {
@@ -149,7 +148,6 @@ export class CppProperties {
private compileCommandsChanged = new vscode.EventEmitter<string>();
private diagnosticCollection: vscode.DiagnosticCollection;
private prevSquiggleMetrics: Map<string, { [key: string]: number }> = new Map<string, { [key: string]: number }>();
private rootfs: string | null = null;
private settingsPanel?: SettingsPanel;
private lastCustomBrowseConfiguration: PersistentFolderState<WorkspaceBrowseConfiguration | undefined> | undefined;
private lastCustomBrowseConfigurationProviderId: PersistentFolderState<string | undefined> | undefined;
@@ -216,7 +214,6 @@ export class CppProperties {
this.defaultFrameworks = compilerDefaults.frameworks;
this.defaultWindowsSdkVersion = compilerDefaults.windowsSdkVersion;
this.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
this.rootfs = compilerDefaults.rootfs;
// defaultPaths is only used when there isn't a c_cpp_properties.json, but we don't send the configuration changed event
// to the language server until the default include paths and frameworks have been sent.
@@ -1356,15 +1353,15 @@ export class CppProperties {
return success;
}
private resolvePath(path: string | undefined, isWindows: boolean): string {
if (!path || path === "${default}") {
public resolvePath(input_path: string | undefined, isWindows: boolean): string {
if (!input_path || input_path === "${default}") {
return "";
}
let result: string = "";
// first resolve variables
result = util.resolveVariables(path, this.ExtendedEnvironment);
result = util.resolveVariables(input_path, this.ExtendedEnvironment);
if (this.rootUri) {
if (result.includes("${workspaceFolder}")) {
result = result.replace("${workspaceFolder}", this.rootUri.fsPath);
@@ -1380,16 +1377,9 @@ export class CppProperties {
result = result.replace(/\*/g, "");
}
// resolve WSL paths
if (isWindows && result.startsWith("/")) {
const mntStr: string = "/mnt/";
if (result.length > "/mnt/c/".length && result.substring(0, mntStr.length) === mntStr) {
result = result.substring(mntStr.length);
result = result.substring(0, 1) + ":" + result.substring(1);
} else if (this.rootfs && this.rootfs.length > 0) {
result = this.rootfs + result.substring(1);
// TODO: Handle WSL symlinks.
}
// Make sure all paths result to an absolute path
if (!path.isAbsolute(result) && this.rootUri) {
result = path.join(this.rootUri.fsPath, result);
}
return result;
@@ -1777,10 +1767,9 @@ export class CppProperties {
}
}
}
const isWSL: boolean = isWindows && compilerPath.startsWith("/");
let compilerPathExists: boolean = true;
if (this.rootUri && !isClCompiler) {
const checkPathExists: any = util.checkPathExistsSync(compilerPath, this.rootUri.fsPath + path.sep, isWindows, isWSL, true);
const checkPathExists: any = util.checkPathExistsSync(compilerPath, this.rootUri.fsPath + path.sep, isWindows, true);
compilerPathExists = checkPathExists.pathExists;
compilerPath = checkPathExists.path;
}
@@ -1804,12 +1793,11 @@ export class CppProperties {
dotConfigPath = currentConfiguration.dotConfig;
dotConfigPath = util.resolveVariables(dotConfigPath, this.ExtendedEnvironment).trim();
dotConfigPath = this.resolvePath(dotConfigPath, isWindows);
const isWSLDotConfig: boolean = isWindows && dotConfigPath.startsWith("/");
// does not try resolve if the dotConfig property is empty
dotConfigPath = dotConfigPath !== '' ? dotConfigPath : undefined;
if (dotConfigPath && this.rootUri) {
const checkPathExists: any = util.checkPathExistsSync(dotConfigPath, this.rootUri.fsPath + path.sep, isWindows, isWSLDotConfig, true);
const checkPathExists: any = util.checkPathExistsSync(dotConfigPath, this.rootUri.fsPath + path.sep, isWindows, true);
dotConfigPathExists = checkPathExists.pathExists;
dotConfigPath = checkPathExists.path;
}
@@ -1849,7 +1837,7 @@ export class CppProperties {
}
let pathExists: boolean = true;
if (this.rootUri) {
const checkPathExists: any = util.checkPathExistsSync(resolvedPath, this.rootUri.fsPath + path.sep, isWindows, isWSL, false);
const checkPathExists: any = util.checkPathExistsSync(resolvedPath, this.rootUri.fsPath + path.sep, isWindows, false);
pathExists = checkPathExists.pathExists;
resolvedPath = checkPathExists.path;
}
@@ -104,7 +104,7 @@ export class CppBuildTaskProvider implements TaskProvider {
userCompilerPath = userCompilerPathAndArgs.compilerPath;
if (userCompilerPath && userCompilerPathAndArgs.compilerName) {
userCompilerPath = userCompilerPath.trim();
if (isWindows && userCompilerPath.startsWith("/")) { // TODO: Add WSL compiler support.
if (isWindows && userCompilerPath.startsWith("/")) {
userCompilerPath = undefined;
} else {
userCompilerPath = userCompilerPath.replace(/\\\\/g, "\\");
@@ -134,7 +134,7 @@ export class CppBuildTaskProvider implements TaskProvider {
) &&
(
!isWindows || !info.path.startsWith("/")
); // TODO: Add WSL compiler support.
);
const cl_to_add: configs.KnownCompiler | undefined = userCompilerIsCl ? undefined : knownCompilers.find(info =>
((path.basename(info.path) === "cl.exe") && compiler_condition(info)));
knownCompilers = knownCompilers.filter(info =>
@@ -435,6 +435,7 @@ export function registerCommands(enabled: boolean): void {
commandDisposables.push(vscode.commands.registerCommand('cpptools.setActiveConfigName', enabled ? onSetActiveConfigName : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.RestartIntelliSenseForFile', enabled ? onRestartIntelliSenseForFile : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.GenerateDoxygenComment', enabled ? onGenerateDoxygenComment : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.CreateDeclarationOrDefinition', enabled ? onCreateDeclarationOrDefinition : onDisabledCommand));
}
function onDisabledCommand(): void {
@@ -670,6 +671,10 @@ async function onDisableAllTypeCodeAnalysisProblems(code: string, identifiersAnd
getActiveClient().handleDisableAllTypeCodeAnalysisProblems(code, identifiersAndUris);
}
async function onCreateDeclarationOrDefinition(): Promise<void> {
getActiveClient().handleCreateDeclarationOrDefinition();
}
function onAddToIncludePath(path: string): void {
if (!isFolderOpen()) {
vscode.window.showInformationMessage(localize('add.includepath.open.first', 'Open a folder first to add to {0}', "includePath"));
@@ -42,7 +42,7 @@ export class SettingsTracker {
(!rawSetting || rawSetting.scope === "resource" || rawSetting.scope === "machine-overridable") ? settingsResourceScope : settingsNonScoped;
const result: { [key: string]: string } = {};
for (const key in settingsResourceScope) {
const rawSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
const rawSetting: any = util.getRawSetting("C_Cpp." + key);
const correctlyScopedSettings: vscode.WorkspaceConfiguration = selectCorrectlyScopedSettings(rawSetting);
const val: any = this.getSetting(correctlyScopedSettings, key);
if (val === undefined) {
@@ -57,7 +57,7 @@ export class SettingsTracker {
}
for (const subKey in val) {
const newKey: string = key + "." + subKey;
const newRawSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + newKey];
const newRawSetting: any = util.getRawSetting("C_Cpp." + newKey);
const correctlyScopedSubSettings: vscode.WorkspaceConfiguration = selectCorrectlyScopedSettings(newRawSetting);
const subVal: any = this.getSetting(correctlyScopedSubSettings, newKey);
if (subVal === undefined) {
@@ -96,7 +96,7 @@ export class SettingsTracker {
}
// Only return values that match the setting's type and enum (if applicable).
const curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
const curSetting: any = util.getRawSetting("C_Cpp." + key);
if (curSetting) {
const type: string | undefined = this.typeMatch(val, curSetting["type"]);
if (type) {
+19 -15
View File
@@ -59,15 +59,19 @@ export function setCachedClangTidyPath(path: string | null): void {
// Use this package.json to read values
export const packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools")?.packageJSON;
// Use getRawPackageJson to read and write back to package.json
// This prevents obtaining any of VSCode's expanded variables.
let rawPackageJson: any = null;
export function getRawPackageJson(): any {
if (rawPackageJson === null || rawPackageJson === undefined) {
const fileContents: Buffer = fs.readFileSync(getPackageJsonPath());
rawPackageJson = JSON.parse(fileContents.toString());
// Use getRawSetting to get subcategorized settings from package.json.
// This prevents having to iterate every time we search.
let flattenedPackageJson: Map<string, any>;
export function getRawSetting(key: string): any {
if (flattenedPackageJson === undefined) {
flattenedPackageJson = new Map();
for (const subheading of packageJson.contributes.configuration) {
for (const setting in subheading.properties) {
flattenedPackageJson.set(setting, subheading.properties[setting]);
}
}
}
return rawPackageJson;
return flattenedPackageJson.get(key);
}
export async function getRawJson(path: string | undefined): Promise<any> {
@@ -556,9 +560,9 @@ export function checkDirectoryExistsSync(dirPath: string): boolean {
}
/** Test whether a relative path exists */
export function checkPathExistsSync(path: string, relativePath: string, _isWindows: boolean, isWSL: boolean, isCompilerPath: boolean): { pathExists: boolean; path: string } {
export function checkPathExistsSync(path: string, relativePath: string, _isWindows: boolean, isCompilerPath: boolean): { pathExists: boolean; path: string } {
let pathExists: boolean = true;
const existsWithExeAdded: (path: string) => boolean = (path: string) => isCompilerPath && _isWindows && !isWSL && fs.existsSync(path + ".exe");
const existsWithExeAdded: (path: string) => boolean = (path: string) => isCompilerPath && _isWindows && fs.existsSync(path + ".exe");
if (!fs.existsSync(path)) {
if (existsWithExeAdded(path)) {
path += ".exe";
@@ -1012,12 +1016,12 @@ function extractArgs(argsString: string): string[] {
}
return result;
} else {
const wordexpResult: any = child_process.execFileSync(getExtensionFilePath("bin/cpptools-wordexp"), [argsString]);
if (wordexpResult === undefined) {
return [];
}
const jsonText: string = wordexpResult.toString();
try {
const wordexpResult: any = child_process.execFileSync(getExtensionFilePath("bin/cpptools-wordexp"), [argsString], { shell: false });
if (wordexpResult === undefined) {
return [];
}
const jsonText: string = wordexpResult.toString();
return jsonc.parse(jsonText, undefined, true);
} catch {
return [];
+102 -3
View File
@@ -106,7 +106,6 @@
"intellisense_client_currently_disconnected": "IntelliSense client is currently disconnected",
"request_cancelled": "Request canceled: {0}",
"intellisense_client_not_available_go_to_definition": "IntelliSense client not available, using Tag Parser for go to definition.",
"wsl_compiler_detected": "WSL compiler detected",
"error_squiggle_count": "Error squiggle count: {0}",
"queueing_update_intellisense": "Queueing IntelliSense update for files in translation unit of: {0}",
"formatting_document": "Formatting document: {0}",
@@ -140,7 +139,6 @@
"unable_to_start_child_process": "Unable to start child process!",
"timed_out_attempting_to_communicate_with_process": "Timed out attempting to communicate with process!",
"process_failed_to_run": "Process has failed to run",
"wsl_not_detected": "WSL not detected",
"compiler_in_compilerpath_not_found": "Specified compiler was not found: {0}",
"config_data_invalid": "Config data invalid, {0}",
"cmake_executable_not_found": "CMake executable not found at {0}",
@@ -266,5 +264,106 @@
"file_tag": "File",
"compiler_default_language_standard_version_old" : "Compiler returned default language standard version: {0}. Since this version is old, will try to use newer version {1} as default.",
"unexpected_output_from_clang_tidy": "Unexpected output from clang-tidy: {0}. Expected: {1}.",
"generate_doxygen_comment": "Generate Doxygen Comment"
"generate_doxygen_comment": "Generate Doxygen Comment",
"offer_create_declaration": {
"text": "Create declaration of {0} in {1}",
"hint": "{0} is the name of a C/C++ function, {1} is a file name."
},
"offer_create_definition": {
"text": "Create definition of {0} in {1}",
"hint": "{0} is the name of a C/C++ function, {1} is a file name."
},
"function_definition_not_found": {
"text": "Function definition for '{0}' not found.",
"hint": "{0} is the name of a C/C++ function."
},
"cm_attributes": {
"text": "Attributes",
"hint": "'Attributes' is a C++ specifier."
},
"cm_bases": {
"text": "Bases",
"hint": "'Bases' are a C++ class type."
},
"cm_classes": {
"text": "Classes"
},
"cm_coclasses": {
"text": "CoClasses"
},
"cm_delegates": {
"text": "Delegates"
},
"cm_enums": {
"text": "Enums"
},
"cm_events": {
"text": "Events"
},
"cm_functions": {
"text": "Functions"
},
"cm_importdirectives": {
"text": "Import directives"
},
"cm_importlibstatements": {
"text": "ImportLib statements"
},
"cm_importstatements": {
"text": "Import statements"
},
"cm_includedirectives": {
"text": "Include directives"
},
"cm_interfaces": {
"text": "Interfaces"
},
"cm_libraries": {
"text": "Libraries"
},
"cm_macros": {
"text": "Macros"
},
"cm_maps": {
"text": "Maps"
},
"cm_mapentries": {
"text": "Map entries"
},
"cm_miscellaneous": {
"text": "Miscellaneous"
},
"cm_namespaces": {
"text": "Namespaces"
},
"cm_parameters": {
"text": "Parameters"
},
"cm_properties": {
"text": "Properties"
},
"cm_structs": {
"text": "Structs"
},
"cm_todo_insert_return": {
"text": "TODO: insert return statement here"
},
"cm_typedefs": {
"text": "Typedefs"
},
"cm_unions": {
"text": "Unions"
},
"cm_usingaliases": {
"text": "Using aliases"
},
"cm_usingdirectives": {
"text": "Using directives"
},
"cm_variables": {
"text": "Variables"
},
"cm_addfunction": {
"text": "Automatic add function"
}
}
+14 -14
View File
@@ -1781,9 +1781,9 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
once "^1.4.0"
enhanced-resolve@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66"
integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==
version "4.5.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec"
integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==
dependencies:
graceful-fs "^4.1.2"
memory-fs "^0.5.0"
@@ -1810,9 +1810,9 @@ envinfo@^7.7.3:
integrity sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==
errno@^0.1.3:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
version "0.1.8"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
dependencies:
prr "~1.0.1"
@@ -3660,10 +3660,10 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
loader-utils@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
loader-utils@^2.0.0, loader-utils@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
@@ -4548,7 +4548,7 @@ prompts@^2.1.0:
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==
pseudomap@^1.0.2:
version "1.0.2"
@@ -5599,9 +5599,9 @@ tr46@~0.0.3:
integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
ts-loader@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.1.0.tgz#d6292487df279c7cc79b6d3b70bb9d31682b693e"
integrity sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==
version "8.4.0"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.4.0.tgz#e845ea0f38d140bdc3d7d60293ca18d12ff2720f"
integrity sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw==
dependencies:
chalk "^4.1.0"
enhanced-resolve "^4.0.0"