From f73a5d169ad1d64ed59e41334c1d04b01258df75 Mon Sep 17 00:00:00 2001 From: Michelle Matias <38734287+michelleangela@users.noreply.github.com> Date: Thu, 21 Jan 2021 13:01:56 -0800 Subject: [PATCH 1/4] Use cpptools API v5 (#6823) --- Extension/package.json | 2 +- Extension/src/LanguageServer/client.ts | 34 ++++++++++++------- .../src/LanguageServer/configurations.ts | 12 +++---- .../src/LanguageServer/customProviders.ts | 4 +-- Extension/yarn.lock | 8 ++--- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index 2113acea6c..92b550fb58 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -2450,7 +2450,7 @@ "mkdirp": "^0.5.1", "plist": "^3.0.1", "tmp": "^0.1.0", - "vscode-cpptools": "^4.0.1", + "vscode-cpptools": "^5.0.0", "vscode-extension-telemetry": "^0.1.2", "vscode-languageclient": "^5.2.1", "vscode-nls": "^4.1.1", diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 0162eeaeed..e986d8ff5c 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -1702,7 +1702,7 @@ export class DefaultClient implements Client { return this.callTaskWithTimeout(provideConfigurationAsync, configProviderTimeout, tokenSource).then( (configs?: SourceFileConfigurationItem[] | null) => { if (configs && configs.length > 0) { - this.sendCustomConfigurations(configs); + this.sendCustomConfigurations(configs, provider.version); } onFinished(); }, @@ -2364,19 +2364,24 @@ export class DefaultClient implements Client { this.notifyWhenReady(() => this.languageClient.sendNotification(ChangeCompileCommandsNotification, params)); } - private isSourceFileConfigurationItem(input: any): input is SourceFileConfigurationItem { + private isSourceFileConfigurationItem(input: any, providerVersion: Version): input is SourceFileConfigurationItem { + // IntelliSenseMode and standard are optional for version 5+. However, they are required when compilerPath is not defined. + let areOptionalsValid: boolean = false; + if (providerVersion < Version.v5 || input.configuration.compilerPath === undefined) { + areOptionalsValid = util.isString(input.configuration.intelliSenseMode) && util.isString(input.configuration.standard); + } else if (util.isString(input.configuration.compilerPath)) { + areOptionalsValid = util.isOptionalString(input.configuration.intelliSenseMode) && util.isOptionalString(input.configuration.standard); + } return (input && (util.isString(input.uri) || util.isUri(input.uri)) && input.configuration && + areOptionalsValid && util.isArrayOfString(input.configuration.includePath) && util.isArrayOfString(input.configuration.defines) && - util.isString(input.configuration.intelliSenseMode) && - util.isString(input.configuration.standard) && - util.isOptionalString(input.configuration.compilerPath) && util.isOptionalArrayOfString(input.configuration.compilerArgs) && util.isOptionalArrayOfString(input.configuration.forcedInclude)); } - private sendCustomConfigurations(configs: any): void { + private sendCustomConfigurations(configs: any, providerVersion: Version): void { // configs is marked as 'any' because it is untrusted data coming from a 3rd-party. We need to sanitize it before sending it to the language server. if (!configs || !(configs instanceof Array)) { console.warn("discarding invalid SourceFileConfigurationItems[]: " + configs); @@ -2390,7 +2395,7 @@ export class DefaultClient implements Client { } const sanitized: SourceFileConfigurationItemAdapter[] = []; configs.forEach(item => { - if (this.isSourceFileConfigurationItem(item)) { + if (this.isSourceFileConfigurationItem(item, providerVersion)) { this.configurationLogging.set(item.uri.toString(), JSON.stringify(item.configuration, null, 4)); if (settings.loggingLevel === "Debug") { out.appendLine(` uri: ${item.uri.toString()}`); @@ -2432,6 +2437,15 @@ export class DefaultClient implements Client { private browseConfigurationLogging: string = ""; private configurationLogging: Map = new Map(); + private isWorkspaceBrowseConfiguration(input: any): boolean { + const areOptionalsValid: boolean = (input.compilerPath === undefined && util.isString(input.standard)) || + (util.isString(input.compilerPath) && util.isOptionalString(input.standard)); + return areOptionalsValid && + util.isArrayOfString(input.browsePath) && + util.isOptionalString(input.compilerArgs) && + util.isOptionalString(input.windowsSdkVersion); + } + private sendCustomBrowseConfiguration(config: any, providerId?: string, timeoutOccured?: boolean): void { const rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; if (!rootFolder) { @@ -2461,11 +2475,7 @@ export class DefaultClient implements Client { } sanitized = {...config}; - if (!util.isArrayOfString(sanitized.browsePath) || - !util.isOptionalString(sanitized.compilerPath) || - !util.isOptionalArrayOfString(sanitized.compilerArgs) || - !util.isOptionalString(sanitized.standard) || - !util.isOptionalString(sanitized.windowsSdkVersion)) { + if (!this.isWorkspaceBrowseConfiguration(sanitized)) { console.log("Received an invalid browse configuration from configuration provider."); const configValue: WorkspaceBrowseConfiguration | undefined = lastCustomBrowseConfiguration.Value; if (configValue) { diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index b7fee2d3c9..213f739f57 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -481,18 +481,18 @@ export class CppProperties { private getIntelliSenseModeForPlatform(name?: string): string { // Do the built-in configs first. if (name === "Linux") { - return "gcc-x64"; + return "linux-gcc-x64"; } else if (name === "Mac") { - return "clang-x64"; + return "macos-clang-x64"; } else if (name === "Win32") { - return "msvc-x64"; + return "windows-msvc-x64"; } else if (process.platform === 'win32') { // Custom configs default to the OS's preference. - return "msvc-x64"; + return "windows-msvc-x64"; } else if (process.platform === 'darwin') { - return "clang-x64"; + return "macos-clang-x64"; } else { - return "gcc-x64"; + return "linux-gcc-x64"; } } diff --git a/Extension/src/LanguageServer/customProviders.ts b/Extension/src/LanguageServer/customProviders.ts index d47d50e889..83b51e7b43 100644 --- a/Extension/src/LanguageServer/customProviders.ts +++ b/Extension/src/LanguageServer/customProviders.ts @@ -83,7 +83,7 @@ class CustomProviderWrapper implements CustomConfigurationProvider1 { return this._version < Version.v2 ? Promise.resolve(false) : this.provider.canProvideBrowseConfiguration(token); } - public provideBrowseConfiguration(token?: vscode.CancellationToken): Thenable { + public provideBrowseConfiguration(token?: vscode.CancellationToken): Thenable { console.assert(this._version >= Version.v2); return this._version < Version.v2 ? Promise.resolve({browsePath: []}) : this.provider.provideBrowseConfiguration(token); } @@ -92,7 +92,7 @@ class CustomProviderWrapper implements CustomConfigurationProvider1 { return this._version < Version.v3 ? Promise.resolve(false) : this.provider.canProvideBrowseConfigurationsPerFolder(token); } - public provideFolderBrowseConfiguration(uri: vscode.Uri, token?: vscode.CancellationToken): Thenable { + public provideFolderBrowseConfiguration(uri: vscode.Uri, token?: vscode.CancellationToken): Thenable { console.assert(this._version >= Version.v3); return this._version < Version.v3 ? Promise.resolve({browsePath: []}) : this.provider.provideFolderBrowseConfiguration(uri, token); } diff --git a/Extension/yarn.lock b/Extension/yarn.lock index 46520202e6..68fbcd35ab 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -5631,10 +5631,10 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vscode-cpptools@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/vscode-cpptools/-/vscode-cpptools-4.0.1.tgz#7e591572b437a6aca47b767487b52bc253e6d911" - integrity sha512-2IjtWe7rjIp20J+5m0Yjpa8TjGhdQWChwE49iYJBUUTHFqJDFq0aXNAyiDNw6BDWI1Q2Z/gmeQGsJBoxTb0J0Q== +vscode-cpptools@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vscode-cpptools/-/vscode-cpptools-5.0.0.tgz#f1195736af1cfa10727482be57093a3997c8f63b" + integrity sha512-TPG6/o9+DisDj2U4AiTOihtfjEzBb/4CErYaB1JIWFMZTQE7zlNTdsgCs+l4xIS2Y34us0RMBIC6On1mBuwxww== vscode-debugadapter@^1.35.0: version "1.38.0" From 89cdae04563a1658dac931cb96898b11e85f2064 Mon Sep 17 00:00:00 2001 From: Elaheh Rashedi Date: Thu, 21 Jan 2021 13:48:41 -0800 Subject: [PATCH 2/4] avoid throwing error for single-file mode task configuration (#6828) * change master to main * ignore single-mode files error * linter error --- .../LanguageServer/cppBuildTaskProvider.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index ed9ec1531d..86a18ff10c 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -5,7 +5,7 @@ import * as path from 'path'; import { TaskDefinition, Task, TaskGroup, ShellExecution, Uri, workspace, - TaskProvider, TaskScope, CustomExecution, ProcessExecution, TextEditor, Pseudoterminal, EventEmitter, Event, TerminalDimensions, window + TaskProvider, TaskScope, CustomExecution, ProcessExecution, TextEditor, Pseudoterminal, EventEmitter, Event, TerminalDimensions, window, WorkspaceFolder } from 'vscode'; import * as os from 'os'; import * as util from '../common'; @@ -181,13 +181,18 @@ export class CppBuildTaskProvider implements TaskProvider { }; } - const activeClient: Client = ext.getActiveClient(); - const uri: Uri | undefined = activeClient.RootUri; - if (!uri) { - throw new Error("No client URI found in getBuildTasks()"); - } - if (!workspace.getWorkspaceFolder(uri)) { - throw new Error("No target WorkspaceFolder found in getBuildTasks()"); + const editor: TextEditor | undefined = window.activeTextEditor; + const folder: WorkspaceFolder | undefined = editor ? workspace.getWorkspaceFolder(editor.document.uri) : undefined; + // Check uri exists (single-mode files are ignored). + if (folder) { + const activeClient: Client = ext.getActiveClient(); + const uri: Uri | undefined = activeClient.RootUri; + if (!uri) { + throw new Error("No client URI found in getBuildTasks()"); + } + if (!workspace.getWorkspaceFolder(uri)) { + throw new Error("No target WorkspaceFolder found in getBuildTasks()"); + } } const scope: TaskScope = TaskScope.Workspace; From fdda9c2db5642a49bee7044b69c4bdb40c27a12b Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 26 Jan 2021 16:59:19 -0800 Subject: [PATCH 3/4] Update changelog. (#6852) * Update changelog. --- Extension/CHANGELOG.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 44e84cdb26..7faa3efbea 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,5 +1,14 @@ # C/C++ for Visual Studio Code Change Log +## Version 1.2.0-insiders3: January 26, 2021 +### Bug Fixes +* Fix build tasks errors in single file mode. [#4638](https://github.com/microsoft/vscode-cpptools/issues/4638), [#6764](https://github.com/microsoft/vscode-cpptools/issues/6764) +* Fix IntelliSense not supporting `__float128` (and `Q` literals) on x64 Linux. [#6574](https://github.com/microsoft/vscode-cpptools/issues/6574) +* Fix IntelliSense process infinitely restarting after crashing. [#6724](https://github.com/microsoft/vscode-cpptools/issues/6724) +* Fix not being able to attach to cpptools-srv on Mac (to get crash call stacks). [#6736](https://github.com/microsoft/vscode-cpptools/issues/6736) +* Fix compiler querying with compilers that do not output `__STD_VERSION__` by default (gcc <= 4.8.x). [#6792](https://github.com/microsoft/vscode-cpptools/issues/6792) +* Fix document symbols when nested symbols have the same name as a parent. [#6830](https://github.com/microsoft/vscode-cpptools/issues/6830) +* Fix automatic adding of header files to `files.associations` after `Go to Definition` on a `#include`. [#6845](https://github.com/microsoft/vscode-cpptools/issues/6845) ## Version 1.2.0-insiders2: January 20, 2021 ### Enhancement @@ -17,11 +26,11 @@ ## Version 1.2.0-insiders: January 14, 2021 ### New Features * Add support for cross-compilation configurations for IntelliSense. For example, `intelliSenseMode` value "linux-gcc-x64" could be used on a Mac host machine. [#1083](https://github.com/microsoft/vscode-cpptools/issues/1083) -* Add `C_Cpp.addNodeAddonIncludePaths` setting to add include paths from `nan` and `node-addon-api` when they're dependencies. [#4854](https://github.com/microsoft/vscode-cpptools/issues/4854) - * Bruce MacNaughton (@bmacnaughton) [PR #67331](https://github.com/microsoft/vscode-cpptools/pull/6731) ### Enhancements * Show configuration squiggles when configurations with the same name exist. [#3412](https://github.com/microsoft/vscode-cpptools/issues/3412) +* Add `C_Cpp.addNodeAddonIncludePaths` setting to add include paths from `nan` and `node-addon-api` when they're dependencies. [#4854](https://github.com/microsoft/vscode-cpptools/issues/4854) + * Bruce MacNaughton (@bmacnaughton) [PR #67331](https://github.com/microsoft/vscode-cpptools/pull/6731) * Add command `Generate EditorConfig contents from VC Format settings`. [#6018](https://github.com/microsoft/vscode-cpptools/issues/6018) * Update to clang-format 11.1. [#6326](https://github.com/microsoft/vscode-cpptools/issues/6326) * Add clang-format built for Windows ARM64. [#6494](https://github.com/microsoft/vscode-cpptools/issues/6494) @@ -46,8 +55,9 @@ * Fix `files.exclude` not applying to watched files handlers. [#5141](https://github.com/microsoft/vscode-cpptools/issues/5141) * Fix code folding incorrectly matching an inactive `}`. [#5429](https://github.com/microsoft/vscode-cpptools/issues/5429) * Fix IntelliSense Clang version for Apple Clang. [#5500](https://github.com/microsoft/vscode-cpptools/issues/5500) +* Fix hover doc comments not working if there's a selection. [#5635](https://github.com/microsoft/vscode-cpptools/issues/5635), [#6583](https://github.com/microsoft/vscode-cpptools/issues/6583) * Fix `#include` completion to include results for non-standard header file extensions. [#5698](https://github.com/microsoft/vscode-cpptools/issues/5698) -* Fix clang-format failing due to missing libtinfo5 on Linux ARM/ARM64. [#6774](https://github.com/microsoft/vscode-cpptools/pull/6774) +* Fix clang-format failing due to missing libtinfo5 on Linux ARM/ARM64. [#5958](https://github.com/microsoft/vscode-cpptools/issues/5958) * Automatically configure to use a custom configuration provider if available and no other configuration exists. [#6150](https://github.com/microsoft/vscode-cpptools/issues/6150) * Fix not being able to attach to cpptools on Mac (to get crash call stacks). [#6151](https://github.com/microsoft/vscode-cpptools/issues/6151) * Fix IntelliSense crashing with cl.exe with C++20 and span. [#6251](https://github.com/microsoft/vscode-cpptools/issues/6251) @@ -67,8 +77,8 @@ * Use "method" instead of "member" for semantic tokens. [#6569](https://github.com/microsoft/vscode-cpptools/issues/6569) * Fix `__builtin_coro_*` methods not recognized by IntelliSense in gcc mode with `-fcoroutines`. [#6575](https://github.com/microsoft/vscode-cpptools/issues/6575) * Fix the `else` snippet interfering with entering one line `else` statements. [#6582](https://github.com/microsoft/vscode-cpptools/issues/6582) -* Fix hover doc comments not working if there's a selection. [#6583](https://github.com/microsoft/vscode-cpptools/issues/6583) * Stop showing an "unknown error" message after canceling the creation of a `launch.json`. [#6608](https://github.com/microsoft/vscode-cpptools/issues/6608) +* Fix potential extension activation delay. [#6630](https://github.com/microsoft/vscode-cpptools/issues/6630) * Fix the executed command not appearing with cppbuild tasks. [#6647](https://github.com/microsoft/vscode-cpptools/issues/6647) * Fix `_Debug` not being defined when `/MDd` or `/MTd` are used. [#6690](https://github.com/microsoft/vscode-cpptools/issues/6690) * Fix infinite IntelliSense processing when C++20, gcc mode, and `-fcoroutines` and used. [#6709](https://github.com/microsoft/vscode-cpptools/issues/6709) From fb89c1c2d822f91e40d3004cfaff223e06cee832 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 26 Jan 2021 17:24:06 -0800 Subject: [PATCH 4/4] Add crash count telemetry. (#6851) * Add crash count telemetry. --- Extension/src/LanguageServer/extension.ts | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 943f5e5f9b..ab3fbf28ca 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -1106,10 +1106,10 @@ function reportMacCrashes(): void { fs.readFile(path.resolve(crashFolder, filename), 'utf8', (err, data) => { if (err) { // Try again? - fs.readFile(path.resolve(crashFolder, filename), 'utf8', handleCrashFileRead); + fs.readFile(path.resolve(crashFolder, filename), 'utf8', handleMacCrashFileRead); return; } - handleCrashFileRead(err, data); + handleMacCrashFileRead(err, data); }); }, 5000); }); @@ -1120,15 +1120,22 @@ function reportMacCrashes(): void { } } -function logCrashTelemetry(data: string): void { +let previousMacCrashData: string; +let previousMacCrashCount: number = 0; + +function logMacCrashTelemetry(data: string): void { const crashObject: { [key: string]: string } = {}; + const crashCountObject: { [key: string]: number } = {}; crashObject["CrashingThreadCallStack"] = data; - telemetry.logLanguageServerEvent("MacCrash", crashObject, undefined); + previousMacCrashCount = data === previousMacCrashData ? previousMacCrashCount + 1 : 0; + previousMacCrashData = data; + crashCountObject["CrashCount"] = previousMacCrashCount; + telemetry.logLanguageServerEvent("MacCrash", crashObject, crashCountObject); } -function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data: string): void { +function handleMacCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data: string): void { if (err) { - return logCrashTelemetry("readFile: " + err.code); + return logMacCrashTelemetry("readFile: " + err.code); } // Extract the crashing process version, because the version might not match @@ -1145,7 +1152,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data const crashStart: string = " Crashed:"; let startCrash: number = data.indexOf(crashStart); if (startCrash < 0) { - return logCrashTelemetry("No crash start"); + return logMacCrashTelemetry("No crash start"); } startCrash += crashStart.length + 1; // Skip past crashStart. let endCrash: number = data.indexOf("Thread ", startCrash); @@ -1153,7 +1160,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data endCrash = data.length - 1; // Not expected, but just in case. } if (endCrash <= startCrash) { - return logCrashTelemetry("No crash end"); + return logMacCrashTelemetry("No crash end"); } data = data.substr(startCrash, endCrash - startCrash); @@ -1191,7 +1198,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data data = data.substr(0, 8189) + "..."; } - logCrashTelemetry(data); + logMacCrashTelemetry(data); } export function deactivate(): Thenable {