Compare commits
63
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
717de54b06 | ||
|
|
51cd214f1e | ||
|
|
4ca9ad8b3a | ||
|
|
8aadd40a58 | ||
|
|
0c61ee96b7 | ||
|
|
e020801dac | ||
|
|
270a4f7d38 | ||
|
|
342de46452 | ||
|
|
cd0dde9e27 | ||
|
|
79f8262d26 | ||
|
|
24b69c7873 | ||
|
|
260124b39b | ||
|
|
2426a66be4 | ||
|
|
6f5c9e362b | ||
|
|
868799af10 | ||
|
|
01d013723f | ||
|
|
1a8e84bca3 | ||
|
|
3db3c8da9a | ||
|
|
670a105c1f | ||
|
|
5445eff250 | ||
|
|
95dd5386ed | ||
|
|
55120359a4 | ||
|
|
bb2d23c694 | ||
|
|
15ac01d70c | ||
|
|
0c77b9e6cf | ||
|
|
c39579010b | ||
|
|
e928bfb0a9 | ||
|
|
1d47bc4160 | ||
|
|
3d7937feeb | ||
|
|
98260f96ea | ||
|
|
8d96465cb6 | ||
|
|
ece90711fb | ||
|
|
361ca45b50 | ||
|
|
28e8f1f2ed | ||
|
|
d27e609d92 | ||
|
|
fdcbfee87c | ||
|
|
bda5bbf89c | ||
|
|
50ddd670c7 | ||
|
|
cc81b4bb8f | ||
|
|
a0f6eb61ad | ||
|
|
10a06af93d | ||
|
|
b28ab0a874 | ||
|
|
f1ca548849 | ||
|
|
f860223723 | ||
|
|
e2aaababc4 | ||
|
|
49aa55261f | ||
|
|
035d0284d9 | ||
|
|
f216e0262a | ||
|
|
da277c8593 | ||
|
|
b3cce807bb | ||
|
|
a533eb9a43 | ||
|
|
9702eae953 | ||
|
|
a4b51997ff | ||
|
|
b1274d3c76 | ||
|
|
8f8565dbfd | ||
|
|
7f4614c31c | ||
|
|
e231453778 | ||
|
|
8729804dc2 | ||
|
|
0cf237c839 | ||
|
|
ddc1f901c2 | ||
|
|
9ca27af2df | ||
|
|
082435ec8b | ||
|
|
324c5f59f4 |
-43
@@ -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
@@ -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
@@ -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 haven’t 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 haven’t already provided us feedback, please take this [quick survey](https://www.research.net/r/VBVV6C6) and let us know what you think!
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -112,9 +112,11 @@
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
@@ -156,5 +158,6 @@
|
||||
"required": [
|
||||
"configurations",
|
||||
"version"
|
||||
]
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Generated
+194
-87
@@ -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
@@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "生成和调试当前文件"
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
+8
-3
@@ -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 => {
|
||||
+4
-3
@@ -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
-5
@@ -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> {
|
||||
+8
-4
@@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user