From 95d4724dc8b6252dcc06c1a3f24e35700b245959 Mon Sep 17 00:00:00 2001 From: Pierson Lee Date: Fri, 13 Jul 2018 15:56:49 -0700 Subject: [PATCH 01/19] Update launch.md with miDebuggerArgs (#2270) --- launch.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launch.md b/launch.md index d49a5a7c0..6e27cafcd 100644 --- a/launch.md +++ b/launch.md @@ -101,6 +101,9 @@ You can change the behavior of GDB or LLDB by setting the following options. * #### `miDebuggerPath` The path to the debugger (such as gdb). When only the executable is specified, it will search the operating system's PATH variable for a debugger (GDB on Linux and Windows, LLDB on OS X). + +* #### `miDebuggerArgs` + Additional arguments to pass to the debugger (such as gdb). * #### `stopAtEntry` If set to true, the debugger should stop at the entry-point of the target (ignored on attach). Default value is `false`. From 458b2be489e48b377fb832c503ce0a94e4dc95da Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Wed, 18 Jul 2018 16:10:00 -0700 Subject: [PATCH 02/19] Update changelog for 0.17.7. (#2288) * Update changelog for 0.17.7. * Fix main snippet. --- Extension/CHANGELOG.md | 11 ++++++++--- Extension/cpp_snippets.json | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index c096df08d..c2d9ccd8e 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,12 +1,12 @@ # C/C++ for Visual Studio Code Change Log -## Version 0.17.7: July 16, 2018 +## Version 0.17.7: July 18, 2018 * Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387) * Fix incorrect IntelliSense errors with template template-arguments. [#1014](https://github.com/Microsoft/vscode-cpptools/issues/1014) * Fix crash when using designated initializer lists. [#1440](https://github.com/Microsoft/vscode-cpptools/issues/1440) * Add `windowsSdkVersion` to `c_cpp_properties.json`. [#1585](https://github.com/Microsoft/vscode-cpptools/issues/1585) * Add `${vcpkgRoot}` variable. [#1817](https://github.com/Microsoft/vscode-cpptools/issues/1817) -* Fix dangling IntelliSense processes and stuck red flame. [#2075](https://github.com/Microsoft/vscode-cpptools/issues/2075), [#2077](https://github.com/Microsoft/vscode-cpptools/issues/2077), [#2169](https://github.com/Microsoft/vscode-cpptools/issues/2169) +* Fix dangling IntelliSense processes. [#2075](https://github.com/Microsoft/vscode-cpptools/issues/2075), [#2169](https://github.com/Microsoft/vscode-cpptools/issues/2169) * Fix incorrect IntelliSense errors when class template argument deduction is used. [#2101](https://github.com/Microsoft/vscode-cpptools/issues/2101) * Skip automatic parsing of source files in Mac system framework paths. [#2156](https://github.com/Microsoft/vscode-cpptools/issues/2156) * Fix `Edit Configurations...` not working after `c_cpp_properties.json` is deleted. [#2214](https://github.com/Microsoft/vscode-cpptools/issues/2214) @@ -17,6 +17,11 @@ * Fix `intelliSenseMode` with custom config providers on Windows. [#2228](https://github.com/Microsoft/vscode-cpptools/issues/2228) * Fix variables not resolving in `macFrameworkPath`. [#2234](https://github.com/Microsoft/vscode-cpptools/issues/2234) * Fix `Go to Definition` not working for macros followed by `.` or `->`. [#2245](https://github.com/Microsoft/vscode-cpptools/issues/2245) +* Fix `#include` autocomplete with Mac framework headers. [#2251](https://github.com/Microsoft/vscode-cpptools/issues/2251) +* Fix for debugging to support empty arguments for debuggee. [#2258](https://github.com/Microsoft/vscode-cpptools/issues/2258) +* Fix `Go to Definition` bug (missing symbols outside the workspace). [#2281](https://github.com/Microsoft/vscode-cpptools/issues/2281) +* Fix for debugging async Visual C++ causing debugger to hang. +* Fix `main` snippet. ## Version 0.17.6: July 2, 2018 * Fix the database icon getting stuck with recursive includes. [#2104](https://github.com/Microsoft/vscode-cpptools/issues/2104) @@ -234,7 +239,7 @@ ## Version 0.13.0: September 25, 2017 * Reference highlighting is now provided by the extension for both IntelliSense engines. * Parameter help is now provided by both IntelliSense engines. -* Light bulbs (code actions) for #include errors now suggest potential paths to add to the `includePath` based on a recursive search of the `browse.path`. [#846](https://github.com/Microsoft/vscode-cpptools/issues/846) +* Light bulbs (code actions) for `#include` errors now suggest potential paths to add to the `includePath` based on a recursive search of the `browse.path`. [#846](https://github.com/Microsoft/vscode-cpptools/issues/846) * Browse database now removes old symbols when `browse.path` changes. [#262](https://github.com/Microsoft/vscode-cpptools/issues/262) * Add `*` on new lines after a multiline comment with `/**` is started. [#579](https://github.com/Microsoft/vscode-cpptools/issues/579) * Fix `Go to Definition`, completion, and parameter hints for partially scoped members. [#635](https://github.com/Microsoft/vscode-cpptools/issues/635) diff --git a/Extension/cpp_snippets.json b/Extension/cpp_snippets.json index b036af953..ccb7dc811 100644 --- a/Extension/cpp_snippets.json +++ b/Extension/cpp_snippets.json @@ -67,7 +67,7 @@ }, "main": { "prefix": "main", - "body": "\nint main(int argc, char const *argv[])\n{\n\t${1:/* code */}\n\treturn 0;\n}\n", + "body": "main(int argc, char const *argv[])\n{\n\t${1:/* code */}\n\treturn 0;\n}\n", "description": "Code snippet for main()", "scope": "source.c, source.objc, source.c++, source.objc++" }, From 528905326f37434b430a6820bb0f0684bc2f0e07 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Thu, 19 Jul 2018 12:03:37 -0700 Subject: [PATCH 03/19] Update changelog. (#2289) --- Extension/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index c2d9ccd8e..d736a6fc4 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,6 +1,6 @@ # C/C++ for Visual Studio Code Change Log -## Version 0.17.7: July 18, 2018 +## Version 0.17.7: July 19, 2018 * Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387) * Fix incorrect IntelliSense errors with template template-arguments. [#1014](https://github.com/Microsoft/vscode-cpptools/issues/1014) * Fix crash when using designated initializer lists. [#1440](https://github.com/Microsoft/vscode-cpptools/issues/1440) @@ -15,6 +15,7 @@ * Add `Change Configuration Provider...` command. [#2224](https://github.com/Microsoft/vscode-cpptools/issues/2224) * Fix out-of-memory crash with `#include` code actions when no folder is open. [#2225](https://github.com/Microsoft/vscode-cpptools/issues/2225) * Fix `intelliSenseMode` with custom config providers on Windows. [#2228](https://github.com/Microsoft/vscode-cpptools/issues/2228) +* Fix formatting not working on Windows if the VC++ 2015 redist isn't installed. [#2232](https://github.com/Microsoft/vscode-cpptools/issues/2232) * Fix variables not resolving in `macFrameworkPath`. [#2234](https://github.com/Microsoft/vscode-cpptools/issues/2234) * Fix `Go to Definition` not working for macros followed by `.` or `->`. [#2245](https://github.com/Microsoft/vscode-cpptools/issues/2245) * Fix `#include` autocomplete with Mac framework headers. [#2251](https://github.com/Microsoft/vscode-cpptools/issues/2251) From a0e0254c73631f86ef153d6cfd3b13f77dcf1da3 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Thu, 19 Jul 2018 12:14:05 -0700 Subject: [PATCH 04/19] Add a setting to silence configuration provider warnings (#2293) * Add a setting to silence configuration provider warnings --- Extension/CHANGELOG.md | 1 + Extension/package.json | 10 ++++++++ Extension/src/LanguageServer/client.ts | 30 +++++++++++++++++------- Extension/src/LanguageServer/settings.ts | 1 + 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index d736a6fc4..478055e6c 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -21,6 +21,7 @@ * Fix `#include` autocomplete with Mac framework headers. [#2251](https://github.com/Microsoft/vscode-cpptools/issues/2251) * Fix for debugging to support empty arguments for debuggee. [#2258](https://github.com/Microsoft/vscode-cpptools/issues/2258) * Fix `Go to Definition` bug (missing symbols outside the workspace). [#2281](https://github.com/Microsoft/vscode-cpptools/issues/2281) +* Add a setting to silence configuration provider warnings. [#2292](https://github.com/Microsoft/vscode-cpptools/issues/2292) * Fix for debugging async Visual C++ causing debugger to hang. * Fix `main` snippet. diff --git a/Extension/package.json b/Extension/package.json index 95873ffc4..78cd2b1b2 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -250,6 +250,16 @@ "description": "Defines the editor behavior for when the Enter key is pressed inside a multiline or single line comment block.", "scope": "resource" }, + "C_Cpp.configurationWarnings": { + "type": "string", + "enum": [ + "Enabled", + "Disabled" + ], + "default": "Enabled", + "description": "Determines whether pop up notifications will be shown when a configuration provider extension is unable to provide a configuration for a source file.", + "scope": "resource" + }, "C_Cpp.default.includePath": { "type": [ "array", diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index d9688785e..c3af87f00 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -30,6 +30,7 @@ import { getTestHook, TestHook } from '../testHook'; import { getCustomConfigProviders, CustomConfigurationProviderCollection, CustomConfigurationProvider1 } from '../LanguageServer/customProviders'; let ui: UI; +const configProviderTimeout: number = 2000; interface NavigationPayload { navigation: string; @@ -430,17 +431,18 @@ class DefaultClient implements Client { let folderStr: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? "the '" + this.Name + "'" : "this"; const message: string = `${provider.name} would like to configure IntelliSense for ${folderStr} folder.`; const allow: string = "Allow"; - const notNow: string = "Not Now"; - const dontAskAgain: string = "Don't Ask Again"; - vscode.window.showInformationMessage(message, allow, notNow, dontAskAgain).then(result => { + const dontAllow: string = "Don't Allow"; + const askLater: string = "Ask Me Later"; + vscode.window.showInformationMessage(message, allow, dontAllow, askLater).then(result => { switch (result) { case allow: { this.configuration.updateCustomConfigurationProvider(provider.extensionId).then(() => { telemetry.logLanguageServerEvent("customConfigurationProvider", { "providerId": provider.extensionId }); }); + ask.Value = false; break; } - case dontAskAgain: { + case dontAllow: { ask.Value = false; break; } @@ -475,7 +477,7 @@ class DefaultClient implements Client { let task: () => Thenable = () => { return currentProvider.provideConfigurations(documentUris, tokenSource.token); }; - this.queueTaskWithTimeout(task, 1000, tokenSource).then(configs => this.sendCustomConfigurations(configs)); + this.queueTaskWithTimeout(task, configProviderTimeout, tokenSource).then(configs => this.sendCustomConfigurations(configs)); }); } @@ -508,17 +510,29 @@ class DefaultClient implements Client { return Promise.reject(""); }; - return this.queueTaskWithTimeout(provideConfigurationAsync, 1000, tokenSource).then( + return this.queueTaskWithTimeout(provideConfigurationAsync, configProviderTimeout, tokenSource).then( (configs: SourceFileConfigurationItem[]) => { if (configs && configs.length > 0) { this.sendCustomConfigurations(configs); } }, () => { - if (!this.isExternalHeader(document) && !vscode.debug.activeDebugSession) { + let settings: CppSettings = new CppSettings(this.RootUri); + if (settings.configurationWarnings === "Enabled" && !this.isExternalHeader(document) && !vscode.debug.activeDebugSession) { + const dismiss: string = "Dismiss"; + const disable: string = "Disable Warnings"; vscode.window.showInformationMessage( `'${providerName}' is unable to provide IntelliSense configuration information for '${document.uri.fsPath}'. ` + - `Settings from the '${configName}' configuration will be used instead.`); + `Settings from the '${configName}' configuration will be used instead.`, + dismiss, + disable).then(response => { + switch (response) { + case disable: { + settings.toggleSetting("configurationWarnings", "Enabled", "Disabled"); + break; + } + } + }); } }); } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 9fca99695..738f8f402 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -48,6 +48,7 @@ export class CppSettings extends Settings { public get workspaceParsingPriority(): boolean { return super.Section.get("workspaceParsingPriority"); } public get exclusionPolicy(): boolean { return super.Section.get("exclusionPolicy"); } public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); } + public get configurationWarnings(): string { return super.Section.get("configurationWarnings"); } public get preferredPathSeparator(): string { return super.Section.get("preferredPathSeparator"); } public get defaultIncludePath(): string[] { return super.Section.get("default.includePath"); } public get defaultDefines(): string[] { return super.Section.get("default.defines"); } From 052f4e7b39ee1398e4a81af11299a975877bc647 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Fri, 20 Jul 2018 10:34:59 -0700 Subject: [PATCH 05/19] update version --- Extension/package-lock.json | 2 +- Extension/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Extension/package-lock.json b/Extension/package-lock.json index 1fcff16b8..56fc2f71f 100644 --- a/Extension/package-lock.json +++ b/Extension/package-lock.json @@ -1,6 +1,6 @@ { "name": "cpptools", - "version": "0.17.6", + "version": "0.17.8-master", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/Extension/package.json b/Extension/package.json index 78cd2b1b2..05c1bed3a 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -2,7 +2,7 @@ "name": "cpptools", "displayName": "C/C++", "description": "C/C++ IntelliSense, debugging, and code browsing.", - "version": "0.17.7-master", + "version": "0.17.8-master", "publisher": "ms-vscode", "preview": true, "icon": "LanguageCCPP_color_128x.png", From 25a29d0bc342117ca4111567b52e4a403c2f3ba4 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Fri, 20 Jul 2018 10:45:55 -0700 Subject: [PATCH 06/19] update fwlinks --- Extension/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Extension/package.json b/Extension/package.json index 05c1bed3a..924330524 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -1376,7 +1376,7 @@ "runtimeDependencies": [ { "description": "C/C++ language components (Linux / x86_64)", - "url": "https://go.microsoft.com/fwlink/?linkid=2004596", + "url": "https://go.microsoft.com/fwlink/?linkid=2006256", "platforms": [ "linux" ], @@ -1390,7 +1390,7 @@ }, { "description": "C/C++ language components (Linux / x86)", - "url": "https://go.microsoft.com/fwlink/?linkid=2004498", + "url": "https://go.microsoft.com/fwlink/?linkid=2006255", "platforms": [ "linux" ], @@ -1406,7 +1406,7 @@ }, { "description": "C/C++ language components (OS X)", - "url": "https://go.microsoft.com/fwlink/?linkid=2004597", + "url": "https://go.microsoft.com/fwlink/?linkid=2006254", "platforms": [ "darwin" ], @@ -1417,7 +1417,7 @@ }, { "description": "C/C++ language components (Windows)", - "url": "https://go.microsoft.com/fwlink/?linkid=2004598", + "url": "https://go.microsoft.com/fwlink/?linkid=2006362", "platforms": [ "win32" ], From 2cbc90d98b52349ad929e587c250803aee414f6f Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Fri, 20 Jul 2018 17:07:14 -0700 Subject: [PATCH 07/19] Fix empty windowsSDKVersion. (#2301) --- Extension/src/LanguageServer/configurations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 3e6f3e598..840e4fb05 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -233,7 +233,7 @@ export class CppProperties { if (!settings.defaultMacFrameworkPath && process.platform === 'darwin') { configuration.macFrameworkPath = this.defaultFrameworks; } - if (!settings.defaultWindowsSdkVersion && process.platform === 'win32') { + if (!settings.defaultWindowsSdkVersion && this.defaultWindowsSdkVersion && process.platform === 'win32') { configuration.windowsSdkVersion = this.defaultWindowsSdkVersion; } if (!settings.defaultCompilerPath && this.defaultCompilerPath) { From 913f740cc2b478de9ec4bf6f30dd5a64c0d58c4d Mon Sep 17 00:00:00 2001 From: John Patterson <17716252+john-patterson@users.noreply.github.com> Date: Mon, 23 Jul 2018 15:52:41 -0700 Subject: [PATCH 08/19] adds settings for inactive region font & bg color (#2308) * adds settings for inactive region font & bg color This adds the inactiveRegionForegroundColor and inactiveRegionBackgroundColor settings. If a preprocessor block is found to be inactive, it will be colored by these fields if they are set. They accept hexadecimal font strings or valid theme colors as their values.These fields also interactive with the dimInactiveRegions setting. This was requested in issue https://github.com/Microsoft/vscode-cpptools/issues/2212. --- Extension/CHANGELOG.md | 5 ++++- Extension/package.json | 18 ++++++++++++++++++ Extension/src/LanguageServer/client.ts | 2 ++ Extension/src/LanguageServer/settings.ts | 2 ++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 478055e6c..9a853477b 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,6 +1,9 @@ # C/C++ for Visual Studio Code Change Log -## Version 0.17.7: July 19, 2018 +## Version 0.17.8: August 16, 2018 +* Add `inactiveRegionForegroundColor` and `inactiveRegionBackgroundColor` to settings. [#2212](https://github.com/Microsoft/vscode-cpptools/issues/2212) + +## Version 0.17.7: July 22, 2018 * Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387) * Fix incorrect IntelliSense errors with template template-arguments. [#1014](https://github.com/Microsoft/vscode-cpptools/issues/1014) * Fix crash when using designated initializer lists. [#1440](https://github.com/Microsoft/vscode-cpptools/issues/1440) diff --git a/Extension/package.json b/Extension/package.json index 924330524..9d8e6f7e7 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -154,6 +154,24 @@ "minimum": 0.1, "maximum": 1 }, + "C_Cpp.inactiveRegionForegroundColor": { + "type": [ + "string", + "null" + ], + "default": null, + "description": "Controls the font coloring of inactive preprocessor blocks. Input is in the form a hexadecimal color code or a valid Theme Color. If not set, this defaults to the syntax coloring scheme of the editor. This setting only applies when inactive region dimming is enabled.", + "scope": "resource" + }, + "C_Cpp.inactiveRegionBackgroundColor": { + "type": [ + "string", + "null" + ], + "default": null, + "description": "Controls the background coloring of inactive preprocessor blocks. Input is in the form a hexadecimal color code or a valid Theme Color. If not set, this defaults to transparent. This setting only applies when inactive region dimming is enabled.", + "scope": "resource" + }, "C_Cpp.formatting": { "type": "string", "enum": [ diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index c3af87f00..01779d7ae 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -840,6 +840,8 @@ class DefaultClient implements Client { let decoration: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType({ opacity: settings.inactiveRegionOpacity.toString(), + backgroundColor: settings.inactiveRegionBackgroundColor, + color: settings.inactiveRegionForegroundColor, rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen }); diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 738f8f402..452eddb7f 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -41,6 +41,8 @@ export class CppSettings extends Settings { public get errorSquiggles(): string { return super.Section.get("errorSquiggles"); } public get dimInactiveRegions(): boolean { return super.Section.get("dimInactiveRegions"); } public get inactiveRegionOpacity(): number { return super.Section.get("inactiveRegionOpacity"); } + public get inactiveRegionForegroundColor(): string { return super.Section.get("inactiveRegionForegroundColor"); } + public get inactiveRegionBackgroundColor(): string { return super.Section.get("inactiveRegionBackgroundColor"); } public get autoComplete(): string { return super.Section.get("autocomplete"); } public get loggingLevel(): string { return super.Section.get("loggingLevel"); } public get navigationLength(): number { return super.Section.get("navigation.length", 60); } From 7947dd80d6b5e726265a990d349493af51483467 Mon Sep 17 00:00:00 2001 From: John Patterson <17716252+john-patterson@users.noreply.github.com> Date: Tue, 24 Jul 2018 14:40:58 -0700 Subject: [PATCH 09/19] Add multi-pass environment variable resolution (#2322) * Dependent variable definition ``` "env": { "envRoot": "apps/tool/builldenv", "arm6.include": "${envRoot}/arm6/include" }, ... "some_config": "${arm6.include} ``` * Additionally, this fixes an open bug that was not reported. If a variable contained "env", "config", or "workspaceFolder" it would not be parsed correctly. If you used a variable ${envRoot} it would match "envR" as the type and "oot" as the variable. This has been resolved. * Also fixes travis-ci to run the unit tests as part of checkin validation --- Extension/.vscode/launch.json | 2 +- Extension/gulpfile.js | 6 +- Extension/src/common.ts | 87 ++++----- Extension/test/unitTests/common.test.ts | 226 ++++++++++++++++++++++++ 4 files changed, 278 insertions(+), 43 deletions(-) create mode 100644 Extension/test/unitTests/common.test.ts diff --git a/Extension/.vscode/launch.json b/Extension/.vscode/launch.json index 838793545..022eaed81 100644 --- a/Extension/.vscode/launch.json +++ b/Extension/.vscode/launch.json @@ -24,7 +24,7 @@ "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" + "--extensionTestsPath=${workspaceFolder}/out/test/unitTests" ], "stopOnEntry": false, "sourceMaps": true, diff --git a/Extension/gulpfile.js b/Extension/gulpfile.js index 03ff32cb7..405960d2c 100644 --- a/Extension/gulpfile.js +++ b/Extension/gulpfile.js @@ -18,7 +18,11 @@ gulp.task('allTests', () => { }); gulp.task('unitTests', () => { - gulp.src('./out/test/unitTests', {read: false}).pipe( + env.set({ + CODE_TESTS_PATH: "./out/test/unitTests", + } + ); + gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}).pipe( mocha({ ui: "tdd" }) diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 4a7c613d5..9b4cd444e 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -178,54 +178,59 @@ export function resolveVariables(input: string, additionalEnvironment: {[key: st } // Replace environment and configuration variables. - let regexp: RegExp = /\$\{((env|config|workspaceFolder)(.|:))?(.*?)\}/g; - let ret: string = input.replace(regexp, (match: string, ignored1: string, varType: string, ignored2: string, name: string) => { - // Historically, if the variable didn't have anything before the "." or ":" - // it was assumed to be an environment variable - if (varType === undefined) { - varType = "env"; - } - let newValue: string = undefined; - switch (varType) { - case "env": { - let v: string | string[] = additionalEnvironment[name]; - if (typeof v === "string") { - newValue = v; - } else if (input === match && v instanceof Array) { - newValue = v.join(";"); - } - if (!newValue) { - newValue = process.env[name]; - } - break; + let regexp: () => RegExp = () => /\$\{((env|config|workspaceFolder)(\.|:))?(.*?)\}/g; + let ret: string = input; + let cycleCache: Set = new Set(); + while (!cycleCache.has(ret)) { + cycleCache.add(ret); + ret = ret.replace(regexp(), (match: string, ignored1: string, varType: string, ignored2: string, name: string) => { + // Historically, if the variable didn't have anything before the "." or ":" + // it was assumed to be an environment variable + if (varType === undefined) { + varType = "env"; } - case "config": { - let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); - if (config) { - newValue = config.get(name); + let newValue: string = undefined; + switch (varType) { + case "env": { + let v: string | string[] = additionalEnvironment[name]; + if (typeof v === "string") { + newValue = v; + } else if (input === match && v instanceof Array) { + newValue = v.join(";"); + } + if (!newValue) { + newValue = process.env[name]; + } + break; } - break; - } - case "workspaceFolder": { - // Only replace ${workspaceFolder:name} variables for now. - // We may consider doing replacement of ${workspaceFolder} here later, but we would have to update the language server and also - // intercept messages with paths in them and add the ${workspaceFolder} variable back in (e.g. for light bulb suggestions) - if (name && vscode.workspace && vscode.workspace.workspaceFolders) { - let folder: vscode.WorkspaceFolder = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase()); - if (folder) { - newValue = folder.uri.fsPath; + case "config": { + let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); + if (config) { + newValue = config.get(name); + } + break; + } + case "workspaceFolder": { + // Only replace ${workspaceFolder:name} variables for now. + // We may consider doing replacement of ${workspaceFolder} here later, but we would have to update the language server and also + // intercept messages with paths in them and add the ${workspaceFolder} variable back in (e.g. for light bulb suggestions) + if (name && vscode.workspace && vscode.workspace.workspaceFolders) { + let folder: vscode.WorkspaceFolder = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase()); + if (folder) { + newValue = folder.uri.fsPath; + } } + break; } - break; + default: { assert.fail("unknown varType matched"); } } - default: { assert.fail("unknown varType matched"); } - } - return (newValue) ? newValue : match; - }); + return (newValue) ? newValue : match; + }); + } // Resolve '~' at the start of the path. - regexp = /^\~/g; - ret = ret.replace(regexp, (match: string, name: string) => { + regexp = () => /^\~/g; + ret = ret.replace(regexp(), (match: string, name: string) => { let newValue: string = process.env.HOME; return (newValue) ? newValue : match; }); diff --git a/Extension/test/unitTests/common.test.ts b/Extension/test/unitTests/common.test.ts new file mode 100644 index 000000000..1b7324716 --- /dev/null +++ b/Extension/test/unitTests/common.test.ts @@ -0,0 +1,226 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import * as assert from "assert"; +import { resolveVariables } from "../../src/common"; + +suite("Common Utility validation", () => { + suite("resolveVariables", () => { + const success: string = "success"; + const home: string = process.env.HOME; + + test("raw input", () => { + const input: string = "test"; + inputAndEnvironment(input, {}) + .shouldResolveTo(input); + }); + + test("raw input with tilde", () => { + inputAndEnvironment("~/test", {}) + .shouldResolveTo(`${home}/test`); + }); + + test("env input with tilde", () => { + inputAndEnvironment("${path}/test", { + path: home + }) + .shouldResolveTo(`${home}/test`); + }); + + test("solo env input resulting in array", () => { + inputAndEnvironment("${test}", { + test: ["foo", "bar"] + }) + .shouldResolveTo("foo;bar"); + }); + + test("mixed raw and env input resulting in array", () => { + const input: string = "baz${test}"; + resolveVariablesWithInput(input) + .withEnvironment({ + test: ["foo", "bar"] + }) + .shouldResolveTo(input); + }); + + test("solo env input not in env config finds process env", () => { + const processKey: string = `cpptoolstests_${Date.now()}`; + const input: string = "foo${" + processKey + "}"; + let actual: string; + try { + process.env[processKey] = "bar"; + actual = resolveVariables(input, {}); + } finally { + delete process.env[processKey]; + } + assert.equal(actual, "foobar"); + }); + + test("env input", () => { + resolveVariablesWithInput("${test}") + .withEnvironment({ + "test": success + }) + .shouldResolveTo(success); + }); + + test("env input mixed with plain text", () => { + resolveVariablesWithInput("${test}bar") + .withEnvironment({ + "test": "foo" + }) + .shouldResolveTo("foobar"); + }); + + test("env input with two variables", () => { + resolveVariablesWithInput("f${a}${b}r") + .withEnvironment({ + a: "oo", + b: "ba" + }) + .shouldResolveTo("foobar"); + }); + + test("env input not in env", () => { + const input: string = "${test}"; + resolveVariablesWithInput(input) + .withEnvironment({}) + .shouldResolveTo(input); + }); + + test("env with macro inside environment definition", () => { + resolveVariablesWithInput("${arm6.include}") + .withEnvironment({ + "envRoot": "apps/tool/buildenv", + "arm6.include": "${envRoot}/arm6/include" + }) + .shouldResolveTo("apps/tool/buildenv/arm6/include"); + }); + + test("env nested with half open variable", () => { + resolveVariablesWithInput("${arm6.include}") + .withEnvironment({ + "envRoot": "apps/tool/buildenv", + "arm6.include": "${envRoot/arm6/include" + }) + .shouldResolveTo("${envRoot/arm6/include"); + }); + + test("env nested with half closed variable", () => { + resolveVariablesWithInput("${arm6.include}") + .withEnvironment({ + "envRoot": "apps/tool/buildenv", + "arm6.include": "envRoot}/arm6/include" + }) + .shouldResolveTo("envRoot}/arm6/include"); + }); + + test("env nested with a cycle", () => { + resolveVariablesWithInput("${a}") + .withEnvironment({ + "a": "${b}", + "b": "${c}", + "c": "${a}" + }) + .shouldResolveTo("${a}"); + }); + + test("env input with 1 level of nested variables anchored at end", () => { + resolveVariablesWithInput("${foo${test}}") + .withEnvironment({ + "foobar": success, + "test": "bar" + }) + .shouldResolveTo("${foo${test}}"); + }); + + test("env input with 1 level of nested variables anchored in the middle", () => { + resolveVariablesWithInput("${f${test}r}") + .withEnvironment({ + "foobar": success, + "test": "ooba" + }) + .shouldResolveTo("${f${test}r}"); + }); + + test("env input with 1 level of nested variable anchored at front", () => { + resolveVariablesWithInput("${${test}bar}") + .withEnvironment({ + "foobar": success, + "test": "foo" + }) + .shouldResolveTo("${${test}bar}"); + }); + + test("env input with 3 levels of nested variables", () => { + resolveVariablesWithInput("${foo${a${b${c}}}}") + .withEnvironment({ + "foobar": success, + "a1": "bar", + "b2": "1", + "c": "2" + }) + .shouldResolveTo("${foo${a${b${c}}}}"); + }); + + test("env input contains env", () => { + resolveVariablesWithInput("${envRoot}") + .shouldLookupSymbol("envRoot"); + }); + + test("env input contains config", () => { + resolveVariablesWithInput("${configRoot}") + .shouldLookupSymbol("configRoot"); + }); + + test("env input contains workspaceFolder", () => { + resolveVariablesWithInput("${workspaceFolderRoot}") + .shouldLookupSymbol("workspaceFolderRoot"); + }); + + test("input contains env.", () => { + resolveVariablesWithInput("${env.Root}") + .shouldLookupSymbol("Root"); + }); + + test("input contains env:", () => { + resolveVariablesWithInput("${env:Root}") + .shouldLookupSymbol("Root"); + }); + + interface ResolveTestFlowEnvironment { + withEnvironment(additionalEnvironment: {[key: string]: string | string[]}): ResolveTestFlowAssert; + shouldLookupSymbol: (key: string) => void; + } + interface ResolveTestFlowAssert { + shouldResolveTo: (x: string) => void; + } + + function resolveVariablesWithInput(input: string): ResolveTestFlowEnvironment { + return { + withEnvironment: (additionalEnvironment: {[key: string]: string | string[]}) => { + return inputAndEnvironment(input, additionalEnvironment); + }, + shouldLookupSymbol: (symbol: string) => { + const environment: {[key: string]: string | string[]} = {}; + environment[symbol] = success; + return inputAndEnvironment(input, environment) + .shouldResolveTo(success); + } + }; + } + + function inputAndEnvironment(input: string, additionalEnvironment: {[key: string]: string | string[]}): ResolveTestFlowAssert { + return { + shouldResolveTo: (expected: string) => { + const actual: string = resolveVariables(input, additionalEnvironment); + const msg: string = `Expected ${expected}. Got ${actual} with input ${input} and environment ${JSON.stringify(additionalEnvironment)}.`; + assert.equal(actual, expected, msg); + } + }; + } + + }); +}); \ No newline at end of file From c8e30c70b1a294005d525fe3b86c85b89fb33710 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Thu, 26 Jul 2018 13:35:34 -0700 Subject: [PATCH 10/19] Allow telemetry to detect failed downloads (#2332) --- Extension/src/packageManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/packageManager.ts b/Extension/src/packageManager.ts index 5f636d61f..f6cda5c73 100644 --- a/Extension/src/packageManager.ts +++ b/Extension/src/packageManager.ts @@ -197,7 +197,7 @@ export class PackageManager { if (retryCount !== 0) { // Log telemetry to see if retrying helps. let telemetryProperties: { [key: string]: string } = {}; - telemetryProperties["success"] = `OnRetry${retryCount}`; + telemetryProperties["success"] = success ? `OnRetry${retryCount}` : 'false'; if (lastError instanceof PackageManagerError) { let packageError: PackageManagerError = lastError; telemetryProperties['error.methodName'] = packageError.methodName; From 2292e7d7620cd566afcccfb7710f802adc6ced1a Mon Sep 17 00:00:00 2001 From: Xeonacid <13995937+Xeonacid@users.noreply.github.com> Date: Sat, 28 Jul 2018 00:23:40 +0800 Subject: [PATCH 11/19] Improve description in Extension/README.md (#2336) `MinGW` is the proper spelling `OS X` is now called `macOS` --- Extension/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/README.md b/Extension/README.md index 445b61684..bdd02a250 100644 --- a/Extension/README.md +++ b/Extension/README.md @@ -11,7 +11,7 @@ This preview release of the extension adds language support for C/C++ to Visual * Quick Info (Hover) * Error Squiggles * Debugging - * Support for debugging Windows (PDB, Mingw/Cygwin), Linux and OS X applications + * Support for debugging Windows (PDB, MinGW/Cygwin), Linux and macOS applications * Line by line code stepping * Breakpoints (including conditional and function breakpoints) * Variable inspection From 84ff661e159661d442a68da09d20794dc952fd3a Mon Sep 17 00:00:00 2001 From: John Patterson <17716252+john-patterson@users.noreply.github.com> Date: Fri, 27 Jul 2018 09:24:11 -0700 Subject: [PATCH 12/19] adds CHANGELOG entry for PR 2322 (#2325) Realized I had left out the CHANGELOG update. For [PR 2322](https://github.com/Microsoft/vscode-cpptools/pull/2322). --- Extension/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 9a853477b..b31c2f48e 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -2,6 +2,7 @@ ## Version 0.17.8: August 16, 2018 * Add `inactiveRegionForegroundColor` and `inactiveRegionBackgroundColor` to settings. [#2212](https://github.com/Microsoft/vscode-cpptools/issues/2212) +* Add multi-pass environment variable resolution allowing variables defined in terms of other variables. [#2322](https://github.com/Microsoft/vscode-cpptools/pull/2322) ## Version 0.17.7: July 22, 2018 * Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387) From 1009b76b229aaf58e30cb9b868fbad0ed96fce73 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Fri, 27 Jul 2018 09:27:14 -0700 Subject: [PATCH 13/19] minor tweaks to config provider experience (#2302) --- Extension/src/LanguageServer/client.ts | 2 +- Extension/src/LanguageServer/configurations.ts | 13 ++++++++++++- Extension/src/LanguageServer/ui.ts | 8 ++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 01779d7ae..658c5fa99 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -1070,7 +1070,7 @@ class DefaultClient implements Client { public handleConfigurationProviderSelectCommand(): void { this.notifyWhenReady(() => { - ui.showConfigurationProviders() + ui.showConfigurationProviders(this.configuration.CurrentConfigurationProvider) .then(extensionId => { if (extensionId === undefined) { // operation was cancelled. diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 840e4fb05..f05b7bd7a 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -343,7 +343,11 @@ export class CppProperties { }); } else { let settings: CppSettings = new CppSettings(this.rootUri); - settings.update("default.configurationProvider", providerId); + if (providerId) { + settings.update("default.configurationProvider", providerId); + } else { + settings.update("default.configurationProvider", undefined); // delete the setting + } this.CurrentConfiguration.configurationProvider = providerId; resolve(); } @@ -513,6 +517,13 @@ export class CppProperties { this.resetToDefaultSettings(true); } this.applyDefaultIncludePathsAndFrameworks(); + let settings: CppSettings = new CppSettings(this.rootUri); + if (settings.defaultConfigurationProvider) { + this.configurationJson.configurations.forEach(config => { + config.configurationProvider = settings.defaultConfigurationProvider; + }); + settings.update("default.configurationProvider", undefined); // delete the setting + } edit.insert(document.uri, new vscode.Position(0, 0), JSON.stringify(this.configurationJson, null, 4)); vscode.workspace.applyEdit(edit).then((status) => { // Fix for issue 163 diff --git a/Extension/src/LanguageServer/ui.ts b/Extension/src/LanguageServer/ui.ts index 72f3ea71b..7447d5471 100644 --- a/Extension/src/LanguageServer/ui.ts +++ b/Extension/src/LanguageServer/ui.ts @@ -164,14 +164,18 @@ export class UI { .then(selection => (selection) ? selection.index : -1); } - public showConfigurationProviders(): Thenable { + public showConfigurationProviders(currentProvider: string|null): Thenable { let options: vscode.QuickPickOptions = {}; options.placeHolder = "Select a Configuration Provider..."; let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); let items: KeyedQuickPickItem[] = []; providers.forEach(provider => { - items.push({ label: provider.name, description: "", key: provider.extensionId }); + let label: string = provider.name; + if (provider.extensionId === currentProvider) { + label += " (active)"; + } + items.push({ label: label, description: "", key: provider.extensionId }); }); items.push({ label: "(none)", description: "Disable the active configuration provider, if applicable.", key: "" }); From 8b704f59727a0023cf38ac12efe6cc3f2c6beaf5 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Fri, 27 Jul 2018 12:50:56 -0700 Subject: [PATCH 14/19] allow users to use ~ for ${userprofile} on Windows (#2333) --- Extension/src/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 9b4cd444e..34c11c3c8 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -231,7 +231,7 @@ export function resolveVariables(input: string, additionalEnvironment: {[key: st // Resolve '~' at the start of the path. regexp = () => /^\~/g; ret = ret.replace(regexp(), (match: string, name: string) => { - let newValue: string = process.env.HOME; + let newValue: string = (process.platform === 'win32') ? process.env.USERPROFILE : process.env.HOME; return (newValue) ? newValue : match; }); From ad46d3887a5de5975c19832290092604b8639cfa Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Mon, 30 Jul 2018 14:28:19 -0700 Subject: [PATCH 15/19] Only allow one configuration popup at a time (#2337) --- Extension/gulpfile.js | 46 +++----- Extension/src/LanguageServer/client.ts | 144 +++++++++++++----------- Extension/src/LanguageServer/ui.ts | 56 +++++++++ Extension/test/unitTests/common.test.ts | 2 +- 4 files changed, 150 insertions(+), 98 deletions(-) diff --git a/Extension/gulpfile.js b/Extension/gulpfile.js index 405960d2c..895d71788 100644 --- a/Extension/gulpfile.js +++ b/Extension/gulpfile.js @@ -12,47 +12,31 @@ const mocha = require('gulp-mocha'); const fs = require('fs'); const optionsSchemaGenerator = require('./out/tools/GenerateOptionsSchema'); -gulp.task('allTests', () => { - gulp.start('unitTests'); - gulp.start('integrationTests'); -}); - gulp.task('unitTests', () => { env.set({ CODE_TESTS_PATH: "./out/test/unitTests", - } - ); - gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}).pipe( - mocha({ - ui: "tdd" - }) - ).once('error', err => { - process.exit(1); - }) - .once('end', () => { - process.exit(); - }) + }); + + gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}) + .pipe(mocha({ ui: "tdd" })) + .once('error', err => process.exit(1)) + .once('end', () => process.exit()) }); gulp.task('integrationTests', () => { env.set({ CODE_TESTS_PATH: "./out/test/integrationTests", CODE_TESTS_WORKSPACE: "./test/integrationTests/testAssets/SimpleCppProject" - } - ); - gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}).pipe( - mocha({ - ui: "tdd", - delay: true - }) - ).once('error', err => { - process.exit(1); - }) - .once('end', () => { - process.exit(); - }) + }); + + gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}) + .pipe(mocha({ ui: "tdd" })) + .once('error', err => process.exit(1)) + .once('end', () => process.exit()) }); +gulp.task('allTests', ['unitTests', 'integrationTests']); + /// Misc Tasks const allTypeScript = [ 'src/**/*.ts', @@ -84,7 +68,7 @@ gulp.task('tslint', () => { gulp.task('pr-check', () => { const packageJson = JSON.parse(fs.readFileSync('./package.json').toString()); - if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') { + if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') { console.log('Please make sure to not check in package.json that has been rewritten by the extension activation. If you intended to have changes in package.json, please only check-in your changes. If you did not, please run `git checkout -- package.json`.'); process.exit(1); } diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 658c5fa99..6562eebbd 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -428,29 +428,34 @@ class DefaultClient implements Client { if (!selectedProvider) { let ask: PersistentFolderState = new PersistentFolderState("Client.registerProvider", true, this.RootPath); if (ask.Value) { - let folderStr: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? "the '" + this.Name + "'" : "this"; - const message: string = `${provider.name} would like to configure IntelliSense for ${folderStr} folder.`; - const allow: string = "Allow"; - const dontAllow: string = "Don't Allow"; - const askLater: string = "Ask Me Later"; - vscode.window.showInformationMessage(message, allow, dontAllow, askLater).then(result => { - switch (result) { - case allow: { - this.configuration.updateCustomConfigurationProvider(provider.extensionId).then(() => { - telemetry.logLanguageServerEvent("customConfigurationProvider", { "providerId": provider.extensionId }); - }); - ask.Value = false; - break; - } - case dontAllow: { - ask.Value = false; - break; - } - default: { - break; + ui.showConfigureCustomProviderMessage(() => { + let folderStr: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? "the '" + this.Name + "'" : "this"; + const message: string = `${provider.name} would like to configure IntelliSense for ${folderStr} folder.`; + const allow: string = "Allow"; + const dontAllow: string = "Don't Allow"; + const askLater: string = "Ask Me Later"; + + return vscode.window.showInformationMessage(message, allow, dontAllow, askLater).then(result => { + switch (result) { + case allow: { + this.configuration.updateCustomConfigurationProvider(provider.extensionId).then(() => { + telemetry.logLanguageServerEvent("customConfigurationProvider", { "providerId": provider.extensionId }); + }); + ask.Value = false; + return true; + } + case dontAllow: { + ask.Value = false; + break; + } + default: { + break; + } } - } - }); + return false; + }); + }, + () => ask.Value = false); } } else if (selectedProvider === provider.extensionId) { telemetry.logLanguageServerEvent("customConfigurationProvider", { "providerId": provider.extensionId }); @@ -806,27 +811,31 @@ class DefaultClient implements Client { } else if (message.endsWith("IntelliSense Fallback")) { let showIntelliSenseFallbackMessage: PersistentState = new PersistentState("CPP.showIntelliSenseFallbackMessage", true); if (showIntelliSenseFallbackMessage.Value) { - let learnMorePanel: string = "Learn More"; - let dontShowAgain: string = "Don't Show Again"; - let fallbackMsg: string = this.configuration.VcpkgInstalled ? - "Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers." : - "Configure your IntelliSense settings to help find missing headers."; - vscode.window.showInformationMessage(fallbackMsg, learnMorePanel, dontShowAgain).then((value) => { - switch (value) { - case learnMorePanel: - let uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`); - vscode.commands.executeCommand('vscode.open', uri); - vscode.commands.getCommands(true).then((commands: string[]) => { - if (commands.indexOf("workbench.action.problems.focus") >= 0) { - vscode.commands.executeCommand("workbench.action.problems.focus"); - } - }); - break; - case dontShowAgain: - showIntelliSenseFallbackMessage.Value = false; - break; - } - }); + ui.showConfigureIncludePathMessage(() => { + let learnMorePanel: string = "Learn More"; + let dontShowAgain: string = "Don't Show Again"; + let fallbackMsg: string = this.configuration.VcpkgInstalled ? + "Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers." : + "Configure your IntelliSense settings to help find missing headers."; + return vscode.window.showInformationMessage(fallbackMsg, learnMorePanel, dontShowAgain).then((value) => { + switch (value) { + case learnMorePanel: + let uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`); + vscode.commands.executeCommand('vscode.open', uri); + vscode.commands.getCommands(true).then((commands: string[]) => { + if (commands.indexOf("workbench.action.problems.focus") >= 0) { + vscode.commands.executeCommand("workbench.action.problems.focus"); + } + }); + break; + case dontShowAgain: + showIntelliSenseFallbackMessage.Value = false; + break; + } + return true; + }); + }, + () => showIntelliSenseFallbackMessage.Value = false); } } } @@ -883,8 +892,8 @@ class DefaultClient implements Client { return; } - let showCompileCommandsSelection: PersistentState = new PersistentState("CPP.showCompileCommandsSelection", true); - if (!showCompileCommandsSelection.Value) { + let ask: PersistentState = new PersistentState("CPP.showCompileCommandsSelection", true); + if (!ask.Value) { return; } @@ -892,30 +901,33 @@ class DefaultClient implements Client { let folderStr: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? "the '" + this.Name + "'" : "this"; const message: string = `Would you like to use ${compileCommandStr} to auto-configure IntelliSense for ${folderStr} folder?`; - const yes: string = "Yes"; - const notNow: string = "Not Now"; - const dontAskAgain: string = "Don't Ask Again"; - vscode.window.showInformationMessage(message, yes, notNow, dontAskAgain).then((value) => { - switch (value) { - case yes: - if (params.paths.length > 1) { - ui.showCompileCommands(params.paths).then((index) => { + ui.showConfigureCompileCommandsMessage(() => { + const yes: string = "Yes"; + const no: string = "No"; + const askLater: string = "Ask Me Later"; + return vscode.window.showInformationMessage(message, yes, no, askLater).then(async (value) => { + switch (value) { + case yes: + if (params.paths.length > 1) { + let index: number = await ui.showCompileCommands(params.paths); if (index < 0) { - return; + return false; } this.configuration.setCompileCommands(params.paths[index]); - }); - } else { - this.configuration.setCompileCommands(params.paths[0]); - } - break; - case notNow: - break; - case dontAskAgain: - showCompileCommandsSelection.Value = false; - break; - } - }); + } else { + this.configuration.setCompileCommands(params.paths[0]); + } + return true; + case askLater: + break; + case no: + ask.Value = false; + break; + } + return false; + }); + }, + () => ask.Value = false); } /********************************************* diff --git a/Extension/src/LanguageServer/ui.ts b/Extension/src/LanguageServer/ui.ts index 7447d5471..2279d2246 100644 --- a/Extension/src/LanguageServer/ui.ts +++ b/Extension/src/LanguageServer/ui.ts @@ -17,11 +17,24 @@ interface KeyedQuickPickItem extends vscode.QuickPickItem { key: string; } +// Higher numbers mean greater priority. +enum ConfigurationPriority { + IncludePath = 1, + CompileCommands = 2, + CustomProvider = 3, +} + +interface ConfigurationResult { + configured: boolean; + priority: ConfigurationPriority; +} + export class UI { private navigationStatusBarItem: vscode.StatusBarItem; private configStatusBarItem: vscode.StatusBarItem; private browseEngineStatusBarItem: vscode.StatusBarItem; private intelliSenseStatusBarItem: vscode.StatusBarItem; + private configurationUIPromise: Thenable; constructor() { // 1000 = priority, it needs to be high enough to be on the left of the Ln/Col. @@ -223,6 +236,49 @@ export class UI { .then(selection => (selection) ? selection.index : -1); } + public showConfigureIncludePathMessage(prompt: () => Thenable, onSkip: () => void): void { + setTimeout(() => { + this.showConfigurationPrompt(ConfigurationPriority.IncludePath, prompt, onSkip); + }, 10000); + } + + public showConfigureCompileCommandsMessage(prompt: () => Thenable, onSkip: () => void): void { + setTimeout(() => { + this.showConfigurationPrompt(ConfigurationPriority.CompileCommands, prompt, onSkip); + }, 5000); + } + + public showConfigureCustomProviderMessage(prompt: () => Thenable, onSkip: () => void): void { + this.showConfigurationPrompt(ConfigurationPriority.CustomProvider, prompt, onSkip); + } + + private showConfigurationPrompt(priority: ConfigurationPriority, prompt: () => Thenable, onSkip: () => void): void { + let showPrompt: () => Thenable = async () => { + let configured: boolean = await prompt(); + return Promise.resolve({ + priority: priority, + configured: configured + }); + }; + + if (this.configurationUIPromise) { + this.configurationUIPromise = this.configurationUIPromise.then(result => { + if (priority > result.priority) { + return showPrompt(); + } else if (!result.configured) { + return showPrompt(); + } + onSkip(); + return Promise.resolve({ + priority: result.priority, + configured: true + }); + }); + } else { + this.configurationUIPromise = showPrompt(); + } + } + public dispose(): void { this.configStatusBarItem.dispose(); this.browseEngineStatusBarItem.dispose(); diff --git a/Extension/test/unitTests/common.test.ts b/Extension/test/unitTests/common.test.ts index 1b7324716..fd6252bf9 100644 --- a/Extension/test/unitTests/common.test.ts +++ b/Extension/test/unitTests/common.test.ts @@ -9,7 +9,7 @@ import { resolveVariables } from "../../src/common"; suite("Common Utility validation", () => { suite("resolveVariables", () => { const success: string = "success"; - const home: string = process.env.HOME; + const home: string = process.env.HOME || process.env.USERPROFILE; test("raw input", () => { const input: string = "test"; From c36eb8e7b173f440e0d7e4a1bba005a3379edaf6 Mon Sep 17 00:00:00 2001 From: Andy Neff Date: Mon, 30 Jul 2018 18:37:55 -0400 Subject: [PATCH 16/19] Using sh instead of bash (#2340) Fixes #569 --- Extension/src/Debugger/attachToProcess.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/Debugger/attachToProcess.ts b/Extension/src/Debugger/attachToProcess.ts index 65b5230b6..3cc8afbce 100644 --- a/Extension/src/Debugger/attachToProcess.ts +++ b/Extension/src/Debugger/attachToProcess.ts @@ -120,7 +120,7 @@ export class RemoteAttachPicker { private getRemoteOSAndProcesses(pipeCmd: string): Promise { // Commands to get OS and processes - const command: string = `bash -c 'uname && if [ $(uname) == "Linux" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) == "Darwin" ] ; ` + + const command: string = `sh -c 'uname && if [ $(uname) == "Linux" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) == "Darwin" ] ; ` + `then ${PsProcessParser.psDarwinCommand}; fi'`; return execChildProcess(`${pipeCmd} "${command}"`, null, this._channel).then(output => { From 2b4b5d397d16b98f8eb16c18006821b76cc60c9b Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Thu, 2 Aug 2018 13:37:47 -0700 Subject: [PATCH 17/19] add a setting to modify the behavior of go to symbol in workspace (#2349) * add a setting to modify the behavior of go to symbol in workspace --- Extension/package.json | 10 ++++++++++ Extension/src/LanguageServer/client.ts | 1 + Extension/src/LanguageServer/settings.ts | 1 + 3 files changed, 12 insertions(+) diff --git a/Extension/package.json b/Extension/package.json index 9d8e6f7e7..d75730e22 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -219,6 +219,16 @@ "description": "Controls whether parsing of the non-active workspace files uses sleeps to avoid using 100% CPU. The values highest/high/medium/low correspond to approximately 100/75/50/25% CPU usage.", "scope": "resource" }, + "C_Cpp.workspaceSymbols": { + "type": "string", + "enum": [ + "All", + "Just My Code" + ], + "default": "Just My Code", + "description": "The symbols to include in the query results when 'Go to Symbol in Workspace' is invoked", + "scope": "resource" + }, "C_Cpp.exclusionPolicy": { "type": "string", "enum": [ diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 6562eebbd..f9d697d47 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -353,6 +353,7 @@ class DefaultClient implements Client { dimInactiveRegions: settings.dimInactiveRegions, loggingLevel: settings.loggingLevel, workspaceParsingPriority: settings.workspaceParsingPriority, + workspaceSymbols: settings.workspaceSymbols, exclusionPolicy: settings.exclusionPolicy, preferredPathSeparator: settings.preferredPathSeparator, default: { diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index 452eddb7f..3d007346d 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -48,6 +48,7 @@ export class CppSettings extends Settings { public get navigationLength(): number { return super.Section.get("navigation.length", 60); } public get autoAddFileAssociations(): boolean { return super.Section.get("autoAddFileAssociations"); } public get workspaceParsingPriority(): boolean { return super.Section.get("workspaceParsingPriority"); } + public get workspaceSymbols(): string { return super.Section.get("workspaceSymbols"); } public get exclusionPolicy(): boolean { return super.Section.get("exclusionPolicy"); } public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); } public get configurationWarnings(): string { return super.Section.get("configurationWarnings"); } From 3a46f10d97411a9f0a82bd2b7f09a36f16cb2f6d Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Thu, 2 Aug 2018 13:53:19 -0700 Subject: [PATCH 18/19] Add gcc-x64 intelliSenseMode. (#2315) * Add gcc-x64 intelliSenseMode. --- Extension/bin/msvc.64.darwin.json | 1 - Extension/bin/msvc.64.intel.clang.json | 1 - Extension/bin/msvc.64.linux.json | 1 - Extension/c_cpp_properties.schema.json | 3 ++- Extension/package.json | 1 + Extension/src/LanguageServer/configurations.ts | 8 ++++++-- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Extension/bin/msvc.64.darwin.json b/Extension/bin/msvc.64.darwin.json index 96872269f..a371f0095 100644 --- a/Extension/bin/msvc.64.darwin.json +++ b/Extension/bin/msvc.64.darwin.json @@ -1,6 +1,5 @@ { "defaults": [ - "--clang", "--pack_alignment", "8" ], diff --git a/Extension/bin/msvc.64.intel.clang.json b/Extension/bin/msvc.64.intel.clang.json index e8b9ba4f9..6072a9ca4 100644 --- a/Extension/bin/msvc.64.intel.clang.json +++ b/Extension/bin/msvc.64.intel.clang.json @@ -1,6 +1,5 @@ { "defaults": [ - "--clang", "--pack_alignment", "8" ], diff --git a/Extension/bin/msvc.64.linux.json b/Extension/bin/msvc.64.linux.json index e8b9ba4f9..6072a9ca4 100644 --- a/Extension/bin/msvc.64.linux.json +++ b/Extension/bin/msvc.64.linux.json @@ -1,6 +1,5 @@ { "defaults": [ - "--clang", "--pack_alignment", "8" ], diff --git a/Extension/c_cpp_properties.schema.json b/Extension/c_cpp_properties.schema.json index 0c399ffab..b3f0c2ee9 100644 --- a/Extension/c_cpp_properties.schema.json +++ b/Extension/c_cpp_properties.schema.json @@ -71,10 +71,11 @@ } }, "intelliSenseMode": { - "description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64 and Linux/Mac default to clang-x64.", + "description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64, Linux defaults to gcc-x64, and Mac default to clang-x64.", "type": "string", "enum": [ "msvc-x64", + "gcc-x64", "clang-x64", "${default}" ] diff --git a/Extension/package.json b/Extension/package.json index d75730e22..751a37156 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -362,6 +362,7 @@ ], "enum": [ "msvc-x64", + "gcc-x64", "clang-x64" ], "default": null, diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index f05b7bd7a..8eedcc358 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -300,15 +300,19 @@ export class CppProperties { private getIntelliSenseModeForPlatform(name: string): string { // Do the built-in configs first. - if (name === "Linux" || name === "Mac") { + if (name === "Linux") { + return "gcc-x64"; + } else if (name === "Mac") { return "clang-x64"; } else if (name === "Win32") { return "msvc-x64"; } else if (process.platform === 'win32') { // Custom configs default to the OS's preference. return "msvc-x64"; - } else { + } else if (process.platform === 'darwin') { return "clang-x64"; + } else { + return "gcc-x64"; } } From 3381cde61c9efbd98f000cc1d43d1aa87b7f9a35 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Fri, 3 Aug 2018 17:36:17 -0700 Subject: [PATCH 19/19] Update changelog for 0.17.8-insiders. (#2353) * Update changelog for 0.17.8-insiders. --- Extension/CHANGELOG.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index b31c2f48e..2413766f5 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,8 +1,23 @@ # C/C++ for Visual Studio Code Change Log ## Version 0.17.8: August 16, 2018 -* Add `inactiveRegionForegroundColor` and `inactiveRegionBackgroundColor` to settings. [#2212](https://github.com/Microsoft/vscode-cpptools/issues/2212) +* Fix attach to process for systems without `bash` by using `sh` instead. [#569](https://github.com/Microsoft/vscode-cpptools/issues/569) + * Andy Neff (@andyneff) [PR 2340](https://github.com/Microsoft/vscode-cpptools/pull/2340) +* Fix IntelliSense crash after hover or completion with `_Complex` types. [#689](https://github.com/Microsoft/vscode-cpptools/issues/689), [#1112](https://github.com/Microsoft/vscode-cpptools/issues/1112) +* Add `C_Cpp.workspaceSymbols` setting with default `Just My Code` to filter out system header symbols. [#1119](https://github.com/Microsoft/vscode-cpptools/issues/1119), [#2320](https://github.com/Microsoft/vscode-cpptools/issues/2320) +* Add `C_Cpp.inactiveRegionForegroundColor` and `C_Cpp.inactiveRegionBackgroundColor` settings. [#1620](https://github.com/Microsoft/vscode-cpptools/issues/1620), [#2212](https://github.com/Microsoft/vscode-cpptools/issues/2212) + * John Patterson (@john-patterson) [PR 2308](https://github.com/Microsoft/vscode-cpptools/pull/2308) +* Fix Mac framework dependencies not being discovered. [#1913](https://github.com/Microsoft/vscode-cpptools/issues/1913) +* Fix red flame getting stuck after modifying `c_cpp_properties.json`. [#2077](https://github.com/Microsoft/vscode-cpptools/issues/2077) +* Add `gcc-x64` `intelliSenseMode` and send the correct clang or gcc version to our parser, fixing various IntelliSense errors. [#2175](https://github.com/Microsoft/vscode-cpptools/issues/2175), [#2299](https://github.com/Microsoft/vscode-cpptools/issues/2299), [#2317](https://github.com/Microsoft/vscode-cpptools/issues/2317) +* Make `Go to Definition` on the definition go to the declaration instead. [#2298](https://github.com/Microsoft/vscode-cpptools/issues/2298) +* Don't add empty `windowsSDKVersion` if none exists. [#2300](https://github.com/Microsoft/vscode-cpptools/issues/2300) * Add multi-pass environment variable resolution allowing variables defined in terms of other variables. [#2322](https://github.com/Microsoft/vscode-cpptools/pull/2322) + * John Patterson (@john-patterson) [PR 2322](https://github.com/Microsoft/vscode-cpptools/pull/2322) +* Fix IntelliSense crash when the gcc-8 type_traits header is used. [#2323](https://github.com/Microsoft/vscode-cpptools/issues/2323), [#2328](https://github.com/Microsoft/vscode-cpptools/issues/2328) +* Limit configuration popups to one at a time. [#2324](https://github.com/Microsoft/vscode-cpptools/issues/2324) +* Allow users to use `~` for `${userProfile}` on Windows. [PR 2333](https://github.com/Microsoft/vscode-cpptools/pull/2333) +* Filter out buggy IntelliSense error `"= delete" can only appear on the first declaration of a function`. [#2352](https://github.com/Microsoft/vscode-cpptools/issues/2352) ## Version 0.17.7: July 22, 2018 * Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387)