Compare commits

...
63 Commits
Author SHA1 Message Date
Sean McManus 717de54b06 Merge pull request #3321 from Microsoft/0_22_0_release
0 22 0 release
2019-03-19 16:52:44 -07:00
Sean McManus 51cd214f1e Merge branch 'release' into 0_22_0_release 2019-03-19 16:40:15 -07:00
Sean McManus 4ca9ad8b3a Update changelog. (#3312)
* Update changelog.
2019-03-19 14:01:54 -07:00
Sean McManus 8aadd40a58 Fix squiggles with WSL compilerPath with args. (#3313)
* Fix squiggles with WSL compilerPath with args.
* Normalize path separators.
2019-03-19 13:44:58 -07:00
Sean McManus 0c61ee96b7 Fix variable resolving not working with ${default}. (#3310) 2019-03-18 15:47:57 -07:00
Bob Brown e020801dac readme feedback #3300 (#3307) 2019-03-18 13:12:18 -07:00
Sean McManus 270a4f7d38 Update changelog for 0.22.0-insiders3. (#3294)
* Update changelog for 0.22.0-insiders3.
2019-03-14 17:27:22 -07:00
Sean McManus 342de46452 Disable the IntelliSense cache on Mac. (#3293)
* Disable the IntelliSense cache on Mac.
2019-03-14 14:22:32 -07:00
Bob Brown cd0dde9e27 Update release notes (#3291) 2019-03-14 13:14:40 -07:00
Bob Brown 79f8262d26 show squiggles when invalid properties are added to the c_cpp_properties.json file (#3283) 2019-03-12 16:58:30 -07:00
Sean McManus 24b69c7873 Seanmcm/add cl debug support (#3264)
* Add cl.exe support.
* Fix Build and Debug too early.
* Make menus better.
2019-03-12 16:55:15 -07:00
Andrew Wang 260124b39b Updating vsdbg (#3267) 2019-03-11 13:02:44 -07:00
Sean McManus 2426a66be4 Seanmcm/change mac mi debugger path default (#3262)
* Change default miDebuggerPath on Mac.
2019-03-07 11:27:30 -08:00
Sean McManus 6f5c9e362b Fix unwanted compilerPath squiggle with cl.exe. (#3263) 2019-03-07 11:22:21 -08:00
Sean McManus 868799af10 Disable AutoPCH for older Macs. (#3261)
* Disable AutoPCH for older Macs.
2019-03-07 11:10:32 -08:00
Sean McManus 01d013723f Fix install vsix. (#3251)
* Fix install vsix.
2019-03-05 16:42:09 -08:00
Sean McManus 1a8e84bca3 Seanmcm/debug fixes (#3244)
* Fix debug launch bugs.
2019-03-05 16:29:43 -08:00
lh123 3db3c8da9a Suggest user switching to insiders channel (#3221)
* suggested user switch to insiders
2019-03-04 17:26:12 -08:00
Sean McManus 670a105c1f Update changelog. (#3243) 2019-03-01 17:26:25 -08:00
Andrew Wang 5445eff250 Update vsdbg for 0.23.0 (#3242) 2019-03-01 17:23:33 -08:00
Sean McManus 95dd5386ed Reduce VS Code requirement. (#3241)
* Reduce VS Code requirement.
* Remove more addresses in crash telemetry.
2019-03-01 16:02:41 -08:00
Sean McManus 55120359a4 Remove trailing "/" from intelliSenseCachePath setting. (#3240) 2019-03-01 14:44:11 -08:00
Sean McManus bb2d23c694 Change AutoPch to AutoPCH. (#3239) 2019-03-01 13:59:19 -08:00
Sean McManus 15ac01d70c Update date. (#3238) 2019-03-01 13:56:03 -08:00
Sean McManus 0c77b9e6cf Fix "cl.exe" in the compilerPath squiggle. (#3237)
* Fix "cl.exe" and missing ".exe" in the compilerPath squiggle.
2019-03-01 13:53:19 -08:00
Sean McManus c39579010b Fix bugs with compilerPath squiggles and build tasks. (#3228) 2019-03-01 11:10:16 -08:00
Bob Brown e928bfb0a9 Fix tslint issues (#3234) 2019-03-01 10:51:11 -08:00
Sean McManus 1d47bc4160 Seanmcm/0 22 0 insiders2 changelog (#3226)
* Update changelog for 0.22.0-insiders.
2019-02-28 17:56:27 -08:00
Griffin Downs 3d7937feeb Grdowns/launch configs (#3215)
* Implement debug configurations that will build the active C/C++ file and launch a debugger (disabled)
* Handle compilerPath in build and squiggles.
2019-02-28 16:46:26 -08:00
Andrew Wang 98260f96ea Remove Travis-CI (#3205)
Removing .travis.yml and will be removing webhooks/app integration of
Travis-CI from vscode-cpptools.

Minor fixes and add debug integration tests back.
2019-02-28 14:55:14 -08:00
Bob Brown 8d96465cb6 Enable ${command:cpptools.activeConfigName} in tasks #1524 (#3219)
* Enable ${command:cpptools.activeConfigName} in tasks #1524

* PR feedback
2019-02-26 20:09:20 -08:00
Bob Brown ece90711fb fix typos (#3218) 2019-02-26 14:54:22 -08:00
Bob Brown 361ca45b50 Merge pull request #3184 from Microsoft/mimatias/add_pch_settings
Add settings for auto pch
2019-02-25 14:51:34 -08:00
Sean McManus 28e8f1f2ed Seanmcm/cpp properties squiggles (#3196)
* Add c_cpp_properties.json warning squiggles for invalid paths.
2019-02-25 14:46:05 -08:00
Michelle Matias d27e609d92 Merge branch 'mimatias/add_pch_settings' of https://github.com/Microsoft/vscode-cpptools into mimatias/add_pch_settings 2019-02-22 13:59:41 -08:00
Michelle Matias fdcbfee87c update cache path 2019-02-22 13:59:26 -08:00
Sean McManus bda5bbf89c Merge branch 'master' into mimatias/add_pch_settings 2019-02-22 13:50:29 -08:00
Sean McManus 50ddd670c7 Fix command not found and empty c_cpp_properties.json if activation is too slow. (#3178)
* Fix command not found if activation is too slow.
* Fix empty c_cpp_properties.json.
2019-02-22 13:50:11 -08:00
Andrew Wang cc81b4bb8f Set up CI with Azure Pipelines (#3191)
Set up CI with Azure Pipelines
2019-02-22 11:51:01 -08:00
Michelle Matias a0f6eb61ad Update cachePath description 2019-02-22 11:05:09 -08:00
Michelle Matias 10a06af93d rename cachePath and cacheSize 2019-02-22 10:39:07 -08:00
Michelle Matias b28ab0a874 add slash at end of default path 2019-02-15 16:20:56 -08:00
Michelle Matias f1ca548849 filter autoPCH cache for telemetry 2019-02-15 16:16:40 -08:00
Michelle Matias f860223723 fix auto pch settings 2019-02-15 16:16:40 -08:00
Michelle Matias e2aaababc4 Add settings for cached pre-compiled headers 2019-02-15 16:16:40 -08:00
Andrew Wang 49aa55261f Fix quoting for process picker (#3181) 2019-02-15 12:58:11 -08:00
Griffin Downs 035d0284d9 Grdowns/build tasks (#3118)
* Generate a C/C++ build task

* Cleaning

* Move args into definition

* Add args to shellexecution to allow calling the task without first configuring; Add TODO's

* Read compiler paths sent in defaults to generate task list

* Rename compilerPaths to compilerInfo; Filter tasks based on file extension

* Use our own file extension filters to decide whether tasks are presented

* Show dialog when no compilers are found

* Display a message if no compilers are found

* Add compilerPath getter to config; Use it to offer another task

* Refactoring; Commenting

* Remove CompilerInfo namespace; Formatting; Change return vals

* Commenting; Add telemetry; Inverse condition

* Change output program based on OS; Remove message and collect telemetry instead

* Filter out redundant compiler entries

* Remove TODO; Get proper exe name; Properly reassign compilerPaths after filtering

* Commenting; Fix cwd mingw bug

* Commenting; Refactor

* Mark compilerInfo const

* Remove whitespace; Remove bad comment

* Remove whitespace

* Replace unique algorithm with a map

* pre-compute basename

* Move comment

* Commenting; Ensure user's compilerPath setting is used

* Use indexOf instead of find

* Simplify isHeader calculation by using some instead of every

* Don't redundantly check extensions; Use some instead of indexOf

* Add comment punctuation

Use file macro instead of fileDirName and fileBaseName

Change path provider name; expose cwd in definition

Add shell task definition (it's not built into vs code apparently)

* Lowercase file extension to match; Count extensionless files as headers

* Add newline

* Change CompilerInfo to KnownCompiler

* Support ambiguous file extension

* Early out for extensionless files

* Commenting

* Commenting; Rename telemetry event

* Change languageAssociation to isC

* Fix bug where cwd was not used; Add comment
2019-02-13 16:00:31 -08:00
Sean McManus f216e0262a Update extend version. (#3146) 2019-02-08 18:47:52 -08:00
Sean McManus da277c8593 Seanmcm/0 21 0 release2 (#3070)
* Update yauzl version and changelog date. (#3069)
2019-01-22 19:17:42 -08:00
Bob Brown b3cce807bb Merge pull request #3068 from Microsoft/seanmcm/0_21_0_release 2019-01-22 14:43:34 -08:00
Sean McManus a533eb9a43 Merge branch 'release' into seanmcm/0_21_0_release 2019-01-22 14:32:57 -08:00
Sean McManus 9702eae953 Update package.json. 2019-01-22 14:32:04 -08:00
Sean McManus a4b51997ff Update version. 2019-01-22 14:30:32 -08:00
Sean McManus b1274d3c76 Merge pull request #2749 from Microsoft/seanmcm/0_20_1_release
Seanmcm/0 20 1 release
2018-10-31 17:24:43 -07:00
Sean McManus 8f8565dbfd Merge branch 'seanmcm/0_20_1_release' of https://github.com/Microsoft/vscode-cpptools into seanmcm/0_20_1_release 2018-10-31 17:16:30 -07:00
Sean McManus 7f4614c31c Merge again. 2018-10-31 17:15:52 -07:00
Sean McManus e231453778 Merge branch 'release' into seanmcm/0_20_1_release 2018-10-31 16:29:33 -07:00
Sean McManus 8729804dc2 Update version. 2018-10-31 16:27:42 -07:00
Sean McManus 0cf237c839 Merge pull request #2725 from Microsoft/master
2nd merge for 0.20.0
2018-10-25 16:46:17 -07:00
Bob Brown ddc1f901c2 Merge pull request #2721 from Microsoft/seanmcm/0_20_0_release
Seanmcm/0 20 0 release
2018-10-25 16:21:08 -07:00
Sean McManus 9ca27af2df Merge. 2018-10-25 15:58:34 -07:00
Sean McManus 082435ec8b Fix comment for intelliSenseEngine setting. 2018-10-25 15:48:28 -07:00
Sean McManus 324c5f59f4 Update changelog for 0.20.0 release. 2018-10-25 15:38:26 -07:00
36 changed files with 1722 additions and 350 deletions
-43
View File
@@ -1,43 +0,0 @@
language: node_js
node_js:
- "8"
before_install:
# Do not modify. Required for GUI based tests: See https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI
- if [ $TRAVIS_OS_NAME == "linux" ]; then
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0;
sh -e /etc/init.d/xvfb start;
sleep 3;
fi
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main'
key_url: 'https://packages.microsoft.com/keys/microsoft.asc'
packages:
- gdb
- g++-4.9
script:
# Download debugAdapters from an existing extension version. See TravisCI settings to set CPPTOOL_VERSION
- mkdir -p ~/.vscode/extensions/ms-vscode.cpptools-$CPPTOOL_VERSION
- wget https://github.com/Microsoft/vscode-cpptools/releases/download/$CPPTOOL_VERSION/cpptools.vsix -O ~/cpptools.vsix
- unzip ~/cpptools.vsix "extension/debugAdapters/*" -d ~/.
- mv ~/extension/debugAdapters ~/.vscode/extensions/ms-vscode.cpptools-$CPPTOOL_VERSION/debugAdapters
# Build and then run tests
- cd Extension
- npm install
- npm run compile
- npm run tslint
# pr-check needs to run before test. test modifies package.json.
- npm run pr-check
- npm run unitTests
# TODO: Merge tests into one group due to Gulp 4.0
- npm run integrationTests
# Dump integrationTest.log output
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
+22 -2
View File
@@ -1,22 +1,42 @@
# C/C++ for Visual Studio Code Change Log
## Version 0.22.0-insiders February 6, 2019
## Version 0.22.0: March 19, 2019
### Major Changes
* Add warning squiggles for invalid properties and paths in `c_cpp_properties.json`. [#2799](https://github.com/Microsoft/vscode-cpptools/issues/2799), [PR #3283](https://github.com/Microsoft/vscode-cpptools/pull/3283)
* Add C/C++ compiler build tasks for compiling the active source file, with support for `F5` debugging and the `Build and Debug Active File` context menu command. [PR #3118](https://github.com/Microsoft/vscode-cpptools/pull/3118), [PR #3244](https://github.com/Microsoft/vscode-cpptools/pull/3244)
* Add AutoPCH support to reduce IntelliSense parsing time, with `C_Cpp.intelliSenseCachePath` and `C_Cpp.intelliSenseCacheSize` settings. It isn't enabled for Mac yet. [PR #3184](https://github.com/Microsoft/vscode-cpptools/pull/3184)
### Minor Changes
* Fix IntelliSense not working on Windows when the username has a space in it and file `C:\Users\<firstname>` exists. [#1377](https://github.com/Microsoft/vscode-cpptools/issues/1377), [#2114](https://github.com/Microsoft/vscode-cpptools/issues/2114), [#2176](https://github.com/Microsoft/vscode-cpptools/issues/2176), [#3052](https://github.com/Microsoft/vscode-cpptools/issues/3052), [#3139](https://github.com/Microsoft/vscode-cpptools/issues/3139)
* Enable `${command:cpptools.activeConfigName}` in tasks. [#1524](https://github.com/Microsoft/vscode-cpptools/issues/1524)
* Fix bugs with squiggles and IntelliSense updating after edits. [#1779](https://github.com/Microsoft/vscode-cpptools/issues/1779), [#3124](https://github.com/Microsoft/vscode-cpptools/issues/3124), [#3260](https://github.com/Microsoft/vscode-cpptools/issues/3260)
* Fix formatting (and other non-IntelliSense operations) being blocked by IntelliSense processing. [#1928](https://github.com/Microsoft/vscode-cpptools/issues/1928)
* Fix completion when the start of an identifier matches a keyword. [#1986](https://github.com/Microsoft/vscode-cpptools/issues/1986)
* Fix auto-removal of compiler-provided paths in `includePath`. [#2177](https://github.com/Microsoft/vscode-cpptools/issues/2177)
* Fix crash on Windows when 8.3 filenames are used. [#2453](https://github.com/Microsoft/vscode-cpptools/issues/2453), [#3104](https://github.com/Microsoft/vscode-cpptools/issues/3104)
* Add support for `Scope::Member` scoped symbol searches. [#2484](https://github.com/Microsoft/vscode-cpptools/issues/2484)
* Fix signature help active parameter selection when parameter names are missing or subsets of each other. [#2952](https://github.com/Microsoft/vscode-cpptools/issues/2952)
* Fix `--enable-pretty-printing` with `gdb` when complex objects are used as keys in maps. [#3024](https://github.com/Microsoft/vscode-cpptools/issues/3024)
* Fix IntelliSense-based `Go to Definition` for `noexcept` methods. [#3060](https://github.com/Microsoft/vscode-cpptools/issues/3060)
* Render macro hover expansions as C/C++. [#3075](https://github.com/Microsoft/vscode-cpptools/issues/3075)
* Enable completion after `struct` when manually invoked. [#3080](https://github.com/Microsoft/vscode-cpptools/issues/3080)
* Add `C_Cpp.suggestSnippets` setting to disable language server snippets. [#3083](https://github.com/Microsoft/vscode-cpptools/issues/3083)
* Show a prompt for changing `C_Cpp.updateChannel` to `Insiders`. [#3089](https://github.com/Microsoft/vscode-cpptools/issues/3089)
* lh123 (@lh123) [PR #3221](https://github.com/Microsoft/vscode-cpptools/pull/3221)
* Fix `compilerPath` not getting priority over the `compile_commands.json` compiler. [#3102](https://github.com/Microsoft/vscode-cpptools/issues/3102)
* Fix Linux `compile_commands.json` compiler querying with relative paths. [#3112](https://github.com/Microsoft/vscode-cpptools/issues/3112)
* Allow `*` in `includePath` to apply to `browse.path` when `browse.path` is not specified. [#3121](https://github.com/Microsoft/vscode-cpptools/issues/3121)
* Tucker Kern (@mill1000) [PR #3122](https://github.com/Microsoft/vscode-cpptools/pull/3122)
* Disable `(` and `<` completion commit characters. [#3127](https://github.com/Microsoft/vscode-cpptools/issues/3127)
* Add Chinese translations for command titles. [PR #3128](https://github.com/Microsoft/vscode-cpptools/pull/3128)
* Fix remote process picker bug. [#2585](https://github.com/Microsoft/vscode-cpptools/issues/2585), [#3150](https://github.com/Microsoft/vscode-cpptools/issues/3150)
* Fix command not found and empty `c_cpp_properties.json` if activation is too slow. [#3160](https://github.com/Microsoft/vscode-cpptools/issues/3160), [#3176](https://github.com/Microsoft/vscode-cpptools/issues/3176)
* Fix `cppvsdbg` debugger showing `"An unspecified error has occurred."` for structured binding variables. [#3197](https://github.com/Microsoft/vscode-cpptools/issues/3197)
* Fix bugs with the Insider reload prompt appearing when it shouldn't. [#3206](https://github.com/Microsoft/vscode-cpptools/issues/3206)
* Fix variable expansion (e.g. `${env.HOME}`) not working when `${default}` is used in `c_cpp_properties.json`. [#3309](https://github.com/Microsoft/vscode-cpptools/issues/3309)
* Fix other unreported IntelliSense engine bugs.
## Version 0.21.0 January 23, 2019
## Version 0.21.0: January 23, 2019
### New Features
* Add documentation comments for hover, completion, and signature help. [#399](https://github.com/Microsoft/vscode-cpptools/issues/399)
* Add completion committing for methods after `(`. [#1184](https://github.com/Microsoft/vscode-cpptools/issues/1184)
+8 -1
View File
@@ -23,5 +23,12 @@ This preview release of the extension adds language support for C/C++ to Visual
You can find more detailed information about C/C++ support for Visual Studio Code at our [GitHub page](https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation) and our [VS Code documentation page](https://code.visualstudio.com/docs/languages/cpp).
## Installation
The extension has OS-specific binary dependencies, so installation via the Marketplace requires an Internet connection so that these additional dependencies can be downloaded. If you are working on a computer that does not have access to the Internet or is behind a strict firewall, you may need to use our OS-specific packages and install them by invoking VS Code's `"Install from VSIX..."` command. These "offline' packages are available at: https://github.com/Microsoft/vscode-cpptools/releases.
* `cpptools-linux.vsix` - for 64-bit Linux
* `cpptools-linux32.vsix` - for 32-bit Linux
* `cpptools-osx.vsix` - for macOS
* `cpptools-win32.vsix` - for 64-bit & 32-bit Windows
## Contact Us
If you run into any issues or have suggestions for us, please file [issues and suggestions on GitHub](https://github.com/Microsoft/vscode-cpptools/issues). If you havent already provided us feedback, please take this [quick survey](https://www.research.net/r/VBVV6C6) to help shape this extension for your needs.
If you run into any issues or have suggestions for us, please file [issues and suggestions on GitHub](https://github.com/Microsoft/vscode-cpptools/issues). If you havent already provided us feedback, please take this [quick survey](https://www.research.net/r/VBVV6C6) and let us know what you think!
+20 -6
View File
@@ -205,8 +205,23 @@
<tr>
<td>
<div>
<h2 class="caption">January 2019 Update</h2>
<div>Thank you for installing the C/C++ extension. In the January update, we added documentation comments for hover, completion, and signature help.<br/>
<h2 class="caption">March 2019 Update</h2>
<div>Thank you for installing the C/C++ extension! We're excited to announce the following features in the March update:<br/>
<h3 style="font-weight: 600">IntelliSense caching</h3>
On Windows and Linux, the extension will now cache header information to improve IntelliSense speed for your code files. Support for macOS will be available in a future release.<br/>
<br/>
<em style="font-weight: 600">Please Note:</em> The extension writes the cache to disk in order to achieve this performance improvement. By default the cache files will be stored in your workspace
folder's ".vscode" folder, but you can change this location by using the <code>"C_Cpp.intelliSenseCachePath"</code> setting. You can also control how much disk space can be
used for the cache with the <code>"C_Cpp.intelliSenseCacheSize"</code> setting. The default is 5120 MB as the caches for individual translation units can be large,
depending on the size and number of included headers.<br/>
<h3 style="font-weight: 600">Build and debug the active source file</h3>
We added a command to help you generate build and debug tasks for single code files. Since this feature writes out tasks.json and launch.json files, it currently requires
that a workspace folder be opened in VS Code first. After that, you can press F5 or select the command from the context menu to configure the tasks or kick off a build and debug
session.<br/>
<h3 style="font-weight: 600">Configuration squiggles</h3>
We added additional validation to the <code>c_cpp_properties.json</code> file to assist in diagnosing potential configuration mistakes. They will show up as problems in the
problems window.<br/>
<br/>
<br/>
Additional features and bug fixes are detailed in the <a href="https://github.com/Microsoft/vscode-cpptools/releases">full release notes</a>.</div>
</div>
@@ -231,10 +246,9 @@
<td>
<div>
<h3 class="caption">Blog Posts</h3>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/12/05/visual-studio-code-cpp-extension-october-2018-update-and-a-simplified-insiders-program/">October 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/08/23/visual-studio-code-c-c-extension-august-2018-update/">August 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/07/25/visual-studio-code-cc-extension-july-2018-update-and-intellisense-auto-configuration-for-cmake/">July 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2016/03/31/cc-extension-for-visual-studio-code/">C/C++ Extension anouncement</a></div>
<div><a href="https://devblogs.microsoft.com/cppblog/vs-code-cpp-extension-january-2019-update/">January 2019 Update</a></div>
<div><a href="https://devblogs.microsoft.com/cppblog/visual-studio-code-cpp-extension-october-2018-update-and-a-simplified-insiders-program/">October 2018 Update</a></div>
<div><a href="https://devblogs.microsoft.com/cppblog/visual-studio-code-c-c-extension-august-2018-update/">August 2018 Update</a></div>
</div>
</td>
</tr>
+6 -3
View File
@@ -112,9 +112,11 @@
"type": "string"
}
}
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
},
"env": {
@@ -156,5 +158,6 @@
"required": [
"configurations",
"version"
]
],
"additionalProperties": false
}
+58
View File
@@ -0,0 +1,58 @@
parameters:
name: ''
pool: ''
jobs:
- job: Windows
pool:
vmImage: 'vs2017-win2016'
steps:
- task: NodeTool@0
displayName: 'Use Node 8.x'
inputs:
versionSpec: 8.x
- script: npm install
displayName: "Install Dependencies"
workingDirectory: '$(Build.SourcesDirectory)\Extension'
- script: npm run compile
displayName: "Compile Sources"
workingDirectory: '$(Build.SourcesDirectory)\Extension'
- script: npm run pr-check
displayName: 'Validate Extension/package.json'
workingDirectory: '$(Build.SourcesDirectory)\Extension'
- script: npm run tslint
displayName: 'Run Linter'
workingDirectory: '$(Build.SourcesDirectory)\Extension'
- script: 'npm run unitTests'
displayName: 'Run unit tests'
workingDirectory: '$(Build.SourcesDirectory)\Extension'
continueOnError: true
- script: 'copy "$(Build.SourcesDirectory)\Extension\out\test\integrationTests\MockDebugger\debugAdapterDescriptorFactory.js" "$(Build.SourcesDirectory)\Extension\out\src\Debugger\debugAdapterDescriptorFactory.js" /Y'
displayName: Replace Debug Adapter Descriptor Factory
- script: 'node node_modules/vscode/bin/test'
displayName: 'Run debug integration tests'
workingDirectory: '$(Build.SourcesDirectory)\Extension'
continueOnError: true
env:
CODE_TESTS_PATH: '$(Build.SourcesDirectory)\Extension\out\test\integrationTests\debug'
CODE_EXTENSIONS_PATH: '$(Build.SourcesDirectory)\Extension'
CODE_TESTS_WORKSPACE: '$(Build.SourcesDirectory)\Extension\test\integrationTests\testAssets\SimpleCppProject'
CODE_DISABLE_EXTENSIONS: 1
- script: 'node node_modules/vscode/bin/test'
displayName: 'Run languageServer integration tests'
workingDirectory: '$(Build.SourcesDirectory)\Extension'
continueOnError: true
env:
CODE_TESTS_PATH: '$(Build.SourcesDirectory)\Extension\out\test\integrationTests\languageServer'
CODE_EXTENSIONS_PATH: '$(Build.SourcesDirectory)\Extension'
CODE_TESTS_WORKSPACE: '$(Build.SourcesDirectory)\Extension\test\integrationTests\testAssets\SimpleCppProject'
CODE_DISABLE_EXTENSIONS: 1
+67
View File
@@ -0,0 +1,67 @@
parameters:
name: ''
pool: ''
jobs:
- job: ${{ parameters.name }}
pool: ${{ parameters.pool }}
steps:
- task: NodeTool@0
displayName: 'Use Node 8.x'
inputs:
versionSpec: 8.x
- script: npm install
displayName: "Install Dependencies"
workingDirectory: '$(Build.SourcesDirectory)/Extension'
- script: npm run compile
displayName: "Compile Sources"
workingDirectory: '$(Build.SourcesDirectory)/Extension'
- script: npm run pr-check
displayName: 'Validate Extension/package.json'
workingDirectory: '$(Build.SourcesDirectory)/Extension'
- script: npm run tslint
displayName: 'Run Linter'
workingDirectory: '$(Build.SourcesDirectory)/Extension'
- script: 'npm run unitTests'
displayName: 'Run unit tests'
workingDirectory: '$(Build.SourcesDirectory)/Extension'
continueOnError: true
- script: |
set -e
/usr/bin/Xvfb :10 -ac >> /tmp/Xvfb.out 2>&1 &
disown -ar
displayName: 'Start xvfb'
- script: |
cp $(Build.SourcesDirectory)/Extension/out/test/integrationTests/MockDebugger/debugAdapterDescriptorFactory.js $(Build.SourcesDirectory)/Extension/out/src/Debugger/debugAdapterDescriptorFactory.js
displayName: Replace Debug Adapter Descriptor Factory
- script: 'node node_modules/vscode/bin/test'
displayName: 'Run debug integration tests'
workingDirectory: '$(Build.SourcesDirectory)/Extension'
continueOnError: true
env:
MOCK_DEBUG: 1
DISPLAY: :10
CODE_TESTS_PATH: '$(Build.SourcesDirectory)/Extension/out/test/integrationTests/debug'
CODE_EXTENSIONS_PATH: '$(Build.SourcesDirectory)/Extension'
CODE_TESTS_WORKSPACE: '$(Build.SourcesDirectory)/Extension/test/integrationTests/testAssets/SimpleCppProject'
CODE_DISABLE_EXTENSIONS: 1
- script: 'node node_modules/vscode/bin/test'
displayName: 'Run languageServer integration tests'
workingDirectory: '$(Build.SourcesDirectory)/Extension'
continueOnError: true
env:
DISPLAY: :10
CODE_TESTS_PATH: '$(Build.SourcesDirectory)/Extension/out/test/integrationTests/languageServer'
CODE_EXTENSIONS_PATH: '$(Build.SourcesDirectory)/Extension'
CODE_TESTS_WORKSPACE: '$(Build.SourcesDirectory)/Extension/test/integrationTests/testAssets/SimpleCppProject'
CODE_DISABLE_EXTENSIONS: 1
+194 -87
View File
@@ -1,6 +1,6 @@
{
"name": "cpptools",
"version": "0.22.0-master",
"version": "0.22.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -10,18 +10,15 @@
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
},
"@types/mocha": {
"version": "2.2.45",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.45.tgz",
"integrity": "sha512-tE1SYtNG3I3atRVPELSGN2FJJJtPg3O/G0tycYSyzeDqdAbdLPRH089LhpWYA5M/iHeWHkVZq/b0OVKngcK0Eg==",
"dev": true,
"requires": {
"@types/node": "*"
}
"version": "5.2.6",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz",
"integrity": "sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==",
"dev": true
},
"@types/node": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.4.tgz",
"integrity": "sha512-iSJdm5S6Vhk+Ep38gwxie/5T7+MSip6bu30LsE5VylRKTMxXrvVJGqdxJLs8hsviLqjlCx9o3uRXDkJ+/K0DsQ==",
"version": "8.10.43",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.43.tgz",
"integrity": "sha512-5m5W13HR2k3cu88mpzlnPBBv5+GyMHtj4F0P83RG4mqoC0AYVYHVMHfF3SgwKNtqEZiZQASMxU92QsLEekKcnw==",
"dev": true
},
"agent-base": {
@@ -33,9 +30,9 @@
}
},
"ajv": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz",
"integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==",
"version": "6.9.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz",
"integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
@@ -117,6 +114,16 @@
"buffer-equal": "^1.0.0"
}
},
"applicationinsights": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.8.tgz",
"integrity": "sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==",
"requires": {
"diagnostic-channel": "0.2.0",
"diagnostic-channel-publishers": "0.2.1",
"zone.js": "0.7.6"
}
},
"archy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
@@ -334,6 +341,12 @@
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
"await-notify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/await-notify/-/await-notify-1.0.1.tgz",
"integrity": "sha1-C0gTOyLlJBgeEVV2ZRhfKi885Hw=",
"dev": true
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -1382,9 +1395,9 @@
}
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"extend-shallow": {
@@ -2407,6 +2420,35 @@
"npm-run-path": "^2.0.2",
"plugin-error": "^0.1.2",
"through2": "^2.0.3"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"mocha": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
"integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"commander": "2.11.0",
"debug": "3.1.0",
"diff": "3.3.1",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.3",
"he": "1.1.1",
"mkdirp": "0.5.1",
"supports-color": "4.4.0"
}
}
}
},
"gulp-remote-src-vscode": {
@@ -2835,9 +2877,9 @@
"dev": true
},
"is": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz",
"integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
"integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==",
"dev": true
},
"is-absolute": {
@@ -3464,18 +3506,18 @@
}
},
"mime-db": {
"version": "1.37.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
"version": "1.38.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
"integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==",
"dev": true
},
"mime-types": {
"version": "2.1.21",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
"version": "2.1.22",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
"integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
"dev": true,
"requires": {
"mime-db": "~1.37.0"
"mime-db": "~1.38.0"
}
},
"minimatch": {
@@ -3519,23 +3561,36 @@
}
},
"mocha": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
"integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
"integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"commander": "2.11.0",
"browser-stdout": "1.3.1",
"commander": "2.15.1",
"debug": "3.1.0",
"diff": "3.3.1",
"diff": "3.5.0",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.3",
"growl": "1.10.5",
"he": "1.1.1",
"minimatch": "3.0.4",
"mkdirp": "0.5.1",
"supports-color": "4.4.0"
"supports-color": "5.4.0"
},
"dependencies": {
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"commander": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"dev": true
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -3544,6 +3599,33 @@
"requires": {
"ms": "2.0.0"
}
},
"diff": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
"growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"supports-color": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -4267,12 +4349,6 @@
"uuid": "^3.3.2"
},
"dependencies": {
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -4338,12 +4414,28 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
"rimraf": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.0.5"
"glob": "^7.1.3"
},
"dependencies": {
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
}
}
},
"safe-buffer": {
@@ -4538,9 +4630,9 @@
}
},
"source-map-support": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz",
"integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
"integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
@@ -4627,9 +4719,9 @@
}
},
"sshpk": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
"integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"dev": true,
"requires": {
"asn1": "~0.2.3",
@@ -5008,9 +5100,9 @@
"dev": true
},
"typescript": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
"dev": true
},
"unc-path-regex": {
@@ -5325,18 +5417,15 @@
}
},
"vrsource-tslint-rules": {
"version": "5.8.2",
"resolved": "https://registry.npmjs.org/vrsource-tslint-rules/-/vrsource-tslint-rules-5.8.2.tgz",
"integrity": "sha512-wr69FB/S6P8GT+rO/OocCr3biFaX4lT/JH1IZGqd7Jy4A3WaPUs0Jn4ELmTEpbFtYMWTawFACMQh1AyT7YewRQ==",
"dev": true,
"requires": {
"tslint": "~5.8.0"
}
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/vrsource-tslint-rules/-/vrsource-tslint-rules-5.8.3.tgz",
"integrity": "sha512-3tYS1zn+d9QtgmQIYmQ9e1i0kipmUjp6cvvYWLC+lZ3z8CQUle7rPKsTFMexOTIVXDpBt9JSJlhDWbwljl3DMQ==",
"dev": true
},
"vscode": {
"version": "1.1.26",
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.26.tgz",
"integrity": "sha512-z1Nf5J38gjUFbuDCbJHPN6OJ//5EG+e/yHlh6ERxj/U9B2Qc3aiHaFr38/fee/GGnxvRw/XegLMOG+UJwKi/Qg==",
"version": "1.1.30",
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.30.tgz",
"integrity": "sha512-YDj5w0TGOcS8XLIdekT4q6LlLV6hv1ZvuT2aGT3KJll4gMz6dUPDgo2VVAf0i0E8igbbZthwvmaUGRwW9yPIaw==",
"dev": true,
"requires": {
"glob": "^7.1.2",
@@ -5353,6 +5442,35 @@
"url-parse": "^1.4.3",
"vinyl-fs": "^3.0.3",
"vinyl-source-stream": "^1.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"mocha": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
"integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"commander": "2.11.0",
"debug": "3.1.0",
"diff": "3.3.1",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.3",
"he": "1.1.1",
"mkdirp": "0.5.1",
"supports-color": "4.4.0"
}
}
}
},
"vscode-cpptools": {
@@ -5361,36 +5479,25 @@
"integrity": "sha512-IDe47rkJVAaSbSknlFnrQWQHM/EIc2r1yGgb5ICuqrGlOpgKkzbrXqDnIEdEYm39ztpNDAiCIwlxjpJK8Y19Iw=="
},
"vscode-debugadapter": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.24.0.tgz",
"integrity": "sha1-KAY7AcyorB5fehPRGOMgem6If/0=",
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.33.0.tgz",
"integrity": "sha512-GsSD6PyVokjyW+7LU3FRXbu8SINv9muQtMQEDvwB6SIGQfrQzld8kECpQRr71j3mgXW+sTY+44/XMzueeaU6/Q==",
"requires": {
"vscode-debugprotocol": "^1.24.0"
"mkdirp": "^0.5.1",
"vscode-debugprotocol": "1.33.0"
}
},
"vscode-debugprotocol": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.24.0.tgz",
"integrity": "sha1-28EOjX2VsQJyehmvPw/O9+JSsI4="
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.33.0.tgz",
"integrity": "sha512-d+l4lrEz6OP2kmGpweqe37x9H7icAMV8S4m8azTWGAIlNJxBP4rlSTnZa7NMLcbgqWkWG9lTGY7fJ+rSPaW7yg=="
},
"vscode-extension-telemetry": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz",
"integrity": "sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==",
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz",
"integrity": "sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==",
"requires": {
"applicationinsights": "1.0.6"
},
"dependencies": {
"applicationinsights": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.6.tgz",
"integrity": "sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==",
"requires": {
"diagnostic-channel": "0.2.0",
"diagnostic-channel-publishers": "0.2.1",
"zone.js": "0.7.6"
}
}
"applicationinsights": "1.0.8"
}
},
"vscode-jsonrpc": {
+58 -28
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "0.22.0-master",
"version": "0.22.0",
"publisher": "ms-vscode",
"preview": true,
"icon": "LanguageCCPP_color_128x.png",
@@ -289,6 +289,19 @@
"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.intelliSenseCachePath": {
"type": "string",
"default": "${workspaceFolder}/.vscode",
"description": "Defines the folder path for cached precompiled headers used by IntelliSense. The default path \"${workspaceFolder}/.vscode\" will be used if a specified path is invalid.",
"scope": "resource"
},
"C_Cpp.intelliSenseCacheSize": {
"type": "number",
"default": 5120,
"description": "Maximum size of the per-workspace hard drive space in megabytes for cached precompiled headers; the actual usage may fluctuate around this value. The default size is 5120 MB. Precompiled header caching is disabled when the size is 0.",
"scope": "resource",
"minimum": 0
},
"C_Cpp.default.includePath": {
"type": [
"array",
@@ -468,10 +481,10 @@
"scope": "resource"
},
"C_Cpp.suggestSnippets": {
"type": "boolean",
"default": true,
"description": "If true, snippets are provided by the language server.",
"scope": "resource"
"type": "boolean",
"default": true,
"description": "If true, snippets are provided by the language server.",
"scope": "resource"
}
}
},
@@ -555,6 +568,11 @@
"command": "C_Cpp.TakeSurvey",
"title": "%c_cpp.command.takeSurvey.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.BuildAndDebugActiveFile",
"title": "%c_cpp.command.buildAndDebugActiveFile.title%",
"category": "C/C++"
}
],
"keybindings": [
@@ -959,12 +977,12 @@
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
@@ -1240,12 +1258,12 @@
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
@@ -1325,42 +1343,52 @@
{
"when": "editorLangId == c",
"command": "C_Cpp.SwitchHeaderSource",
"group": "other@1"
"group": "other1_navigation@1"
},
{
"when": "editorLangId == cpp",
"command": "C_Cpp.SwitchHeaderSource",
"group": "other@1"
"group": "other1_navigation@1"
},
{
"when": "editorLangId == c",
"command": "C_Cpp.Navigate",
"group": "other@2"
"group": "other1_navigation@2"
},
{
"when": "editorLangId == cpp",
"command": "C_Cpp.Navigate",
"group": "other@2"
"group": "other1_navigation@2"
},
{
"when": "editorLangId == c",
"command": "workbench.action.gotoSymbol",
"group": "other@3"
"group": "other1_navigation@3"
},
{
"when": "editorLangId == cpp",
"command": "workbench.action.gotoSymbol",
"group": "other@3"
"group": "other1_navigation@3"
},
{
"when": "editorLangId == c",
"command": "workbench.action.showAllSymbols",
"group": "other@4"
"group": "other1_navigation@4"
},
{
"when": "editorLangId == cpp",
"command": "workbench.action.showAllSymbols",
"group": "other@4"
"group": "other1_navigation@4"
},
{
"when": "editorLangId == cpp",
"command": "C_Cpp.BuildAndDebugActiveFile",
"group": "other2_debug@1"
},
{
"when": "editorLangId == c",
"command": "C_Cpp.BuildAndDebugActiveFile",
"group": "other2_debug@1"
}
]
},
@@ -1387,21 +1415,23 @@
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.46",
"@types/mocha": "^5.2.6",
"@types/node": "^8.10.43",
"async-child-process": "^1.1.1",
"await-notify": "^1.0.1",
"child-process": "^1.0.2",
"extend": "3.0.2",
"gulp": "^4.0.0",
"gulp-env": "0.4.0",
"gulp-mocha": "5.0.0",
"gulp-tslint": "8.1.2",
"mocha": "^4.0.1",
"mocha": "^5.2.0",
"tslint": "5.8.0",
"tslint-microsoft-contrib": "5.0.1",
"tslint-no-unused-expression-chai": "0.0.3",
"typescript": "^2.5.3",
"vrsource-tslint-rules": "^5.8.2",
"vscode": "^1.1.26"
"typescript": "^2.9.2",
"vrsource-tslint-rules": "^5.8.3",
"vscode": "^1.1.30"
},
"dependencies": {
"@types/minimatch": "^3.0.3",
@@ -1412,9 +1442,9 @@
"mkdirp": "~0.5.1",
"tmp": "~0.0.33",
"vscode-cpptools": "2.1.1",
"vscode-debugadapter": "~1.24.0",
"vscode-debugprotocol": "~1.24.0",
"vscode-extension-telemetry": "~0.1.0",
"vscode-debugadapter": "~1.33.0",
"vscode-debugprotocol": "~1.33.0",
"vscode-extension-telemetry": "^0.1.1",
"vscode-languageclient": "5.1.1",
"yauzl": "~2.10.0"
},
@@ -1576,11 +1606,11 @@
},
{
"description": "Visual Studio Windows Debugger",
"url": "https://go.microsoft.com/fwlink/?linkid=872985",
"url": "https://go.microsoft.com/fwlink/?linkid=2082216",
"platforms": [
"win32"
],
"binaries": []
}
]
}
}
+2 -1
View File
@@ -14,5 +14,6 @@
"c_cpp.command.pauseParsing.title": "Metti in pausa l'analisi del codice",
"c_cpp.command.resumeParsing.title": "Riprendi l'analisi del codice",
"c_cpp.command.showParsingCommands.title": "Mostra comandi per l'analisi del codice",
"c_cpp.command.takeSurvey.title": "Partecipa al Sondaggio"
"c_cpp.command.takeSurvey.title": "Partecipa al Sondaggio",
"c_cpp.command.buildAndDebugActiveFile.title": "Compila ed Esegui il debug del file attivo"
}
+4 -3
View File
@@ -2,8 +2,8 @@
"c_cpp.command.configurationSelect.title": "Select a configuration...",
"c_cpp.command.configurationProviderSelect.title": "Change configuration provider...",
"c_cpp.command.configurationEdit.title": "Edit configurations...",
"c_cpp.command.goToDeclaration.title": "Go to declaration",
"c_cpp.command.peekDeclaration.title": "Peek declaration",
"c_cpp.command.goToDeclaration.title": "Go to Declaration",
"c_cpp.command.peekDeclaration.title": "Peek Declaration",
"c_cpp.command.switchHeaderSource.title": "Switch Header/Source",
"c_cpp.command.navigate.title": "Navigate...",
"c_cpp.command.toggleErrorSquiggles.title": "Toggle error squiggles",
@@ -14,5 +14,6 @@
"c_cpp.command.pauseParsing.title": "Pause parsing",
"c_cpp.command.resumeParsing.title": "Resume parsing",
"c_cpp.command.showParsingCommands.title": "Show parsing commands",
"c_cpp.command.takeSurvey.title": "Take survey"
"c_cpp.command.takeSurvey.title": "Take survey",
"c_cpp.command.buildAndDebugActiveFile.title": "Build and Debug Active File"
}
+2 -1
View File
@@ -14,5 +14,6 @@
"c_cpp.command.pauseParsing.title": "暂停解析",
"c_cpp.command.resumeParsing.title": "继续解析",
"c_cpp.command.showParsingCommands.title": "查看解析命令",
"c_cpp.command.takeSurvey.title": "调查问卷"
"c_cpp.command.takeSurvey.title": "调查问卷",
"c_cpp.command.buildAndDebugActiveFile.title": "生成和调试当前文件"
}
+3 -2
View File
@@ -105,9 +105,10 @@ export class RemoteAttachPicker {
private getRemoteOSAndProcesses(pipeCmd: string): Promise<AttachItem[]> {
// Commands to get OS and processes
const command: string = `sh -c 'uname && if [ $(uname) = "Linux" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) = "Darwin" ] ; ` +
`then ${PsProcessParser.psDarwinCommand}; fi'`;
const command: string = `sh -c "uname && if [ $(uname) = \\\"Linux\\\" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) = \\\"Darwin\\\" ] ; ` +
`then ${PsProcessParser.psDarwinCommand}; fi"`;
// Must use single quotes around ${command}. Linux systems evaluate $() within double-quotes.
return execChildProcess(`${pipeCmd} '${command}'`, null, this._channel).then(output => {
// OS will be on first line
// Processess will follow if listed
+150 -3
View File
@@ -7,11 +7,81 @@ import * as debugUtils from './utils';
import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import { getBuildTasks, BuildTaskDefinition } from '../LanguageServer/extension';
import * as util from '../common';
import * as fs from 'fs';
import * as Telemetry from '../telemetry';
import { buildAndDebugActiveFileStr } from './extension';
import { IConfiguration, IConfigurationSnippet, DebuggerType, MIConfigurations, WindowsConfigurations, WSLConfigurations, PipeTransportConfigurations } from './configurations';
import { parse } from 'jsonc-parser';
import { PlatformInformation } from '../platform';
abstract class CppConfigurationProvider implements vscode.DebugConfigurationProvider {
function isDebugLaunchStr(str: string): boolean {
return str === "(gdb) Launch" || str === "(lldb) Launch" || str === "(Windows) Launch";
}
/*
* Retrieves configurations from a provider and displays them in a quickpick menu to be selected.
* Ensures that the selected configuration's preLaunchTask (if existent) is populated in the user's task.json.
* Automatically starts debugging for "Build and Debug" configurations.
*/
export class QuickPickConfigurationProvider implements vscode.DebugConfigurationProvider {
private underlyingProvider: vscode.DebugConfigurationProvider;
public constructor(provider: CppConfigurationProvider) {
this.underlyingProvider = provider;
}
async provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
const configs: vscode.DebugConfiguration[] = await this.underlyingProvider.provideDebugConfigurations(folder, token);
const defaultConfig: vscode.DebugConfiguration = configs.find(config => { return isDebugLaunchStr(config.name); });
console.assert(defaultConfig);
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
if (!editor || !util.fileIsCOrCppSource(editor.document.fileName) || configs.length <= 1) {
return [defaultConfig];
}
interface MenuItem extends vscode.QuickPickItem {
configuration: vscode.DebugConfiguration;
}
const items: MenuItem[] = configs.map<MenuItem>(config => {
let menuItem: MenuItem = {label: config.name, configuration: config};
// Rename the menu item for the default configuration as its name is non-descriptive.
if (isDebugLaunchStr(menuItem.label)) {
menuItem.label = "Default Configuration";
}
return menuItem;
});
const selection: MenuItem = await vscode.window.showQuickPick(items, {placeHolder: "Select a configuration"});
if (!selection) {
throw new Error(); // User canceled it.
}
if (selection.label.startsWith("cl.exe")) {
if (!process.env.DevEnvDir || process.env.DevEnvDir.length === 0) {
vscode.window.showErrorMessage('cl.exe build and debug is only usable when VS Code is run from the Developer Command Prompt for VS.');
throw new Error();
}
}
if (selection.label.indexOf(buildAndDebugActiveFileStr()) !== -1 && selection.configuration.preLaunchTask) {
try {
await util.ensureBuildTaskExists(selection.configuration.preLaunchTask);
await vscode.debug.startDebugging(folder, selection.configuration);
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "true" });
} catch (e) {
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
}
}
return [selection.configuration];
}
resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
return this.underlyingProvider.resolveDebugConfiguration(folder, config, token);
}
}
class CppConfigurationProvider implements vscode.DebugConfigurationProvider {
private type: DebuggerType;
private provider: IConfigurationAssetProvider;
@@ -23,8 +93,85 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
/**
* Returns a list of initial debug configurations based on contextual information, e.g. package.json or folder.
*/
provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration[]> {
return this.provider.getInitialConfigurations(this.type);
async provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
let buildTasks: vscode.Task[] = await getBuildTasks();
if (buildTasks.length === 0) {
return Promise.resolve(this.provider.getInitialConfigurations(this.type));
}
const defaultConfig: vscode.DebugConfiguration = this.provider.getInitialConfigurations(this.type).find(config => {
return isDebugLaunchStr(config.name);
});
console.assert(defaultConfig, "Could not find default debug configuration.");
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
const platform: string = platformInfo.platform;
// Filter out build tasks that don't match the currently selectede debug configuration type.
buildTasks = buildTasks.filter((task: vscode.Task) => {
if (defaultConfig.name === "(Windows) Launch") {
if (task.name.startsWith("cl.exe")) {
return true;
}
} else {
if (!task.name.startsWith("cl.exe")) {
return true;
}
}
return false;
});
// Generate new configurations for each build task.
// Generating a task is async, therefore we must *await* *all* map(task => config) Promises to resolve.
let configs: vscode.DebugConfiguration[] = await Promise.all(buildTasks.map<Promise<vscode.DebugConfiguration>>(async task => {
const definition: BuildTaskDefinition = task.definition as BuildTaskDefinition;
const compilerName: string = path.basename(definition.compilerPath);
let newConfig: vscode.DebugConfiguration = Object.assign({}, defaultConfig); // Copy enumerables and properties
newConfig.name = compilerName + buildAndDebugActiveFileStr();
newConfig.preLaunchTask = task.name;
newConfig.externalConsole = false;
const exeName: string = path.join("${fileDirname}", "${fileBasenameNoExtension}");
newConfig.program = platform === "win32" ? exeName + ".exe" : exeName;
return new Promise<vscode.DebugConfiguration>(resolve => {
if (platform === "darwin") {
return resolve(newConfig);
} else {
let debuggerName: string;
if (compilerName.startsWith("clang")) {
newConfig.MIMode = "lldb";
const suffixIndex: number = compilerName.indexOf("-");
const suffix: string = suffixIndex === -1 ? "" : compilerName.substr(suffixIndex);
debuggerName = "lldb-mi" + suffix;
} else if (compilerName === "cl.exe") {
newConfig.miDebuggerPath = undefined;
newConfig.type = "cppvsdbg";
return resolve(newConfig);
} else {
debuggerName = "gdb";
}
if (platform === "win32") {
debuggerName += ".exe";
}
const compilerDirname: string = path.dirname(definition.compilerPath);
const debuggerPath: string = path.join(compilerDirname, debuggerName);
fs.stat(debuggerPath, (err, stats: fs.Stats) => {
if (!err && stats && stats.isFile) {
newConfig.miDebuggerPath = debuggerPath;
} else {
// TODO should probably resolve a missing debugger in a more graceful fashion for win32.
newConfig.miDebuggerPath = path.join("/usr", "bin", debuggerName);
}
return resolve(newConfig);
});
}
});
}));
configs.push(defaultConfig);
return configs;
}
/**
@@ -9,22 +9,37 @@ import * as path from 'path';
import * as os from 'os';
// Registers DebugAdapterDescriptorFactory for `cppdbg` and `cppvsdbg`. If it is not ready, it will prompt a wait for the download dialog.
// Note: util.extensionContext.extensionPath is needed for the commands because VsCode does not support relative paths for adapterExecutableComand
// NOTE: This file is not automatically tested.
export class CppdbgDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
abstract class AbstractDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
protected readonly context: vscode.ExtensionContext;
// This is important for the Mock Debugger since it can not use src/common
constructor(context: vscode.ExtensionContext) {
this.context = context;
}
abstract createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor>;
}
export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
public static DEBUG_TYPE : string = "cppdbg";
constructor(context: vscode.ExtensionContext) {
super(context);
}
createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
return util.isExtensionReady().then(ready => {
if (ready) {
let command: string = path.join(util.extensionContext.extensionPath, './debugAdapters/OpenDebugAD7');
let command: string = path.join(this.context.extensionPath, './debugAdapters/OpenDebugAD7');
// Windows has the exe in debugAdapters/bin.
if (os.platform() === 'win32') {
command = path.join(util.extensionContext.extensionPath, "./debugAdapters/bin/OpenDebugAD7.exe");
command = path.join(this.context.extensionPath, "./debugAdapters/bin/OpenDebugAD7.exe");
}
return new vscode.DebugAdapterExecutable(command);
return new vscode.DebugAdapterExecutable(command, []);
} else {
throw new Error(util.extensionNotReadyString);
}
@@ -32,9 +47,13 @@ export class CppdbgDebugAdapterDescriptorFactory implements vscode.DebugAdapterD
}
}
export class CppvsdbgDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
export class CppvsdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
public static DEBUG_TYPE : string = "cppvsdbg";
constructor(context: vscode.ExtensionContext) {
super(context);
}
createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
if (os.platform() !== 'win32') {
vscode.window.showErrorMessage("Debugger type 'cppvsdbg' is not avaliable for non-Windows machines.");
@@ -43,7 +62,7 @@ export class CppvsdbgDebugAdapterDescriptorFactory implements vscode.DebugAdapte
return util.isExtensionReady().then(ready => {
if (ready) {
return new vscode.DebugAdapterExecutable(
path.join(util.extensionContext.extensionPath, './debugAdapters/vsdbg/bin/vsdbg.exe'),
path.join(this.context.extensionPath, './debugAdapters/vsdbg/bin/vsdbg.exe'),
['--interpreter=vscode']
);
} else {
+93 -6
View File
@@ -7,13 +7,19 @@ import * as vscode from 'vscode';
import * as os from 'os';
import { AttachPicker, RemoteAttachPicker, AttachItemsProvider } from './attachToProcess';
import { NativeAttachItemsProviderFactory } from './nativeAttach';
import { ConfigurationAssetProviderFactory, CppVsDbgConfigurationProvider, CppDbgConfigurationProvider, ConfigurationSnippetProvider, IConfigurationAssetProvider } from './configurationProvider';
import { QuickPickConfigurationProvider, ConfigurationAssetProviderFactory, CppVsDbgConfigurationProvider, CppDbgConfigurationProvider, ConfigurationSnippetProvider, IConfigurationAssetProvider } from './configurationProvider';
import { CppdbgDebugAdapterDescriptorFactory, CppvsdbgDebugAdapterDescriptorFactory } from './debugAdapterDescriptorFactory';
import * as util from '../common';
import * as Telemetry from '../telemetry';
// The extension deactivate method is asynchronous, so we handle the disposables ourselves instead of using extensonContext.subscriptions.
let disposables: vscode.Disposable[] = [];
export function initialize(): void {
export function buildAndDebugActiveFileStr(): string {
return " build and debug active file";
}
export function initialize(context: vscode.ExtensionContext): void {
// Activate Process Picker Commands
let attachItemsProvider: AttachItemsProvider = NativeAttachItemsProviderFactory.Get();
let attacher: AttachPicker = new AttachPicker(attachItemsProvider);
@@ -25,10 +31,91 @@ export function initialize(): void {
let configurationProvider: IConfigurationAssetProvider = ConfigurationAssetProviderFactory.getConfigurationProvider();
// On non-windows platforms, the cppvsdbg debugger will not be registered for initial configurations.
// This will cause it to not show up on the dropdown list.
let vsdbgProvider: CppVsDbgConfigurationProvider = null;
if (os.platform() === 'win32') {
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppvsdbg', new CppVsDbgConfigurationProvider(configurationProvider)));
vsdbgProvider = new CppVsDbgConfigurationProvider(configurationProvider);
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppvsdbg', new QuickPickConfigurationProvider(vsdbgProvider)));
}
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', new CppDbgConfigurationProvider(configurationProvider)));
const provider: CppDbgConfigurationProvider = new CppDbgConfigurationProvider(configurationProvider);
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', new QuickPickConfigurationProvider(provider)));
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndDebugActiveFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => {
const folder: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(textEditor.document.uri);
if (!folder) {
// Not enabled because we do not react to single-file mode correctly yet.
// We get an ENOENT when the user's c_cpp_properties.json is attempted to be parsed.
// The DefaultClient will also have its configuration accessed, but since it doesn't exist it errors out.
vscode.window.showErrorMessage('This command is not yet available for single-file mode.');
return Promise.resolve();
}
if (!util.fileIsCOrCppSource(textEditor.document.uri.fsPath)) {
vscode.window.showErrorMessage('Cannot build and debug because the active file is not a C or C++ source file.');
return Promise.resolve();
}
let configs: vscode.DebugConfiguration[] = (await provider.provideDebugConfigurations(folder)).filter(config => {
return config.name.indexOf(buildAndDebugActiveFileStr()) !== -1;
});
if (vsdbgProvider) {
let vsdbgConfigs: vscode.DebugConfiguration[] = (await vsdbgProvider.provideDebugConfigurations(folder)).filter(config => {
return config.name.indexOf(buildAndDebugActiveFileStr()) !== -1;
});
if (vsdbgConfigs) {
configs.push(...vsdbgConfigs);
}
}
interface MenuItem extends vscode.QuickPickItem {
configuration: vscode.DebugConfiguration;
}
const items: MenuItem[] = configs.map<MenuItem>(config => {
return {label: config.name, configuration: config};
});
vscode.window.showQuickPick(items, {placeHolder: (items.length === 0 ? "No compiler found" : "Select a compiler" )}).then(async selection => {
if (!selection) {
return; // User canceled it.
}
if (selection.label.startsWith("cl.exe")) {
if (!process.env.DevEnvDir || process.env.DevEnvDir.length === 0) {
vscode.window.showErrorMessage('cl.exe build and debug is only usable when VS Code is run from the Developer Command Prompt for VS.');
return;
}
}
if (selection.configuration.preLaunchTask) {
if (folder) {
try {
await util.ensureBuildTaskExists(selection.configuration.preLaunchTask);
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
} catch (e) {
return Promise.resolve();
}
} else {
return Promise.resolve();
// TODO uncomment this when single file mode works correctly.
// const buildTasks: vscode.Task[] = await getBuildTasks();
// const task: vscode.Task = buildTasks.find(task => task.name === selection.configuration.preLaunchTask);
// await vscode.tasks.executeTask(task);
// delete selection.configuration.preLaunchTask;
}
}
// Attempt to use the user's (possibly) modified configuration before using the generated one.
try {
await vscode.debug.startDebugging(folder, selection.configuration.name);
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "true" });
} catch (e) {
try {
vscode.debug.startDebugging(folder, selection.configuration);
} catch (e) {
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
}
}
});
}));
configurationProvider.getConfigurationSnippets();
@@ -42,8 +129,8 @@ export function initialize(): void {
disposables.push(vscode.languages.registerCompletionItemProvider(launchJsonDocumentSelector, new ConfigurationSnippetProvider(configurationProvider)));
// Register Debug Adapters
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppvsdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppvsdbgDebugAdapterDescriptorFactory()));
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppdbgDebugAdapterDescriptorFactory()));
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppvsdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppvsdbgDebugAdapterDescriptorFactory(context)));
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppdbgDebugAdapterDescriptorFactory(context)));
vscode.Disposable.from(...disposables);
}
+33 -1
View File
@@ -23,13 +23,14 @@ import { createProtocolFilter } from './protocolFilter';
import { DataBinding } from './dataBinding';
import minimatch = require("minimatch");
import * as logger from '../logger';
import { updateLanguageConfigurations } from './extension';
import { updateLanguageConfigurations, registerCommands } from './extension';
import { CancellationTokenSource } from 'vscode';
import { SettingsTracker, getTracker } from './settingsTracker';
import { getTestHook, TestHook } from '../testHook';
import { getCustomConfigProviders, CustomConfigurationProviderCollection, CustomConfigurationProvider1 } from '../LanguageServer/customProviders';
import { ABTestSettings, getABTestSettings } from '../abTesting';
import * as fs from 'fs';
import * as os from 'os';
let ui: UI;
const configProviderTimeout: number = 2000;
@@ -202,6 +203,8 @@ export interface Client {
updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable<void>;
provideCustomConfiguration(document: vscode.TextDocument): Promise<void>;
getCurrentConfigName(): Thenable<string>;
getCompilerPath(): Thenable<string>;
getKnownCompilers(): Thenable<configs.KnownCompiler[]>;
takeOwnership(document: vscode.TextDocument): void;
queueTask<T>(task: () => Thenable<T>): Thenable<T>;
requestWhenReady(request: () => Thenable<any>): Thenable<any>;
@@ -319,6 +322,10 @@ class DefaultClient implements Client {
// The event handlers must be set before this happens.
languageClient.sendRequest(QueryCompilerDefaultsRequest, {}).then((compilerDefaults: configs.CompilerDefaults) => {
this.configuration.CompilerDefaults = compilerDefaults;
// Only register the real commands after the extension has finished initializing,
// e.g. prevents empty c_cpp_properties.json from generation.
registerCommands();
});
this.languageClient = languageClient;
@@ -373,6 +380,18 @@ class DefaultClient implements Client {
}
let abTestSettings: ABTestSettings = getABTestSettings();
let intelliSenseCacheDisabled: boolean = false;
if (os.platform() === "darwin") {
intelliSenseCacheDisabled = true;
// TODO: Re-enable this after the performance is improved on Mac.
//const releaseParts: string[] = os.release().split(".");
//if (releaseParts.length >= 1) {
// // AutoPCH doesn't work for older Mac OS's.
// intelliSenseCacheDisabled = parseInt(releaseParts[0]) < 17;
//}
}
let clientOptions: LanguageClientOptions = {
documentSelector: [
{ scheme: 'file', language: 'cpp' },
@@ -396,6 +415,9 @@ class DefaultClient implements Client {
tab_size: other.editorTabSize,
intelliSenseEngine: settings.intelliSenseEngine,
intelliSenseEngineFallback: settings.intelliSenseEngineFallback,
intelliSenseCacheDisabled: intelliSenseCacheDisabled,
intelliSenseCachePath : settings.intelliSenseCachePath,
intelliSenseCacheSize : settings.intelliSenseCacheSize,
autocomplete: settings.autoComplete,
errorSquiggles: settings.errorSquiggles,
dimInactiveRegions: settings.dimInactiveRegions,
@@ -662,6 +684,14 @@ class DefaultClient implements Client {
return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration.name));
}
public getCompilerPath(): Thenable<string> {
return this.queueTask(() => Promise.resolve(this.configuration.CompilerPath));
}
public getKnownCompilers(): Thenable<configs.KnownCompiler[]> {
return this.queueTask(() => Promise.resolve(this.configuration.KnownCompiler));
}
/**
* Take ownership of a document that was previously serviced by another client.
* This process involves sending a textDocument/didOpen message to the server so
@@ -1350,6 +1380,8 @@ class NullClient implements Client {
updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable<void> { return Promise.resolve(); }
provideCustomConfiguration(document: vscode.TextDocument): Promise<void> { return Promise.resolve(); }
getCurrentConfigName(): Thenable<string> { return Promise.resolve(""); }
getCompilerPath(): Thenable<string> { return Promise.resolve(""); }
getKnownCompilers(): Thenable<configs.KnownCompiler[]> { return Promise.resolve([]); }
takeOwnership(document: vscode.TextDocument): void {}
queueTask<T>(task: () => Thenable<T>): Thenable<T> { return task(); }
requestWhenReady(request: () => Thenable<any>): Thenable<any> { return; }
@@ -175,7 +175,8 @@ export class ClientCollection {
}
private onDidOpenTextDocument(document: vscode.TextDocument): void {
if (document.languageId === "c" || document.languageId === "cpp") {
if (document.languageId === "c" || document.languageId === "cpp"
|| document.languageId === "json" && document.uri.fsPath.endsWith("c_cpp_properties.json")) {
// Make sure a client exists for this document's workspace.
this.getClientFor(document.uri);
}
+283 -49
View File
@@ -13,6 +13,7 @@ import { PersistentFolderState } from './persistentState';
import { CppSettings } from './settings';
import { ABTestSettings, getABTestSettings } from '../abTesting';
import { getCustomConfigProviders } from './customProviders';
import * as os from 'os';
const configVersion: number = 4;
type Environment = { [key: string]: string | string[] };
@@ -46,6 +47,7 @@ export interface ConfigurationJson {
export interface Configuration {
name: string;
compilerPath?: string;
knownCompilers?: KnownCompiler[];
cStandard?: string;
cppStandard?: string;
includePath?: string[];
@@ -65,19 +67,26 @@ export interface Browse {
databaseFilename?: string;
}
export interface KnownCompiler {
path: string;
isC: boolean;
}
export interface CompilerDefaults {
compilerPath: string;
knownCompilers: KnownCompiler[];
cStandard: string;
cppStandard: string;
includes: string[];
frameworks: string[];
windowsSdkVersion: string;
intelliSenseMode: string;
rootfs: string;
}
export class CppProperties {
private rootUri: vscode.Uri;
private propertiesFile: vscode.Uri = null;
private propertiesFile: vscode.Uri = undefined;
private readonly configFolder: string;
private configurationJson: ConfigurationJson = null;
private currentConfigurationIndex: PersistentFolderState<number>;
@@ -85,6 +94,7 @@ export class CppProperties {
private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
private compileCommandFileWatchers: fs.FSWatcher[] = [];
private defaultCompilerPath: string = null;
private knownCompilers: KnownCompiler[] = null;
private defaultCStandard: string = null;
private defaultCppStandard: string = null;
private defaultIncludes: string[] = null;
@@ -98,6 +108,9 @@ export class CppProperties {
private configurationsChanged = new vscode.EventEmitter<Configuration[]>();
private selectionChanged = new vscode.EventEmitter<number>();
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;
// Any time the default settings are parsed and assigned to `this.configurationJson`,
// we want to track when the default includes have been added to it.
@@ -109,16 +122,55 @@ export class CppProperties {
let rootPath: string = rootUri ? rootUri.fsPath : "";
this.currentConfigurationIndex = new PersistentFolderState<number>("CppProperties.currentConfigurationIndex", -1, rootPath);
this.configFolder = path.join(rootPath, ".vscode");
this.diagnosticCollection = vscode.languages.createDiagnosticCollection(rootPath);
this.buildVcpkgIncludePath();
this.disposables.push(vscode.Disposable.from(this.configurationsChanged, this.selectionChanged, this.compileCommandsChanged));
}
public get ConfigurationsChanged(): vscode.Event<Configuration[]> { return this.configurationsChanged.event; }
public get SelectionChanged(): vscode.Event<number> { return this.selectionChanged.event; }
public get CompileCommandsChanged(): vscode.Event<string> { return this.compileCommandsChanged.event; }
public get Configurations(): Configuration[] { return this.configurationJson ? this.configurationJson.configurations : null; }
public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; }
public get CurrentConfiguration(): Configuration { return this.Configurations ? this.Configurations[this.CurrentConfigurationIndex] : null; }
public get CompilerPath(): string { return this.CurrentConfiguration ? this.CurrentConfiguration.compilerPath : null; }
public get KnownCompiler(): KnownCompiler[] { return this.knownCompilers; }
public get CurrentConfigurationProvider(): string|null {
if (this.CurrentConfiguration.configurationProvider) {
return this.CurrentConfiguration.configurationProvider;
}
return new CppSettings(this.rootUri).defaultConfigurationProvider;
}
public get ConfigurationNames(): string[] {
let result: string[] = [];
this.configurationJson.configurations.forEach((config: Configuration) => result.push(config.name));
return result;
}
public set CompilerDefaults(compilerDefaults: CompilerDefaults) {
this.defaultCompilerPath = compilerDefaults.compilerPath;
this.knownCompilers = compilerDefaults.knownCompilers;
this.defaultCStandard = compilerDefaults.cStandard;
this.defaultCppStandard = compilerDefaults.cppStandard;
this.defaultIncludes = compilerDefaults.includes;
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.
let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json");
if (fs.existsSync(configFilePath)) {
this.propertiesFile = vscode.Uri.file(configFilePath);
this.parsePropertiesFile();
} else {
this.propertiesFile = null;
}
if (!this.configurationJson) {
this.resetToDefaultSettings(this.CurrentConfigurationIndex === -1);
}
this.configFileWatcher = vscode.workspace.createFileSystemWatcher(path.join(this.configFolder, this.configurationGlobPattern));
this.disposables.push(this.configFileWatcher);
this.configFileWatcher.onDidCreate((uri) => {
@@ -136,42 +188,6 @@ export class CppProperties {
this.handleConfigurationChange();
});
this.buildVcpkgIncludePath();
this.disposables.push(vscode.Disposable.from(this.configurationsChanged, this.selectionChanged, this.compileCommandsChanged));
}
public get ConfigurationsChanged(): vscode.Event<Configuration[]> { return this.configurationsChanged.event; }
public get SelectionChanged(): vscode.Event<number> { return this.selectionChanged.event; }
public get CompileCommandsChanged(): vscode.Event<string> { return this.compileCommandsChanged.event; }
public get Configurations(): Configuration[] { return this.configurationJson.configurations; }
public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; }
public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; }
public get CurrentConfigurationProvider(): string|null {
if (this.CurrentConfiguration.configurationProvider) {
return this.CurrentConfiguration.configurationProvider;
}
return new CppSettings(this.rootUri).defaultConfigurationProvider;
}
public get ConfigurationNames(): string[] {
let result: string[] = [];
this.configurationJson.configurations.forEach((config: Configuration) => result.push(config.name));
return result;
}
public set CompilerDefaults(compilerDefaults: CompilerDefaults) {
this.defaultCompilerPath = compilerDefaults.compilerPath;
this.defaultCStandard = compilerDefaults.cStandard;
this.defaultCppStandard = compilerDefaults.cppStandard;
this.defaultIncludes = compilerDefaults.includes;
this.defaultFrameworks = compilerDefaults.frameworks;
this.defaultWindowsSdkVersion = compilerDefaults.windowsSdkVersion;
this.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
// 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.
this.handleConfigurationChange();
}
@@ -185,6 +201,7 @@ export class CppProperties {
private onSelectionChanged(): void {
this.selectionChanged.fire(this.CurrentConfigurationIndex);
this.handleSquiggles();
}
private onCompileCommandsChanged(path: string): void {
@@ -248,6 +265,9 @@ export class CppProperties {
// don't set a default when compileCommands is in use.
configuration.compilerPath = this.defaultCompilerPath;
}
if (this.knownCompilers) {
configuration.knownCompilers = this.knownCompilers;
}
if (isUnset(settings.defaultCStandard) && this.defaultCStandard) {
configuration.cStandard = this.defaultCStandard;
}
@@ -415,9 +435,9 @@ export class CppProperties {
private resolveAndSplit(paths: string[] | undefined, defaultValue: string[], env: Environment): string[] {
let result: string[] = [];
if (paths) {
paths = this.resolveDefaults(paths, defaultValue);
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry, env).split(";").filter(e => e);
entries = this.resolveDefaults(entries, defaultValue);
result = result.concat(entries);
});
}
@@ -453,6 +473,9 @@ export class CppProperties {
}
private updateServerOnFolderSettingsChange(): void {
if (!this.configurationJson) {
return;
}
let settings: CppSettings = new CppSettings(this.rootUri);
let env: Environment = this.ExtendedEnvironment;
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
@@ -548,7 +571,10 @@ export class CppProperties {
});
settings.update("default.configurationProvider", undefined); // delete the setting
}
let savedKnownCompilers: KnownCompiler[] = this.configurationJson.configurations[0].knownCompilers;
delete this.configurationJson.configurations[0].knownCompilers;
edit.insert(document.uri, new vscode.Position(0, 0), JSON.stringify(this.configurationJson, null, 4));
this.configurationJson.configurations[0].knownCompilers = savedKnownCompilers;
vscode.workspace.applyEdit(edit).then((status) => {
// Fix for issue 163
// https://github.com/Microsoft/vscppsamples/issues/163
@@ -569,12 +595,15 @@ export class CppProperties {
}
private handleConfigurationChange(): void {
if (this.propertiesFile === undefined) {
return; // Occurs when propertiesFile hasn't been checked yet.
}
this.configFileWatcherFallbackTime = new Date();
if (this.propertiesFile) {
this.parsePropertiesFile();
// parsePropertiesFile can fail, but it won't overwrite an existing configurationJson in the event of failure.
// this.configurationJson should only be undefined here if we have never successfully parsed the propertiesFile.
if (this.configurationJson !== undefined) {
if (this.configurationJson) {
if (this.CurrentConfigurationIndex < 0 ||
this.CurrentConfigurationIndex >= this.configurationJson.configurations.length) {
// If the index is out of bounds (during initialization or due to removal of configs), fix it.
@@ -583,7 +612,7 @@ export class CppProperties {
}
}
if (this.configurationJson === undefined) {
if (!this.configurationJson) {
this.resetToDefaultSettings(true); // I don't think there's a case where this will be hit anymore.
}
@@ -598,6 +627,11 @@ export class CppProperties {
return; // Repros randomly when the file is initially created. The parse will get called again after the file is written.
}
// Replace all \<escape character> with \\<character>.
// Otherwise, the JSON.parse result will have the \<escape character> missing.
readResults = readResults.replace(/\\/g, '\\\\');
readResults = readResults.replace(/\\\\"/g, '\\"'); // Need to revert the change to \".
// Try to use the same configuration as before the change.
let newJson: ConfigurationJson = JSON.parse(readResults);
if (!newJson || !newJson.configurations || newJson.configurations.length === 0) {
@@ -661,15 +695,213 @@ export class CppProperties {
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
} catch (err) {
// Ignore write errors, the file may be under source control. Updated settings will only be modified in memory.
vscode.window.showWarningMessage('Attempt to update "' + this.propertiesFile.fsPath + '" failed (do you have write access?)');
vscode.window.showWarningMessage(`Attempt to update "${this.propertiesFile.fsPath}" failed (do you have write access?)`);
}
}
this.handleSquiggles();
} catch (err) {
vscode.window.showErrorMessage('Failed to parse "' + this.propertiesFile.fsPath + '": ' + err.message);
vscode.window.showErrorMessage(`Failed to parse "${this.propertiesFile.fsPath}": ${err.message}`);
throw err;
}
}
private handleSquiggles(): void {
if (!this.propertiesFile) {
return;
}
vscode.workspace.openTextDocument(this.propertiesFile).then((document: vscode.TextDocument) => {
let diagnostics: vscode.Diagnostic[] = new Array<vscode.Diagnostic>();
// Get the text of the current configuration.
let curText: string = document.getText();
let curTextStartOffset: number = 0;
const configStart: number = curText.search(new RegExp(`{\\s*"name"\\s*:\\s*"${this.CurrentConfiguration.name}"`));
if (configStart === -1) {
telemetry.logLanguageServerEvent("ConfigSquiggles", { "error": "config name not first" });
return;
}
curTextStartOffset = configStart + 1;
curText = curText.substr(curTextStartOffset); // Remove earlier configs.
const nameEnd: number = curText.indexOf(":");
curTextStartOffset += nameEnd + 1;
curText = curText.substr(nameEnd + 1);
const nextNameStart: number = curText.search(new RegExp('"name"\\s*:\\s*"'));
if (nextNameStart !== -1) {
curText = curText.substr(0, nextNameStart + 6); // Remove later configs.
const nextNameStart2: number = curText.search(new RegExp('\\s*}\\s*,\\s*{\\s*"name"'));
if (nextNameStart2 === -1) {
telemetry.logLanguageServerEvent("ConfigSquiggles", { "error": "next config name not first" });
return;
}
curText = curText.substr(0, nextNameStart2);
}
// TODO: Add other squiggles.
// Check for path-related squiggles.
let paths: Set<string> = new Set<string>();
for (let pathArray of [ (this.CurrentConfiguration.browse ? this.CurrentConfiguration.browse.path : undefined),
this.CurrentConfiguration.includePath, this.CurrentConfiguration.macFrameworkPath, this.CurrentConfiguration.forcedInclude ] ) {
if (pathArray) {
for (let curPath of pathArray) {
paths.add(`"${curPath}"`);
}
}
}
if (this.CurrentConfiguration.compileCommands) {
paths.add(`"${this.CurrentConfiguration.compileCommands}"`);
}
if (this.CurrentConfiguration.compilerPath) {
// Unlike other cases, compilerPath may not start or end with " due to trimming of whitespace and the possibility of compiler args.
paths.add(`${this.CurrentConfiguration.compilerPath}`);
}
// Get the start/end for properties that are file-only.
const forcedIncludeStart: number = curText.search(/\s*\"forcedInclude\"\s*:\s*\[/);
const forcedeIncludeEnd: number = forcedIncludeStart === -1 ? -1 : curText.indexOf("]", forcedIncludeStart);
const compileCommandsStart: number = curText.search(/\s*\"compileCommands\"\s*:\s*\"/);
const compileCommandsEnd: number = compileCommandsStart === -1 ? -1 : curText.indexOf('"', curText.indexOf('"', curText.indexOf(":", compileCommandsStart)) + 1);
const compilerPathStart: number = curText.search(/\s*\"compilerPath\"\s*:\s*\"/);
const compilerPathEnd: number = compilerPathStart === -1 ? -1 : curText.indexOf('"', curText.indexOf('"', curText.indexOf(":", compilerPathStart)) + 1) + 1;
if (this.prevSquiggleMetrics[this.CurrentConfiguration.name] === undefined) {
this.prevSquiggleMetrics[this.CurrentConfiguration.name] = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0 };
}
let newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0 };
const isWindows: boolean = os.platform() === 'win32';
for (let curPath of paths) {
const isCompilerPath: boolean = curPath === this.CurrentConfiguration.compilerPath;
let resolvedPath: string = isCompilerPath ? curPath : curPath.substr(1, curPath.length - 2); // Remove the surrounding quotes.
// Resolve special path cases.
if (resolvedPath === "${default}") {
// TODO: Add squiggles for when the C_Cpp.default.* paths are invalid.
continue;
}
resolvedPath = util.resolveVariables(resolvedPath, this.ExtendedEnvironment);
if (resolvedPath.includes("${workspaceFolder}")) {
resolvedPath = resolvedPath.replace("${workspaceFolder}", this.rootUri.fsPath);
}
if (resolvedPath.includes("${workspaceRoot}")) {
resolvedPath = resolvedPath.replace("${workspaceRoot}", this.rootUri.fsPath);
}
if (resolvedPath.includes("${vcpkgRoot}")) {
resolvedPath = resolvedPath.replace("${vcpkgRoot}", util.getVcpkgRoot());
}
if (resolvedPath.includes("*")) {
resolvedPath = resolvedPath.replace(/\*/g, "");
}
// TODO: Invalid paths created from environment variables are not detected.
// Handle WSL paths.
const isWSL: boolean = isWindows && resolvedPath.startsWith("/");
if (isWSL) {
const mntStr: string = "/mnt/";
if (resolvedPath.length > "/mnt/c/".length && resolvedPath.substr(0, mntStr.length) === mntStr) {
resolvedPath = resolvedPath.substr(mntStr.length);
resolvedPath = resolvedPath.substr(0, 1) + ":" + resolvedPath.substr(1);
} else if (this.rootfs && this.rootfs.length > 0) {
resolvedPath = this.rootfs + resolvedPath.substr(1);
// TODO: Handle WSL symlinks.
}
}
if (isCompilerPath) {
let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedPath);
if (isWindows && compilerPathAndArgs.compilerPath.endsWith("cl.exe")) {
continue; // Don't squiggle invalid cl.exe paths because it could be for an older preview build.
}
resolvedPath = compilerPathAndArgs.compilerPath;
curPath = curPath.replace(/\"/g, `\\"`);
}
let pathExists: boolean = true;
let existsWithExeAdded: (path: string) => boolean = (path: string) => {
return isCompilerPath && isWindows && !isWSL && fs.existsSync(path + ".exe");
};
if (!fs.existsSync(resolvedPath)) {
if (existsWithExeAdded(resolvedPath)) {
resolvedPath += ".exe";
} else {
// Check again for a relative path.
const relativePath: string = this.rootUri.fsPath + path.sep + resolvedPath;
if (!fs.existsSync(relativePath)) {
if (existsWithExeAdded(resolvedPath)) {
resolvedPath += ".exe";
} else {
pathExists = false;
}
} else {
resolvedPath = relativePath;
}
}
}
// Normalize path separators.
if (path.sep === "/") {
resolvedPath = resolvedPath.replace(/\\/g, path.sep);
} else {
resolvedPath = resolvedPath.replace(/\//g, path.sep);
}
// Iterate through the text and apply squiggles.
for (let curOffset: number = curText.indexOf(curPath); curOffset !== -1; curOffset = curText.indexOf(curPath, curOffset + curPath.length)) {
let message: string;
if (!pathExists) {
message = `Cannot find "${resolvedPath}".`;
newSquiggleMetrics.PathNonExistent++;
} else {
// Check for file versus path mismatches.
if ((curOffset >= forcedIncludeStart && curOffset <= forcedeIncludeEnd) ||
(curOffset >= compileCommandsStart && curOffset <= compileCommandsEnd) ||
(curOffset >= compilerPathStart && curOffset <= compilerPathEnd)) {
if (util.checkFileExistsSync(resolvedPath)) {
continue;
}
message = `Path is not a file: "${resolvedPath}".`;
newSquiggleMetrics.PathNotAFile++;
} else {
if (util.checkDirectoryExistsSync(resolvedPath)) {
continue;
}
message = `Path is not a directory: "${resolvedPath}".`;
newSquiggleMetrics.PathNotADirectory++;
}
}
let diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
new vscode.Range(document.positionAt(curTextStartOffset + curOffset),
document.positionAt(curTextStartOffset + curOffset + curPath.length + (!isCompilerPath ? -1 : 0))),
message, vscode.DiagnosticSeverity.Warning);
diagnostics.push(diagnostic);
}
}
if (diagnostics.length !== 0) {
this.diagnosticCollection.set(document.uri, diagnostics);
} else {
this.diagnosticCollection.clear();
}
// Send telemetry on squiggle changes.
let changedSquiggleMetrics: { [key: string]: number } = {};
if (newSquiggleMetrics.PathNonExistent !== this.prevSquiggleMetrics[this.CurrentConfiguration.name].PathNonExistent) {
changedSquiggleMetrics.PathNonExistent = newSquiggleMetrics.PathNonExistent;
}
if (newSquiggleMetrics.PathNotAFile !== this.prevSquiggleMetrics[this.CurrentConfiguration.name].PathNotAFile) {
changedSquiggleMetrics.PathNotAFile = newSquiggleMetrics.PathNotAFile;
}
if (newSquiggleMetrics.PathNotADirectory !== this.prevSquiggleMetrics[this.CurrentConfiguration.name].PathNotADirectory) {
changedSquiggleMetrics.PathNotADirectory = newSquiggleMetrics.PathNotADirectory;
}
if (Object.keys(changedSquiggleMetrics).length > 0) {
telemetry.logLanguageServerEvent("ConfigSquiggles", null, changedSquiggleMetrics);
}
this.prevSquiggleMetrics[this.CurrentConfiguration.name] = newSquiggleMetrics;
});
}
private updateToVersion2(): void {
this.configurationJson.version = 2;
// no-op. We don't automatically populate the browse.path anymore.
@@ -721,13 +953,13 @@ export class CppProperties {
let propertiesFile: string = path.join(this.configFolder, "c_cpp_properties.json");
fs.stat(propertiesFile, (err, stats) => {
if (err) {
if (this.propertiesFile !== null) {
if (this.propertiesFile) {
this.propertiesFile = null; // File deleted.
this.resetToDefaultSettings(true);
this.handleConfigurationChange();
}
} else if (stats.mtime > this.configFileWatcherFallbackTime) {
if (this.propertiesFile === null) {
if (!this.propertiesFile) {
this.propertiesFile = vscode.Uri.file(propertiesFile); // File created.
}
this.handleConfigurationChange();
@@ -741,5 +973,7 @@ export class CppProperties {
this.compileCommandFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close());
this.compileCommandFileWatchers = []; //reset it
this.diagnosticCollection.dispose();
}
}
+318 -75
View File
@@ -21,8 +21,10 @@ import { PlatformInformation } from '../platform';
import { Range } from 'vscode-languageclient';
import { ChildProcess, spawn, execSync } from 'child_process';
import * as tmp from 'tmp';
import { getTargetBuildInfo } from '../githubAPI';
import { getTargetBuildInfo, BuildInfo } from '../githubAPI';
import * as configs from './configurations';
import { PackageVersion } from '../packageVersion';
import { getTemporaryCommandRegistrarInstance } from '../commands';
let prevCrashFile: string;
let clients: ClientCollection;
@@ -36,12 +38,18 @@ let realActivationOccurred: boolean = false;
let tempCommands: vscode.Disposable[] = [];
let activatedPreviously: PersistentWorkspaceState<boolean>;
const insiderUpdateTimerInterval: number = 1000 * 60 * 60;
let buildInfoCache: BuildInfo | null = null;
const taskSourceStr: string = "C/C++";
const cppInstallVsixStr: string = 'C/C++: Install vsix -- ';
let taskProvider: vscode.Disposable;
/**
* activate: set up the extension for language services
*/
export function activate(activationEventOccurred: boolean): void {
console.log("activating extension");
if (realActivationOccurred) {
return; // Occurs if multiple delayed commands occur before the real commands are registered.
}
// Activate immediately if an activation event occurred in the previous workspace session.
// If onActivationEvent doesn't occur, it won't auto-activate next time.
@@ -51,8 +59,9 @@ export function activate(activationEventOccurred: boolean): void {
realActivation();
}
registerCommands();
tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d)));
if (tempCommands.length === 0) { // Only needs to be added once.
tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d)));
}
// Check if an activation event has already occurred.
if (activationEventOccurred) {
@@ -60,6 +69,21 @@ export function activate(activationEventOccurred: boolean): void {
return;
}
taskProvider = vscode.tasks.registerTaskProvider(taskSourceStr, {
provideTasks: () => {
return getBuildTasks();
},
resolveTask(task: vscode.Task): vscode.Task {
// Currently cannot implement because VS Code does not call this. Can implement custom output file directory when enabled.
return undefined;
}
});
vscode.tasks.onDidStartTask(event => {
if (event.execution.task.source === taskSourceStr) {
telemetry.logLanguageServerEvent('buildTaskStarted');
}
});
// handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event.
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
for (let i: number = 0; i < vscode.workspace.workspaceFolders.length; ++i) {
@@ -83,6 +107,146 @@ export function activate(activationEventOccurred: boolean): void {
}
}
export interface BuildTaskDefinition extends vscode.TaskDefinition {
compilerPath: string;
}
/**
* Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension.
*/
export async function getBuildTasks(): Promise<vscode.Task[]> {
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
if (!editor) {
return [];
}
const fileExt: string = path.extname(editor.document.fileName);
if (!fileExt) {
return;
}
// Don't offer tasks for header files.
const fileExtLower: string = fileExt.toLowerCase();
const isHeader: boolean = !fileExt || [".hpp", ".hh", ".hxx", ".h", ".inl", ""].some(ext => fileExtLower === ext);
if (isHeader) {
return [];
}
// Don't offer tasks if the active file's extension is not a recognized C/C++ extension.
let fileIsCpp: boolean;
let fileIsC: boolean;
if (fileExt === ".C") { // ".C" file extensions are both C and C++.
fileIsCpp = true;
fileIsC = true;
} else {
fileIsCpp = [".cpp", ".cc", ".cxx", ".mm", ".ino"].some(ext => fileExtLower === ext);
fileIsC = fileExtLower === ".c";
}
if (!(fileIsCpp || fileIsC)) {
return [];
}
// Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate
// for the active file, remove duplicate compiler names, then finally add the user's compilerPath setting.
let compilerPaths: string[];
const isWindows: boolean = os.platform() === 'win32';
const activeClient: Client = getActiveClient();
let userCompilerPath: string = await activeClient.getCompilerPath();
if (userCompilerPath) {
userCompilerPath = userCompilerPath.trim();
if (isWindows && userCompilerPath.startsWith("/")) { // TODO: Add WSL compiler support.
userCompilerPath = null;
} else {
userCompilerPath = userCompilerPath.replace(/\\\\/g, "\\");
}
}
let knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers();
if (knownCompilers) {
knownCompilers = knownCompilers.filter(info => {
return ((fileIsCpp && !info.isC) || (fileIsC && info.isC)) &&
(!isWindows || !info.path.startsWith("/")); // TODO: Add WSL compiler support.
});
compilerPaths = knownCompilers.map<string>(info => { return info.path; });
let map: Map<string, string> = new Map<string, string>();
const insertOrAssignEntry: (compilerPath: string) => void = (compilerPath: string): void => {
const basename: string = path.basename(compilerPath);
//map.has(basename) ? map.basename] = compilerPath :
map.set(basename, compilerPath);
};
compilerPaths.forEach(insertOrAssignEntry);
// Ensure that the user's compilerPath setting is used by inserting/assigning last.
if (userCompilerPath) {
insertOrAssignEntry(userCompilerPath);
}
compilerPaths = [...map.values()];
} else if (userCompilerPath) {
compilerPaths = [userCompilerPath];
}
if (!compilerPaths) {
// Don't prompt a message yet until we can make a data-based decision.
telemetry.logLanguageServerEvent('noCompilerFound');
// Display a message prompting the user to install compilers if none were found.
// const dontShowAgain: string = "Don't Show Again";
// const learnMore: string = "Learn More";
// const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/C++: build active file tasks.";
// let showNoCompilerFoundMessage: PersistentState<boolean> = new PersistentState<boolean>("CPP.showNoCompilerFoundMessage", true);
// if (showNoCompilerFoundMessage) {
// vscode.window.showInformationMessage(message, learnMore, dontShowAgain).then(selection => {
// switch (selection) {
// case learnMore:
// const uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`);
// vscode.commands.executeCommand('vscode.open', uri);
// break;
// case dontShowAgain:
// showNoCompilerFoundMessage.Value = false;
// break;
// default:
// break;
// }
// });
// }
return [];
}
// Generate tasks.
return compilerPaths.map<vscode.Task>(compilerPath => {
// Handle compiler args in compilerPath.
let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(compilerPath);
compilerPath = compilerPathAndArgs.compilerPath;
const filePath: string = path.join('${fileDirname}', '${fileBasenameNoExtension}');
const compilerPathBase: string = path.basename(compilerPath);
const taskName: string = compilerPathBase + " build active file";
const isCl: boolean = taskName.startsWith("cl.exe");
let args: string[] = isCl ? [ '/Zi', '/EHsc', '/Fe:', filePath + '.exe', '${file}' ] : ['-g', '${file}', '-o', filePath + (isWindows ? '.exe' : '')];
if (compilerPathAndArgs.additionalArgs) {
args = args.concat(compilerPathAndArgs.additionalArgs);
}
const cwd: string = isCl ? "" : path.dirname(compilerPath);
const kind: BuildTaskDefinition = {
type: 'shell',
label: taskName,
command: isCl ? compilerPathBase : compilerPath,
args: args,
options: isCl ? undefined : {"cwd": cwd},
compilerPath: isCl ? compilerPathBase : compilerPath
};
const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, [...args], { cwd: cwd });
const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri);
let task: vscode.Task = new vscode.Task(kind, target, taskName, taskSourceStr, command, '$gcc');
task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning.
task.group = vscode.TaskGroup.Build;
return task;
});
}
function onDidOpenTextDocument(document: vscode.TextDocument): void {
if (document.languageId === "c" || document.languageId === "cpp") {
onActivationEvent();
@@ -109,6 +273,7 @@ function realActivation(): void {
if (new CppSettings().intelliSenseEngine === "Disabled") {
throw new Error("Do not activate the extension when IntelliSense is disabled.");
} else {
console.log("activating extension");
let checkForConflictingExtensions: PersistentState<boolean> = new PersistentState<boolean>("CPP." + util.packageJson.version + ".checkForConflictingExtensions", true);
if (checkForConflictingExtensions.Value) {
checkForConflictingExtensions.Value = false;
@@ -147,9 +312,12 @@ function realActivation(): void {
updateLanguageConfigurations();
reportMacCrashes();
const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri);
if (settings.updateChannel === 'Insiders') {
if (settings.updateChannel === 'Default') {
suggestInsidersChannel();
} else if (settings.updateChannel === 'Insiders') {
insiderUpdateTimer = setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval, settings.updateChannel);
checkAndApplyUpdate(settings.updateChannel);
}
@@ -180,7 +348,7 @@ function onDidChangeSettings(): void {
} else if (newUpdateChannel === 'Insiders') {
insiderUpdateTimer = setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval);
}
checkAndApplyUpdate(newUpdateChannel);
}
}
@@ -244,7 +412,7 @@ function onInterval(): void {
* Install a VSIX package. This helper function will exist until VSCode offers a command to do so.
* @param updateChannel The user's updateChannel setting.
*/
async function installVsix(vsixLocation: string, updateChannel: string): Promise<void> {
function installVsix(vsixLocation: string, updateChannel: string): Promise<void> {
// Get the path to the VSCode command -- replace logic later when VSCode allows calling of
// workbench.extensions.action.installVSIX from TypeScript w/o instead popping up a file dialog
return PlatformInformation.GetPlatformInformation().then((platformInfo) => {
@@ -286,6 +454,21 @@ async function installVsix(vsixLocation: string, updateChannel: string): Promise
let process: ChildProcess;
try {
process = spawn(vsCodeScriptPath, ['--install-extension', vsixLocation, '--force']);
// Timeout the process if no response is sent back. Ensures this Promise resolves/rejects
const timer: NodeJS.Timer = setTimeout(() => {
process.kill();
reject(new Error('Failed to receive response from VS Code script process for installation within 30s.'));
}, 30000);
process.on('exit', (code: number) => {
clearInterval(timer);
if (code !== 0) {
reject(new Error(`VS Code script exited with error code ${code}`));
} else {
resolve();
}
});
if (process.pid === undefined) {
throw new Error();
}
@@ -293,7 +476,6 @@ async function installVsix(vsixLocation: string, updateChannel: string): Promise
reject(new Error('Failed to launch VS Code script process for installation'));
return;
}
resolve();
});
}
@@ -331,78 +513,99 @@ async function installVsix(vsixLocation: string, updateChannel: string): Promise
});
}
/**
* Query package.json and the GitHub API to determine whether the user should update, if so then install the update.
* The update can be an upgrade or downgrade depending on the the updateChannel setting.
* @param updateChannel The user's updateChannel setting.
*/
async function checkAndApplyUpdate(updateChannel: string): Promise<void> {
// Wrap in new Promise to allow tmp.file callback to successfully resolve/reject
// as tmp.file does not do anything with the callback functions return value
const p: Promise<void> = new Promise<void>((resolve, reject) => {
getTargetBuildInfo(updateChannel).then(buildInfo => {
if (!buildInfo) {
resolve();
async function suggestInsidersChannel(): Promise<void> {
let suggestInsiders: PersistentState<boolean> = new PersistentState<boolean>("CPP.suggestInsiders", true);
if (!suggestInsiders.Value) {
return;
}
let buildInfo: BuildInfo;
try {
buildInfo = await getTargetBuildInfo("Insiders");
} catch (error) {
console.log(`${cppInstallVsixStr}${error.message}`);
if (error.message.indexOf('/') !== -1 || error.message.indexOf('\\') !== -1) {
error.message = "Potential PII hidden";
}
telemetry.logLanguageServerEvent('suggestInsiders', { 'error': error.message, 'success': 'false' });
}
if (!buildInfo) {
return; // No need to update.
}
const message: string = `Insiders version ${buildInfo.name} is available. Would you like to switch to the Insiders channel and install this update?`;
const yes: string = "Yes";
const askLater: string = "Ask Me Later";
const dontShowAgain: string = "Don't Show Again";
let selection: string = await vscode.window.showInformationMessage(message, yes, askLater, dontShowAgain);
switch (selection) {
case yes:
// Cache buildInfo.
buildInfoCache = buildInfo;
// It will call onDidChangeSettings.
vscode.workspace.getConfiguration("C_Cpp").update("updateChannel", "Insiders", vscode.ConfigurationTarget.Global);
break;
case dontShowAgain:
suggestInsiders.Value = false;
break;
case askLater:
break;
default:
break;
}
}
function applyUpdate(buildInfo: BuildInfo, updateChannel: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
tmp.file({postfix: '.vsix'}, async (err, vsixPath, fd, cleanupCallback) => {
if (err) {
reject(new Error('Failed to create vsix file'));
return;
}
// Create a temporary file, download the VSIX to it, then install the VSIX
tmp.file({postfix: '.vsix'}, async (err, vsixPath, fd, cleanupCallback) => {
if (err) {
reject(new Error('Failed to create vsix file'));
return;
}
// Place in try/catch as the .catch call catches a rejection in downloadFileToDestination
// then the .catch call will return a resolved promise
// Thusly, the .catch call must also throw, as a return would simply return an unused promise
// instead of returning early from this function scope
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let originalProxySupport: string = config.inspect<string>('http.proxySupport').globalValue;
while (true) { // Might need to try again with a different http.proxySupport setting.
try {
await util.downloadFileToDestination(buildInfo.downloadUrl, vsixPath);
} catch {
// Try again with the proxySupport to "off".
if (originalProxySupport !== config.inspect<string>('http.proxySupport').globalValue) {
config.update('http.proxySupport', originalProxySupport, true); // Reset the http.proxySupport.
reject(new Error('Failed to download VSIX package with proxySupport off')); // Changing the proxySupport didn't help.
return;
}
if (config.get('http.proxySupport') !== "off" && originalProxySupport !== "off") {
config.update('http.proxySupport', "off", true);
continue;
}
reject(new Error('Failed to download VSIX package'));
return;
}
// Place in try/catch as the .catch call catches a rejection in downloadFileToDestination
// then the .catch call will return a resolved promise
// Thusly, the .catch call must also throw, as a return would simply return an unused promise
// instead of returning early from this function scope
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let originalProxySupport: string = config.inspect<string>('http.proxySupport').globalValue;
while (true) { // Might need to try again with a different http.proxySupport setting.
try {
await util.downloadFileToDestination(buildInfo.downloadUrl, vsixPath);
} catch {
// Try again with the proxySupport to "off".
if (originalProxySupport !== config.inspect<string>('http.proxySupport').globalValue) {
config.update('http.proxySupport', originalProxySupport, true); // Reset the http.proxySupport.
telemetry.logLanguageServerEvent('installVsix', { 'error': "Success with proxySupport off", 'success': 'true' });
reject(new Error('Failed to download VSIX package with proxySupport off')); // Changing the proxySupport didn't help.
return;
}
break;
}
try {
await installVsix(vsixPath, updateChannel);
} catch (error) {
reject(error);
if (config.get('http.proxySupport') !== "off" && originalProxySupport !== "off") {
config.update('http.proxySupport', "off", true);
continue;
}
reject(new Error('Failed to download VSIX package'));
return;
}
clearInterval(insiderUpdateTimer);
const message: string =
`The C/C++ Extension has been updated to version ${buildInfo.name}. Please reload the window for the changes to take effect.`;
util.promptReloadWindow(message);
telemetry.logLanguageServerEvent('installVsix', { 'success': 'true' });
resolve();
});
}, (error: Error) => {
// Handle getTargetBuildInfo rejection
reject(error);
if (originalProxySupport !== config.inspect<string>('http.proxySupport').globalValue) {
config.update('http.proxySupport', originalProxySupport, true); // Reset the http.proxySupport.
telemetry.logLanguageServerEvent('installVsix', { 'error': "Success with proxySupport off", 'success': 'true' });
}
break;
}
try {
await installVsix(vsixPath, updateChannel);
} catch (error) {
reject(error);
return;
}
clearInterval(insiderUpdateTimer);
const message: string =
`The C/C++ Extension has been updated to version ${buildInfo.name}. Please reload the window for the changes to take effect.`;
util.promptReloadWindow(message);
telemetry.logLanguageServerEvent('installVsix', { 'success': 'true' });
resolve();
});
});
await p.catch((error: Error) => {
// Handle .then following getTargetBuildInfo rejection
}).catch(error => {
console.error(`${cppInstallVsixStr}${error.message}`);
if (error.message.indexOf('/') !== -1 || error.message.indexOf('\\') !== -1) {
error.message = "Potential PII hidden";
}
@@ -410,11 +613,41 @@ async function checkAndApplyUpdate(updateChannel: string): Promise<void> {
});
}
/**
* Query package.json and the GitHub API to determine whether the user should update, if so then install the update.
* The update can be an upgrade or downgrade depending on the the updateChannel setting.
* @param updateChannel The user's updateChannel setting.
*/
async function checkAndApplyUpdate(updateChannel: string): Promise<void> {
// If we have buildInfo cache, we should use it.
let buildInfo: BuildInfo | null = buildInfoCache;
// clear buildInfo cache.
buildInfoCache = null;
if (!buildInfo) {
try {
buildInfo = await getTargetBuildInfo(updateChannel);
} catch (error) {
telemetry.logLanguageServerEvent('installVsix', { 'error': error.message, 'success': 'false' });
}
}
if (!buildInfo) {
return; // No need to update.
}
await applyUpdate(buildInfo, updateChannel);
}
/*********************************************
* registered commands
*********************************************/
let commandsRegistered: boolean = false;
function registerCommands(): void {
export function registerCommands(): void {
if (commandsRegistered) {
return;
}
commandsRegistered = true;
getTemporaryCommandRegistrarInstance().clearTempCommands();
disposables.push(vscode.commands.registerCommand('C_Cpp.Navigate', onNavigate));
disposables.push(vscode.commands.registerCommand('C_Cpp.GoToDeclaration', onGoToDeclaration));
disposables.push(vscode.commands.registerCommand('C_Cpp.PeekDeclaration', onPeekDeclaration));
@@ -432,6 +665,8 @@ function registerCommands(): void {
disposables.push(vscode.commands.registerCommand('C_Cpp.ResumeParsing', onResumeParsing));
disposables.push(vscode.commands.registerCommand('C_Cpp.ShowParsingCommands', onShowParsingCommands));
disposables.push(vscode.commands.registerCommand('C_Cpp.TakeSurvey', onTakeSurvey));
disposables.push(vscode.commands.registerCommand('cpptools.activeConfigName', onGetActiveConfigName));
getTemporaryCommandRegistrarInstance().executeDelayedCommands();
}
function onNavigate(): void {
@@ -612,6 +847,10 @@ function onTakeSurvey(): void {
vscode.commands.executeCommand('vscode.open', uri);
}
function onGetActiveConfigName(): Thenable<string> {
return clients.ActiveClient.getCurrentConfigName();
}
function reportMacCrashes(): void {
if (process.platform === "darwin") {
prevCrashFile = "";
@@ -686,6 +925,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException, data: string): void {
// Get rid of the memory addresses (which breaks being able get a hit count for each crash call stack).
data = data.replace(/0x................ /g, "");
data = data.replace(/0x1........ \+ 0/g, "");
// Get rid of the process names on each line and just add it to the start.
const process1: string = "Microsoft.VSCode.CPP.IntelliSense.Msvc.darwin\t";
@@ -727,6 +967,9 @@ export function deactivate(): Thenable<void> {
disposables.forEach(d => d.dispose());
languageConfigurations.forEach(d => d.dispose());
ui.dispose();
if (taskProvider) {
taskProvider.dispose();
}
return clients.dispose();
}
@@ -746,4 +989,4 @@ export function getActiveClient(): Client {
realActivation();
}
return clients.ActiveClient;
}
}
+2
View File
@@ -39,6 +39,8 @@ export class CppSettings extends Settings {
public get suggestSnippets(): boolean { return super.Section.get<boolean>("suggestSnippets"); }
public get intelliSenseEngine(): string { return super.Section.get<string>("intelliSenseEngine"); }
public get intelliSenseEngineFallback(): string { return super.Section.get<string>("intelliSenseEngineFallback"); }
public get intelliSenseCachePath(): string { return super.Section.get<string>("intelliSenseCachePath"); }
public get intelliSenseCacheSize(): number { return super.Section.get<number>("intelliSenseCacheSize"); }
public get errorSquiggles(): string { return super.Section.get<string>("errorSquiggles"); }
public get dimInactiveRegions(): boolean { return super.Section.get<boolean>("dimInactiveRegions"); }
public get inactiveRegionOpacity(): number { return super.Section.get<number>("inactiveRegionOpacity"); }
@@ -160,7 +160,7 @@ export class SettingsTracker {
break;
}
default: {
if (key === "clang_format_path" || key.startsWith("default.")) {
if (key === "clang_format_path" || key === "intelliSenseCachePath" || key.startsWith("default.")) {
value = this.areEqual(val, settings.inspect(key).defaultValue) ? "<default>" : "..."; // Track whether it's being used, but nothing specific about it.
} else {
value = String(this.previousCppSettings[key]);
+12 -3
View File
@@ -11,7 +11,8 @@ class TemporaryCommandRegistrar {
// Used to save/re-execute commands used before the extension has activated (e.g. delayed by dependency downloading).
private delayedCommandsToExecute: Set<string>;
private tempCommands: vscode.Disposable[]; // Need to save this to unregister/dispose the temporary commands.
private isLanguageServerDisabled: boolean;
private isLanguageServerDisabled: boolean = false;
private isActivationReady: boolean = false;
private commandsToRegister: string[] = [
"C_Cpp.ConfigurationEdit",
@@ -49,6 +50,9 @@ class TemporaryCommandRegistrar {
return;
}
this.delayedCommandsToExecute.add(command);
if (this.isActivationReady) {
LanguageServer.activate(true);
}
}));
}
@@ -58,13 +62,18 @@ class TemporaryCommandRegistrar {
public activateLanguageServer(): void {
// Main activation code.
LanguageServer.activate(this.delayedCommandsToExecute.size > 0);
this.isActivationReady = true;
}
public clearTempCommands(): void {
this.tempCommands.forEach((command) => {
command.dispose();
});
this.tempCommands = [];
}
LanguageServer.activate(this.delayedCommandsToExecute.size > 0);
public executeDelayedCommands(): void {
this.delayedCommandsToExecute.forEach((command) => {
vscode.commands.executeCommand(command);
});
+132
View File
@@ -16,6 +16,7 @@ import { getOutputChannelLogger, showOutputChannel } from './logger';
import * as assert from 'assert';
import * as https from 'https';
import { ClientRequest, OutgoingHttpHeaders } from 'http';
import { getBuildTasks } from './LanguageServer/extension';
export let extensionContext: vscode.ExtensionContext;
export function setExtensionContext(context: vscode.ExtensionContext): void {
@@ -36,6 +37,67 @@ export function getRawPackageJson(): any {
return rawPackageJson;
}
export function getRawTasksJson(): Promise<any> {
const path: string = getTasksJsonPath();
if (!path) {
return undefined;
}
return new Promise<any>((resolve, reject) => {
fs.exists(path, exists => {
if (!exists) {
return resolve({});
}
const fileContents: Buffer = fs.readFileSync(path);
let rawTasks: any = {};
try {
rawTasks = JSON.parse(fileContents.toString());
} catch (error) {
}
resolve(rawTasks);
});
});
}
export async function ensureBuildTaskExists(taskName: string): Promise<void> {
let rawTasksJson: any = await getRawTasksJson();
// Ensure that the task exists in the user's task.json. Task will not be found otherwise.
if (!rawTasksJson.tasks) {
rawTasksJson.tasks = new Array();
}
// Find or create the task which should be created based on the selected "debug configuration".
let selectedTask: vscode.Task = rawTasksJson.tasks.find(task => {
return task.label && task.label === task;
});
if (selectedTask) {
return;
}
const buildTasks: vscode.Task[] = await getBuildTasks();
selectedTask = buildTasks.find(task => task.name === taskName);
console.assert(selectedTask);
let definition: vscode.TaskDefinition = selectedTask.definition as vscode.TaskDefinition;
if (definition && definition.compilerPath) {
// TODO: add desired properties to empty object, don't delete.
delete definition.compilerPath;
}
rawTasksJson.version = "2.0.0";
if (!rawTasksJson.tasks.find(task => { return task.label === selectedTask.definition.label; })) {
rawTasksJson.tasks.push(selectedTask.definition);
}
// TODO: It's dangerous to overwrite this file. We could be wiping out comments.
await writeFileText(getTasksJsonPath(), JSON.stringify(rawTasksJson, null, 2));
}
export function fileIsCOrCppSource(file: string): boolean {
const fileExtLower: string = path.extname(file).toLowerCase();
return [".C", ".c", ".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => fileExtLower === ext);
}
// This function is used to stringify the rawPackageJson.
// Do not use with util.packageJson or else the expanded
// package.json will be written back.
@@ -51,6 +113,15 @@ export function getPackageJsonPath(): string {
return getExtensionFilePath("package.json");
}
export function getTasksJsonPath(): string {
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
const folder: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri);
if (!folder) {
return undefined;
}
return path.join(folder.uri.fsPath, ".vscode", "tasks.json");
}
export function getVcpkgPathDescriptorFile(): string {
if (process.platform === 'win32') {
return path.join(process.env.LOCALAPPDATA, "vcpkg/vcpkg.path.txt");
@@ -386,6 +457,23 @@ export function checkDirectoryExists(dirPath: string): Promise<boolean> {
});
}
export function checkFileExistsSync(filePath: string): boolean {
try {
return fs.statSync(filePath).isFile();
} catch (e) {
}
return false;
}
/** Test whether a directory exists */
export function checkDirectoryExistsSync(dirPath: string): boolean {
try {
return fs.statSync(dirPath).isDirectory();
} catch (e) {
}
return false;
}
/** Read the files in a directory */
export function readDir(dirPath: string): Promise<string[]> {
return new Promise((resolve) => {
@@ -669,4 +757,48 @@ export function downloadFileToStr(urlStr: string, headers?: OutgoingHttpHeaders)
request.on('error', (error) => { reject(error); });
request.end();
});
}
export interface CompilerPathAndArgs {
compilerPath: string;
additionalArgs: string[];
}
export function extractCompilerPathAndArgs(inputCompilerPath: string): CompilerPathAndArgs {
let compilerPath: string = inputCompilerPath;
let additionalArgs: string[];
let isWindows: boolean = os.platform() === 'win32';
if (compilerPath) {
compilerPath = compilerPath.trim();
if (compilerPath.startsWith("\"")) {
let endQuote: number = compilerPath.substr(1).search("\"") + 1;
if (endQuote !== -1) {
additionalArgs = compilerPath.substr(endQuote + 1).split(" ");
additionalArgs = additionalArgs.filter((arg: string) => { return arg.trim().length !== 0; }); // Remove empty args.
compilerPath = compilerPath.substr(1, endQuote - 1);
}
} else {
// Go from right to left checking if a valid path is to the left of a space.
let spaceStart: number = compilerPath.lastIndexOf(" ");
if (spaceStart !== -1 && (!isWindows || !compilerPath.endsWith("cl.exe")) && !checkFileExistsSync(compilerPath)) {
let potentialCompilerPath: string = compilerPath.substr(0, spaceStart);
while ((!isWindows || !potentialCompilerPath.endsWith("cl.exe")) && !checkFileExistsSync(potentialCompilerPath)) {
spaceStart = potentialCompilerPath.lastIndexOf(" ");
if (spaceStart === -1) {
// Reached the start without finding a valid path. Use the original value.
potentialCompilerPath = compilerPath;
break;
}
potentialCompilerPath = potentialCompilerPath.substr(0, spaceStart);
}
if (compilerPath !== potentialCompilerPath) {
// Found a valid compilerPath and args.
additionalArgs = compilerPath.substr(spaceStart + 1).split(" ");
additionalArgs = additionalArgs.filter((arg: string) => { return arg.trim().length !== 0; }); // Remove empty args.
compilerPath = potentialCompilerPath;
}
}
}
}
return { compilerPath, additionalArgs };
}
+11 -6
View File
@@ -9,6 +9,8 @@ import * as util from './common';
import { PlatformInformation } from './platform';
import { OutgoingHttpHeaders } from 'http';
const testingInsidersVsixInstall: boolean = false; // Change this to true to enable testing of the Insiders vsix installation.
/**
* The object representation of a Build Asset. Each Asset corresponds to information about a release file on GitHub.
*/
@@ -139,7 +141,7 @@ export async function getTargetBuildInfo(updateChannel: string): Promise<BuildIn
// Allows testing pre-releases without accidentally downgrading to the latest version
const userVersion: PackageVersion = new PackageVersion(util.packageJson.version);
const latestVersion: PackageVersion = new PackageVersion(builds[0].name);
if (userVersion.isGreaterThan(latestVersion) || (userVersion.suffix && userVersion.suffix !== 'insiders')) {
if (!testingInsidersVsixInstall && (userVersion.isGreaterThan(latestVersion) || (userVersion.suffix && userVersion.suffix !== 'insiders'))) {
return undefined;
}
@@ -172,7 +174,7 @@ function getTargetBuild(builds: Build[], userVersion: PackageVersion, updateChan
let needsUpdate: (installed: PackageVersion, target: PackageVersion) => boolean;
let useBuild: (build: Build) => boolean;
if (updateChannel === 'Insiders') {
needsUpdate = (installed: PackageVersion, target: PackageVersion) => { return target.isGreaterThan(installed); };
needsUpdate = (installed: PackageVersion, target: PackageVersion) => { return testingInsidersVsixInstall || target.isGreaterThan(installed); };
useBuild = (build: Build): boolean => { return true; };
} else if (updateChannel === 'Default') {
needsUpdate = function(installed: PackageVersion, target: PackageVersion): boolean { return installed.isGreaterThan(target); };
@@ -189,7 +191,10 @@ function getTargetBuild(builds: Build[], userVersion: PackageVersion, updateChan
// Check current version against target's version to determine if the installation should happen
const targetVersion: PackageVersion = new PackageVersion(targetBuild.name);
return needsUpdate(userVersion, targetVersion) ? targetBuild : undefined;
if (needsUpdate(userVersion, targetVersion)) {
return targetBuild;
}
return undefined;
}
interface Rate {
@@ -201,7 +206,7 @@ interface RateLimit {
}
function isRate(input: any): input is Rate {
return input && input.remaining && util.isNumber(input.remaining);
return input && util.isNumber(input.remaining);
}
function isRateLimit(input: any): input is RateLimit {
@@ -212,7 +217,7 @@ async function getRateLimit(): Promise<RateLimit> {
const header: OutgoingHttpHeaders = { 'User-Agent': 'vscode-cpptools' };
const data: string = await util.downloadFileToStr('https://api.github.com/rate_limit', header)
.catch((error) => {
if (error.code && error.code !== "ENOENT") {
if (error && error.code && error.code !== "ENOENT") {
// Only throw if the user is connected to the Internet.
throw new Error('Failed to download rate limit JSON');
}
@@ -255,7 +260,7 @@ async function getReleaseJson(): Promise<Build[]> {
const data: string = await util.downloadFileToStr(releaseUrl, header)
.catch((error) => {
if (error.code && error.code !== "ENOENT") {
if (error && error.code && error.code !== "ENOENT") {
// Only throw if the user is connected to the Internet.
throw new Error('Failed to download release JSON');
}
+3 -2
View File
@@ -22,7 +22,7 @@ import { getInstallationInformation, InstallationInformation, setInstallationSta
import { Logger, getOutputChannelLogger, showOutputChannel } from './logger';
import { CppTools1 } from './cppTools1';
const releaseNotesVersion: number = 3;
const releaseNotesVersion: number = 4;
const cppTools: CppTools1 = new CppTools1();
let languageServiceDisabled: boolean = false;
let reloadMessageShown: boolean = false;
@@ -35,7 +35,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<CppToo
util.setProgress(0);
// Initialize the DebuggerExtension and register the related commands and providers.
DebuggerExtension.initialize();
DebuggerExtension.initialize(context);
await processRuntimeDependencies();
@@ -329,6 +329,7 @@ function rewriteManifest(): Promise<void> {
"onLanguage:c",
"onCommand:extension.pickNativeProcess",
"onCommand:extension.pickRemoteNativeProcess",
"onCommand:C_Cpp.BuildAndDebugActiveFile",
"onCommand:C_Cpp.ConfigurationEdit",
"onCommand:C_Cpp.ConfigurationSelect",
"onCommand:C_Cpp.ConfigurationProviderSelect",
@@ -0,0 +1,47 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as vscode from "vscode";
import * as path from 'path';
// import * as util from '../src/common' <- DO NOT USE. Also do not use anything with relative paths, it will break during replacing in test/integrationTests/debug/integration.test.ts
abstract class AbstractDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
protected readonly context: vscode.ExtensionContext;
constructor(context: vscode.ExtensionContext) {
this.context = context;
}
abstract createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor>;
}
export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
public static DEBUG_TYPE : string = "cppdbg";
constructor(context: vscode.ExtensionContext) {
super(context);
}
createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
console.warn("This should only appear in a test scenario.");
return new vscode.DebugAdapterExecutable('node', [path.join(this.context.extensionPath, './out/test/integrationTests/MockDebugger/mockDebug.js')]);
}
}
export class CppvsdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
public static DEBUG_TYPE : string = "cppvsdbg";
constructor(context: vscode.ExtensionContext) {
super(context);
}
createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
console.warn("This should only appear in a test scenario.");
return new vscode.DebugAdapterExecutable('node', [path.join(this.context.extensionPath, './out/test/integrationTests/MockDebugger/mockDebug.js')]);
}
}
@@ -0,0 +1,8 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { MockDebugSession } from './mockDebugSession';
MockDebugSession.run(MockDebugSession);
@@ -0,0 +1,67 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { Logger, logger, LoggingDebugSession, InitializedEvent, TerminatedEvent } from 'vscode-debugadapter';
import { DebugProtocol } from 'vscode-debugprotocol';
import { Subject } from 'await-notify';
interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
/** An absolute path to the "program" to debug. */
program: string;
/** enable logging the Debug Adapter Protocol */
logPath?: string;
}
export class MockDebugSession extends LoggingDebugSession
{
private _configurationDone = new Subject();
public constructor() {
super("mock-debug.txt");
}
protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
// build and return the capabilities of this debug adapter:
response.body = response.body || {};
// the adapter implements the configurationDoneRequest.
response.body.supportsConfigurationDoneRequest = true;
this.sendResponse(response);
// since this debug adapter can accept configuration requests like 'setBreakpoint' at any time,
// we request them early by sending an 'initializeRequest' to the frontend.
// The frontend will end the configuration sequence by calling 'configurationDone' request.
this.sendEvent(new InitializedEvent());
}
protected configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void {
super.configurationDoneRequest(response, args);
// notify the launchRequest that configuration has finished
this._configurationDone.notify();
}
protected async launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments) {
// make sure to 'Stop' the buffered logging if 'trace' is not set
logger.setup(Logger.LogLevel.Verbose, args.logPath);
// wait until configuration has finished (and configurationDoneRequest has been called)
await this._configurationDone.wait(1000);
this.sendResponse(response);
// Terminate after launch.
this.sendEvent(new TerminatedEvent());
}
protected async disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments)
{
this.sendResponse(response);
}
}
@@ -0,0 +1,44 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as fs from "fs";
import * as path from 'path';
import { subscribeToAllLoggers } from "../../../src/logger";
//
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
//
// This file is providing the test runner to use when running extension tests.
// By default the test runner in use is Mocha based.
// git status
// You can provide your own test runner if you want to override it by exporting
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
// host can call to run the tests. The test runner is expected to use console.log
// to report the results back to the caller. When the tests are finished, return
// a possible error to the callback or null if none.
var testRunner = require('vscode/lib/testrunner');
// You can directly control Mocha options by uncommenting the following lines
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
testRunner.configure({
ui: 'tdd', // the TDD UI is being used in *.test.ts (suite, test, etc.)
useColors: true, // colored output from test results
fullTrace: true,
timeout: 60000
});
const logFolder = path.join( __dirname, ".logs")
if (!fs.existsSync(logFolder)) {
fs.mkdirSync(logFolder);
}
const logFilePath = path.join(logFolder, "integrationTests.log");
subscribeToAllLoggers(message => fs.appendFileSync(logFilePath, message));
module.exports = testRunner;
@@ -7,14 +7,19 @@ import * as vscode from 'vscode';
import * as assert from 'assert';
suite(`Debug Integration Test: `, function(): void {
suiteSetup(async function(): Promise<void> {
let origFactoryFile: string;
let tempFactoryFile: string;
let hijackedFactoryFile: string;
suiteSetup(async function(): Promise<void> {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
}
});
});
test("Starting (gdb) Launch from the workspace root should create an Active Debug Session", async () => {
test("Starting (gdb) Launch from the workspace root should create an Active Debug Session", async function() {
// If it is failing on startDebugging. Investigate the SimpleCppProject's tasks.json or launch.json.
await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], "(gdb) Launch");
let debugSessionTerminated: Promise<void> = new Promise(resolve => {
@@ -7,7 +7,7 @@
import * as fs from "fs";
import * as path from 'path';
import { subscribeToAllLoggers } from "../../src/logger";
import { subscribeToAllLoggers } from "../../../src/logger";
//
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
@@ -26,8 +26,9 @@ var testRunner = require('vscode/lib/testrunner');
// You can directly control Mocha options by uncommenting the following lines
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
testRunner.configure({
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
useColors: true, // colored output from test results
ui: 'tdd', // the TDD UI is being used in *.test.ts (suite, test, etc.)
useColors: true, // colored output from test results
fullTrace: true,
timeout: 60000
});
@@ -5,13 +5,13 @@
import * as vscode from 'vscode';
import * as assert from 'assert';
import { getLanguageConfigFromPatterns } from '../../src/LanguageServer/languageConfig';
import * as util from '../../src/common';
import { getLanguageConfigFromPatterns } from '../../../src/LanguageServer/languageConfig';
import * as util from '../../../src/common';
import * as api from 'vscode-cpptools';
import * as apit from 'vscode-cpptools/out/testApi';
import * as config from '../../src/LanguageServer/configurations';
import { CppSettings } from '../../src/LanguageServer/settings';
import { getActiveClient } from '../../src/LanguageServer/extension';
import * as config from '../../../src/LanguageServer/configurations';
import { CppSettings } from '../../../src/LanguageServer/settings';
import { getActiveClient } from '../../../src/LanguageServer/extension';
suite("multiline comment setting tests", function(): void {
suiteSetup(async function(): Promise<void> {
@@ -5,15 +5,12 @@
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/program",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
@@ -22,10 +19,17 @@
}
],
"windows": {
"MIMode": "gdb",
"miDebuggerPath": "C:\\MinGW\\bin\\gdb.exe"
},
"osx": {
"miDebuggerPath": "/usr/bin/lldb"
"MIMode": "lldb",
"preLaunchTask": "build"
},
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"preLaunchTask": "build"
}
}
]
+4 -4
View File
@@ -345,12 +345,12 @@
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
@@ -511,12 +511,12 @@
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcess}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
+17
View File
@@ -0,0 +1,17 @@
name: $(Date:yyyyMMdd).$(Rev:.r)
pr:
- 'master'
jobs:
- template: Extension/jobs/build.yml
parameters:
name: macOS
pool:
vmImage: 'macOS-10.13'
- template: Extension/jobs/build.yml
parameters:
name: Linux
pool:
vmImage: 'ubuntu-16.04'
- template: Extension/jobs/build.windows.yml