Compare commits

..
3 Commits
Author SHA1 Message Date
Sean McManus e5976d2656 Merge pull request #1557 from Microsoft/master
Merge for release.
2018-02-14 16:55:56 -08:00
Pierson Lee (PIE) cdab065ded Merge remote-tracking branch 'origin/master' into release 2018-01-17 13:09:00 -08:00
Sean McManus 3f62c3d244 Merge pull request #1458 from Microsoft/master
0.14.6 release
2018-01-16 15:51:11 -08:00
61 changed files with 1376 additions and 3827 deletions
+6 -4
View File
@@ -31,11 +31,13 @@ script:
# 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 compile
- npm run test
# Dump integrationTest.log output
after_failure:
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
after_success:
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
+1 -1
View File
@@ -2,7 +2,7 @@
## Contribution Steps
* [Build and debug the extension](Documentation/Building%20the%20Extension.md).
* [Build and debug the extension](Documentation/Getting%20started.md#build-and-debug-the-cpptools-extension).
* File an [issue](https://github.com/Microsoft/vscode-cpptools/issues) and a [pull request](https://github.com/Microsoft/vscode-cpptools/pulls) with the change and we will review it.
* If the change affects functionality, add a line describing the change to [**CHANGELOG.md**](Extension/CHANGELOG.md).
* Try and add a test in [**test/extension.test.ts**](Extension/test/unitTests/extension.test.ts).
+2 -2
View File
@@ -4,7 +4,7 @@
"version": "2.0.0",
"tasks": [
{
"label": "clang++",
"taskName": "clang++",
"command": "clang++ --debug -o main.exe main.cpp",
// "--debug" enables debugging symbols
// "-o main.exe" specifies the output executable
@@ -16,4 +16,4 @@
}
}
]
}
}
@@ -1,16 +0,0 @@
#### Old information (it still works, but is no longer recommended):
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Note:** You will likely need to reload the window or close VS Code to flush the contents of the log file since we do not flush the log after every call. If your log file seems to be empty, try reloading the window after you have followed the steps to reproduce your issue.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
@@ -1,76 +0,0 @@
## Extension version 0.16.1 and earlier:
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
In earlier versions of the extension, the `includePath` and a some system defines need to be set in order for IntelliSense to work properly. Note that you may have to change the MinGW version number to match what you have installed. Eg. `C:/MinGW/lib/gcc/mingw32/5.3.0/` instead of `C:/MinGW/lib/gcc/mingw32/6.3.0/`.
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/backward",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `"gcc -v -E -x c++ nul"`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
@@ -1,139 +0,0 @@
# Windows Subsystem for Linux
To use the Windows Subsystem for Linux with this extension you need to add a configuration to your **c_cpp_properties.json** file which adds the necessary header paths from within the WSL filesystem to the `includePath`.
Select "C/Cpp: Edit Configurations" from the command palette to create the **c_cpp_properties.json** file if you haven't already.
## Release
For developers using Ubuntu with the current version of WSL released with the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
### Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
---
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -1,99 +0,0 @@
# Customizing Default Settings
In version 0.17.0 we introduced new settings that allow you to override the extension's default values for properties set in **c_cpp_properties.json**.
## New VS Code settings
The following `C_Cpp.default.*` settings map to each of the properties in a configuration block of **c_cpp_properties.json**. Namely:
```
C_Cpp.default.includePath : string[]
C_Cpp.default.defines : string[]
C_Cpp.default.compileCommands : string
C_Cpp.default.macFrameworkPath : string[]
C_Cpp.default.forcedIncludes : string[]
C_Cpp.default.intelliSenseMode : string
C_Cpp.default.compilerPath : string
C_Cpp.default.cStandard : c89 | c99 | c11
C_Cpp.default.cppStandard : c++98 | c++03 | c++11 | c++14 | c++17
C_Cpp.default.browse.path : string[]
C_Cpp.default.browse.databaseFilename : string
C_Cpp.default.browse.limitSymbolsToIncludedHeaders : boolean
```
These settings have all of the benefits of VS Code settings, meaning that they can have default, "User", "Workspace", and "Folder" values. So you can set a global value for `C_Cpp.default.cppStandard` in your "User" settings and have it apply to all of the folders you open. If any one folder needs a different value, you can override the value by adding a "Folder" or "Workspace" value.
This property of VS Code settings allows you to configure each of your workspaces independently - making the **c_cpp_properties.json** file optional.
## Updated **c_cpp_properties.json** syntax
A special variable has been added to the accepted syntax of **c_cpp_properties.json** that will instruct the extension to insert the value from the VS Code settings mentioned above. If you set the value of any setting in **c_cpp_properties.json** to "${default}" it will instruct the extension to read the VS Code default setting for that property and insert it. For example:
```
"configurations": [
{
"name": "Win32",
"includePath": [
"additional/paths",
"${default}"
],
"defines": [
"${default}",
],
"macFrameworkPath": [
"${default}",
"additional/paths"
],
"forceInclude": [
"${default}",
"additional/paths"
],
"compileCommands": "${default}",
"browse": {
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "${default}",
"path": [
"${default}",
"additional/paths"
]
},
"intelliSenseMode": "${default}",
"cStandard": "${default}",
"cppStandard": "${default}",
"compilerPath": "${default}"
}
],
```
Take note that for the properties that accept string[], the syntax proposed above allows you to augment the VS Code setting with additional values, thus allowing you to have common paths listed in the VS Code settings and configuration-specific settings in **c_cpp_properties.json**.
If a property is missing from **c_cpp_properties.json**, the extension will use the value in the VS Code setting. If a developer assigns values to all of the settings that apply for a given folder, then **c_cpp_properties.json** could be removed from the .vscode folder as it will no longer be needed.
### System includes
A new setting will be added that allows you specify the system include path separate from the folder's include path. If this setting has a value, then the system include path the extension gets from the compiler specified in the `compilerPath` setting will not be added to the path array that the extension uses for IntelliSense. We may want to provide a VS Code command to populate this value from the compiler's default for users who are interested in using it in case they want to make some modifications to the defaults.
```
C_Cpp.default.systemIncludePath : string[]
```
### Include Path Resolution Strategies
The extension determines the includePath to send to the IntelliSense engine in the following manner:
1. If `compileCommands` has a valid value and the file open in the editor is in the database, use the compile command in the database entry to determine the include path and defines.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to seach for system defines).
2. If `compilerPath` is valid, query it.
3. Interpret the first argument in the command as the compiler and attempt to query it.
4. If `compilerPath` is `""`, use an empty array for system include path and defines.
5. If `compilerPath` is undefined, look for a compiler on the system and query it.
2. If `compileCommands` is invalid or the current file is not listed in the database, use the `includePath` and `defines` properties in the configuration for IntelliSense.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to seach for system defines).
2. If `compilerPath` is valid, query it.
3. If `compilerPath` is `""`, use an empty array for system include path and defines (they are assumed to be in the `includePath` and `defines` for the current config already).
4. If `compilerPath` is undefined, look for a compiler on the system and query it.
System includes should no longer be added to the `"includePath"` or `"browse.path"` variables. If the extension detects any system include paths in the `"includePath"` property it will silently remove them so that it can ensure system include paths are added last and in the correct order (this is especially important for GCC/Clang). In a future update we may add a notification message to the extension to remind developers to remove system include paths from their `"includePath"` and `'browse.path"` as they will be ignored.
@@ -6,7 +6,19 @@ As of version 0.14.0 of the extension, logging information is now delivered dire
![image](https://user-images.githubusercontent.com/12818240/31898313-b32ff284-b7cd-11e7-97f5-89df93b5d9de.png)
VS Code organizes the logging from different extensions to improve readability so you must select the "C/C++" option in the log filter selector to see logging from the C/C++ extension:
#### Old information (it still works, but is no longer recommended):
![image](https://user-images.githubusercontent.com/12818240/39769357-d6673bea-52a0-11e8-86c6-3be91618e8fc.png)
<del>
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
</del>
+2 -14
View File
@@ -3,7 +3,6 @@
* [How do I get IntelliSense to work correctly?](#how-do-i-get-intellisense-to-work-correctly)
* [Why do I see red squiggles under Standard Library types?](#why-do-i-see-red-squiggles-under-standard-library-types)
* [How do I get the new IntelliSense to work with MinGW on Windows?](#how-do-i-get-the-new-intellisense-to-work-with-mingw-on-windows)
* [How do I get the new IntelliSense to work with the Windows Subsystem for Linux?](#how-do-i-get-the-new-intellisense-to-work-with-the-windows-subsystem-for-linux)
* [What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?](#what-is-the-difference-between-includepath-and-browsepath-in-c_cpp_propertiesjson)
* [How do I re-create the IntelliSense database?](#how-do-i-re-create-the-intellisense-database)
@@ -28,22 +27,11 @@ If you want IntelliSense to operate on your files even when all #include directi
## Why do I see red squiggles under Standard Library types?
The most common reason for this is missing include paths and defines. The easiest way to fix this on each platform is as follows:
**Linux/Mac**
* Set `"intelliSenseMode": "clang-x64"` and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
**Windows**
* If you are using a Microsoft compiler from Visual Studio, set `"intelliSenseMode": "msvc-x64"`, but don't add the `"compilerPath"` property to **c_cpp_properties.json**.
* If you are using Clang for Windows, set `"intelliSenseMode": "msvc-x64"`, and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
The most common reason for this is missing or sorted include paths. If you are using a compiler in the GCC family, the system includes that you add to your `"includePath"` in **c_cpp_properties.json** should match the output of the following command: `gcc -Wp,-v -E -xc -x c++ /dev/null` (replace 'gcc' with whichever compiler you are using). GCC and its relatives require the paths to be in a specific order too, so sorting the paths for aesthetics will likely result in incorrect IntelliSense results.
## How do I get the new IntelliSense to work with MinGW on Windows?
The page discussing configuration with MinGW is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
## How do I get the new IntelliSense to work with the Windows Subsystem for Linux?
The page discussing configuration with WSL is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/Windows%20Subsystem%20for%20Linux.md).
Since MinGW is a relative of GCC, Microsoft mode compilation (which is the default on Windows) doesn't work very well with it. To use GCC/CLang mode, set the `"intelliSenseMode"` property in your **c_cpp_properties.json** file to `"clang-x64"`. An example **c_cpp_properties.json** [is shared here for your convenience](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
## What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?
+68 -24
View File
@@ -1,32 +1,76 @@
# MinGW
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
To use MinGW on Windows, we recommend you add the following configuration to your **c_cpp_properties.json** file. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
## Extension version 0.17.0 and higher:
When you set the `compilerPath` property and change `intelliSenseMode` to `clang-x64`, you no longer need to copy the system include path or defines to `includePath`, `browse.path`, or `defines` to enable IntelliSense to work properly. For example:
Note that you may have to change the MinGW version number to match what you have installed. Eg. `C:/MinGW/lib/gcc/mingw32/5.3.0/` instead of `C:/MinGW/lib/gcc/mingw32/6.3.0/`.
```json
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"compilerPath": "C:/mingw64/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"defines": [],
"browse": {
"path": [
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/backward",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"UNICODE",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
## Extension version 0.16.1 and earlier:
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `gcc -v -E -x c++ -`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
If you have an older version of the C/C++ extension installed, use [these instructions](Archive/MinGW.md) instead.
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"UNICODE",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
@@ -1,43 +1,139 @@
# Windows Subsystem for Linux
> **Note:** If you are on **build 17110 of Windows or higher**, you must use version 0.17.0 or higher for IntelliSense to work. The Windows team turned on case-sensitive folders for the WSL environment and the C/C++ extension doesn't support case-sensitive folders until version 0.17.0.
To use the Windows Subsystem for Linux with this extension you need to add a configuration to your **c_cpp_properties.json** file which adds the necessary header paths from within the WSL filesystem to the `includePath`.
Select "C/Cpp: Edit Configurations" from the command palette to create the **c_cpp_properties.json** file if you haven't already.
## With extension version 0.17.0 and higher:
## Release
In **c_cpp_properties.json** you can directly address your WSL compiler and include paths by using *nix-style paths and we will do the conversion to Windows paths for you. If you have multiple distros installed, we disambiguate the `compilerPath` by picking the one marked as Default when you run `wslconfig.exe /l` in a CMD or PowerShell window. We continue to support Windows-style paths for these properties as outlined in the [archived instructions](Archive/Windows%20Subsystem%20for%20Linux.md) if you prefer to use those.
For developers using Ubuntu with the current version of WSL released with the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"compilerPath": "/usr/bin/gcc",
"includePath": [
"${workspaceFolder}",
"/mnt/c/libraries/lib1/include",
"C:/libraries/lib2/include"
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"defines": [],
"browse": {
"path": [
"${workspaceFolder}",
"/mnt/c/libraries"
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
}
```
## Earlier versions of the extension:
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
If you are on a build of Windows prior to 17110 and you have an older version of the C/C++ extension installed, use [these instructions](Archive/Windows%20Subsystem%20for%20Linux.md) instead.
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
## Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
---
Remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -1,46 +1,29 @@
# `c_cpp_properties.json` Reference Guide
> See also: [Customizing Default Settings](Customizing%20Default%20Settings.md)
### Example
```json
{
"env" : {
"defaultIncludePath": [
"${workspaceFolder}",
"${workspaceFolder}/include"
],
"myCompilerPath": "/usr/local/bin/gcc-7"
},
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "msvc-x64",
"includePath": [ "${defaultIncludePath}", "/another/path" ],
"macFrameworkPath": [ "/System/Library/Frameworks" ],
"includePath": [ "${workspaceRoot}" ],
"defines": [ "FOO", "BAR=100" ],
"forcedInclude": [ "${workspaceFolder}/include/config.h" ],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"compileCommands": "/path/to/compile_commands.json",
"browse": {
"path": [ "${workspaceFolder}" ],
"path": [ "${workspaceRoot}" ],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
"version": 2
}
```
## Top-level properties
* #### `env`
An array of user-defined variables that will be available for substitution in the configurations via the standard environment variable syntax: `${<var>}` or `${env:<var>}`. Strings and arrays of strings are accepted.
* #### `configurations`
An array of configuration objects that provide the IntelliSense engine with information about your project and your preferences. By default, the extension creates 3 configurations for you, one each for Linux, Mac, and Windows, but it is not required to keep them all. You may also add additional configurations if necessary.
@@ -56,30 +39,15 @@
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this property determines which mode the IntelliSense engine will run in. `"msvc-x64"` maps to Visual Studio mode with 64-bit pointer sizes. `"clang-x64"` maps to GCC/CLang mode with 64-bit pointer sizes. Windows uses `"msvc-x64"` by default and Linux/Mac use `"clang-x64"` by default.
* #### `includePath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch; the IntelliSense engine will not do a recursive search in these paths for includes. If a GCC/CLang compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
* #### `macFrameworkPath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for framework headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-F` switch; the IntelliSense engine will not do a recursive search in these paths for includes.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch; the IntelliSense engine will not do a recursive search in these paths for includes.
* #### `defines`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of preprocessor symbols will be used by IntelliSense during the compilation of your source files. This is basically the same as the list of symbols you pass to your compiler with the `-D` switch.
* #### `forcedInclude` (optional)
A list of files that should be included before any other characters in the source file are processed. Files are included in the order listed.
* #### `compilerPath` (optional)
The absolute path to the compiler you use to build your project. The extension will query the compiler to determine the system include paths and default defines to use for IntelliSense. Args can be added to modify the includes/defines used, e.g. `-nostdinc++`, `-m32`, etc., but paths with spaces must be surrounded by double quotes (`"`) if args are used.
* #### `cStandard`
The C standard revision to use for IntelliSense in your project.
* #### `cppStandard`
The C++ standard revision to use for IntelliSense in your project.
* #### `compileCommands` (optional)
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, the includes and defines discovered in this file will be used instead of the values set for `includePath` and `defines`. If the compile commands database does not contain an entry for the translation unit that corresponds to the file you opened in the editor, then a warning message will appear and the extension will use the `includePath` and `defines` settings instead.
>For more information about the file format, see the [Clang documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html). Some build systems, such as CMake, [simplify generating this file](https://cmake.org/cmake/help/v3.5/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html).
*For more information about the file format, see the [Clang documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html). Some build systems, such as CMake, [simplify generating this file](https://cmake.org/cmake/help/v3.5/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html).*
* #### `browse`
The set of properties used when `"C_Cpp.intelliSenseEngine"` is set to `"Tag Parser"` (also referred to as "fuzzy" IntelliSense, or the "browse" engine). These properties are also used by the Go To Definition/Declaration features, or when the "Default" IntelliSense engine is unable to resolve the #includes in your source files.
@@ -90,7 +58,7 @@
This list of paths will be used by the Tag Parser to search for headers included by your source files. The Tag Parser will automatically search all subfolders in these paths unless the path ends with a `/*` or `\*`. For example, `/usr/include` directs the Tag Parser to search the `include` folder and its subfolders for headers while `/usr/include/*` directs the Tag Parser not to look in any subfolders of `/usr/include`.
* #### `limitSymbolsToIncludedHeaders`
When true, the Tag Parser will only parse code files that have been directly or indirectly included by a source file in `${workspaceFolder}`. When false, the Tag Parser will parse all code files found in the paths specified in the **path** list.
When true, the Tag Parser will only parse code files that have been directly or indirectly included by a source file in `${workspaceRoot}`. When false, the Tag Parser will parse all code files found in the paths specified in the **path** list.
* #### `databaseFilename`
When set, this instructs the extension to save the Tag Parser's symbol database somewhere other than the workspace's default storage location. If a relative path is specified, it will be made relative to the workspace's default storage location, not the workspace folder itself. The `${workspaceFolder}` variable can be used to specify a path relative to the workspace folder (e.g. `${workspaceFolder}/.vscode/browse.vc.db`)
When set, this instructs the extension to save the Tag Parser's symbol database somewhere other than the workspace's default storage location. If a relative path is specified, it will be made relative to the workspace's default storage location, not the workspace folder itself. The `${workspaceRoot}` variable can be used to specify a path relative to the workspace folder (e.g. `$[workspaceRoot}/.vscode/browse.vc.db`)
+22 -31
View File
@@ -7,31 +7,22 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "compile",
"outFiles": ["${workspaceRoot}/out/src"],
"preLaunchTask": "npm"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test"
],
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "compile"
"outFiles": ["${workspaceRoot}/out/test"],
"preLaunchTask": "npm"
},
{
"name": "Node Attach",
@@ -40,20 +31,20 @@
"port": 5858
},
{
"name": "Launch Integration Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/integrationTests/testAssets/SimpleCppProject",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/integrationTests"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
]
},
"name": "Launch Integration Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceRoot}/test/integrationTests/testAssets/SimpleCppProject",
"--extensionDevelopmentPath=${workspaceRoot}",
"--extensionTestsPath=${workspaceRoot}/out/test/integrationTests"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/out/test/**/*.js"
]
},
]
}
}
+28 -58
View File
@@ -1,60 +1,30 @@
// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team
// ${file}: the current opened file
// ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname
// ${fileExtname}: the current opened file's extension
// ${cwd}: the current working directory of the spawned process
// A task runner that calls a custom npm script that compiles the extension.
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "TypeScript Compile",
"identifier": "compile",
"group": {
"kind": "build",
"isDefault": true
},
"isBackground": true,
"type": "shell",
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared"
},
"command": "npm",
"args": [
"run",
"compile",
"--loglevel",
"silent"
],
"problemMatcher": "$tsc-watch"
},
{
"label": "TypeScript Lint",
"identifier": "tslint",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "npm",
"args": [
"run",
"tslint"
],
"problemMatcher": {
"fileLocation": "absolute",
"source": "tslint",
"pattern": [
{
"regexp": "(ERROR:) ([a-zA-Z/:\\-\\.]*)\\[(\\d+), (\\d+)\\]: (.*)",
"severity": 1,
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
]
},
"dependsOn": [
"compile"
]
}
]
"version": "0.1.0",
// we want to run npm
"command": "npm",
// the command is a shell script
"isShellCommand": true,
// show the output window only if unrecognized errors occur.
"showOutput": "silent",
// we run the custom script "compile" as defined in package.json
"args": ["run", "compile", "--loglevel", "silent"],
// The tsc compiler is started in watching mode
"isWatching": true,
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
"problemMatcher": "$tsc-watch"
}
-1
View File
@@ -11,5 +11,4 @@ CMakeLists.txt
debugAdapters/install.lock*
out/src/Debugger/copyScript.js
tools/**
out/tools/**
notices/**
+1 -56
View File
@@ -1,64 +1,9 @@
# C/C++ for Visual Studio Code Change Log
## Version 0.17.1: May 17, 2018
* Fix IntelliSense update slowness when using recursive includes. [#1949](https://github.com/Microsoft/vscode-cpptools/issues/1949)
* Fix code navigation failure after switching between WSL and non-WSL configs. [#1958](https://github.com/Microsoft/vscode-cpptools/issues/1958)
* Fix extension crash when the `includePath` is a file or the root drive. [#1979](https://github.com/Microsoft/vscode-cpptools/issues/1979), [#1965](https://github.com/Microsoft/vscode-cpptools/issues/1965)
* Fix IntelliSense crash in `have_member_access_from_class_scope`. [#1763](https://github.com/Microsoft/vscode-cpptools/issues/1763)
* Fix `#include` completion bugs. [#1959](https://github.com/Microsoft/vscode-cpptools/issues/1959), [#1970](https://github.com/Microsoft/vscode-cpptools/issues/1970)
* Add `Debug` value for `loggingLevel` (previously the hidden value `"6"`).
* Fix C++17 features not being fully enabled with msvc-x64 mode. [#1990](https://github.com/Microsoft/vscode-cpptools/issues/1990)
* Fix IntelliSense interprocess deadlocks. [#1407](https://github.com/Microsoft/vscode-cpptools/issues/1407), [#1777](https://github.com/Microsoft/vscode-cpptools/issues/1777)
## Version 0.17.0: May 7, 2018
* Auto-complete for headers after typing `#include`. [#802](https://github.com/Microsoft/vscode-cpptools/issues/802)
* Add support for recursive `includePath`, e.g. `${workspaceFolder}/**`. [#897](https://github.com/Microsoft/vscode-cpptools/issues/897)
* Configuration improvements. [#1338](https://github.com/Microsoft/vscode-cpptools/issues/1338)
* Potentially addresses: [#368](https://github.com/Microsoft/vscode-cpptools/issues/368), [#410](https://github.com/Microsoft/vscode-cpptools/issues/410), [#1229](https://github.com/Microsoft/vscode-cpptools/issues/1229), [#1270](https://github.com/Microsoft/vscode-cpptools/issues/1270), [#1404](https://github.com/Microsoft/vscode-cpptools/issues/1404)
* Add support for querying system includes/defines from WSL and Cygwin compilers. [#1845](https://github.com/Microsoft/vscode-cpptools/issues/1845), [#1736](https://github.com/Microsoft/vscode-cpptools/issues/1736)
* Fix IntelliSense for WSL projects in Windows builds 17110 and greater. [#1694](https://github.com/Microsoft/vscode-cpptools/issues/1694)
* Add snippets. [PR #1823](https://github.com/Microsoft/vscode-cpptools/pull/1823)
* Add support for vcpkg. [PR #1886](https://github.com/Microsoft/vscode-cpptools/pull/1886)
* Add support for custom variables in `c_cpp_properties.json` via `env`. [#1857](https://github.com/Microsoft/vscode-cpptools/issues/1857), [#368](https://github.com/Microsoft/vscode-cpptools/issues/368)
* Stop automatically adding `/usr/include` to the `includePath`. [#1819](https://github.com/Microsoft/vscode-cpptools/issues/1819)
* Fix wrong configuration being used if there are four or more. [#1599](https://github.com/Microsoft/vscode-cpptools/issues/1599)
* Fix `c_cpp_properties.json` requiring write access. [#1790](https://github.com/Microsoft/vscode-cpptools/issues/1790)
* Change file not found in `compile_commands.json` message from an error to a warning. [#1783](https://github.com/Microsoft/vscode-cpptools/issues/1783)
* Fix an IntelliSense crash during completion requests. [#1782](https://github.com/Microsoft/vscode-cpptools/issues/1782)
* Update the installed clang-format to 6.0.
* Fix bug with `compile_commands.json` when "arguments" have both a switch and a value in the arg. [#1890](https://github.com/Microsoft/vscode-cpptools/issues/1890)
* Fix bug with garbage data appearing in tooltips on Linux/Mac. [#1577](https://github.com/Microsoft/vscode-cpptools/issues/1577)
## Version 0.16.1: March 30, 2018
* Fix random deadlock caused by logging code on Linux/Mac. [#1759](https://github.com/Microsoft/vscode-cpptools/issues/1759)
* Fix compiler from `compileCommands` not being queried for includes/defines if `compilerPath` isn't set on Windows. [#1754](https://github.com/Microsoft/vscode-cpptools/issues/1754)
* Fix OSX `UseShellExecute` I/O bug. [#1756](https://github.com/Microsoft/vscode-cpptools/issues/1756)
* Invalidate partially unzipped files from package manager. [#1757](https://github.com/Microsoft/vscode-cpptools/issues/1757)
## Version 0.16.0: March 28, 2018
* Enable autocomplete for local and global scopes. [#13](https://github.com/Microsoft/vscode-cpptools/issues/13)
* Add a setting to define multiline comment patterns: `C_Cpp.commentContinuationPatterns`. [#1100](https://github.com/Microsoft/vscode-cpptools/issues/1100), [#1539](https://github.com/Microsoft/vscode-cpptools/issues/1539)
* Add a setting to disable inactive region highlighting: `C_Cpp.dimInactiveRegions`. [#1592](https://github.com/Microsoft/vscode-cpptools/issues/1592)
* Add `forcedInclude` configuration setting. [#852](https://github.com/Microsoft/vscode-cpptools/issues/852)
* Add `compilerPath`, `cStandard`, and `cppStandard` configuration settings, and query gcc/clang-based compilers for default defines. [#1293](https://github.com/Microsoft/vscode-cpptools/issues/1293), [#1251](https://github.com/Microsoft/vscode-cpptools/issues/1251), [#1448](https://github.com/Microsoft/vscode-cpptools/issues/1448), [#1465](https://github.com/Microsoft/vscode-cpptools/issues/1465), [#1484](https://github.com/Microsoft/vscode-cpptools/issues/1484)
* Fix text being temporarily gray when an inactive region is deleted. [Microsoft/vscode#44872](https://github.com/Microsoft/vscode/issues/44872)
* Add support for `${workspaceFolder}` variable in **c_cpp_properties.json**. [#1392](https://github.com/Microsoft/vscode-cpptools/issues/1392)
* Fix IntelliSense not updating in source files after dependent header files are changed. [#1501](https://github.com/Microsoft/vscode-cpptools/issues/1501)
* Change database icon to use the `statusBar.foreground` color. [#1638](https://github.com/Microsoft/vscode-cpptools/issues/1638)
* Enable C++/CLI IntelliSense mode via adding the `/clr` arg to the `compilerPath`. [#1596](https://github.com/Microsoft/vscode-cpptools/issues/1596)
* Fix delay in language service activation caused by **cpptools.json** downloading. [#1640](https://github.com/Microsoft/vscode-cpptools/issues/1640)
* Fix debugger failure when a single quote is in the path. [#1554](https://github.com/Microsoft/vscode-cpptools/issues/1554)
* Fix terminal stdout and stderr redirection to not send to VS Code. [#1348](https://github.com/Microsoft/vscode-cpptools/issues/1348)
* Fix blank config and endless "Initializing..." if the file watcher limit is hit when using `compileCommands`. [PR #1709](https://github.com/Microsoft/vscode-cpptools/pull/1709)
* Fix error squiggles re-appearing after editing then closing a file. [#1712](https://github.com/Microsoft/vscode-cpptools/issues/1712)
* Show error output from clang-format. [#1259](https://github.com/Microsoft/vscode-cpptools/issues/1259)
* Fix `add_expression_to_index` crash (most frequent crash in 0.15.0). [#1396](https://github.com/Microsoft/vscode-cpptools/issues/1396)
* Fix incorrect error squiggle `explicitly instantiated more than once`. [#871](https://github.com/Microsoft/vscode-cpptools/issues/871)
## Version 0.15.0: February 15, 2018
* Add colorization for inactive regions. [#1466](https://github.com/Microsoft/vscode-cpptools/issues/1466)
* Fix 3 highest hitting crashes. [#1137](https://github.com/Microsoft/vscode-cpptools/issues/1137), [#1337](https://github.com/Microsoft/vscode-cpptools/issues/1337), [#1497](https://github.com/Microsoft/vscode-cpptools/issues/1497)
* Update IntelliSense compiler (bug fixes and more C++17 support). [#1067](https://github.com/Microsoft/vscode-cpptools/issues/1067), [#1313](https://github.com/Microsoft/vscode-cpptools/issues/1313)
* Update IntelliSense compiler (bug fixes and more C++17 support). [#1067](https://github.com/Microsoft/vscode-cpptools/issues/1067), [#1313](https://github.com/Microsoft/vscode-cpptools/issues/1313), [#1461](https://github.com/Microsoft/vscode-cpptools/issues/1461)
* Fix duplicate `cannot open source file` errors. [#1469](https://github.com/Microsoft/vscode-cpptools/issues/1469)
* Fix `Go to Symbol in File...` being slow for large workspaces. [#1472](https://github.com/Microsoft/vscode-cpptools/issues/1472)
* Fix stuck processes during shutdown. [#1474](https://github.com/Microsoft/vscode-cpptools/issues/1474)
+49 -174
View File
@@ -1,203 +1,78 @@
MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS
MICROSOFT C/C++ EXTENSION FOR VISUAL STUDIO CODE
# License
These license terms are an agreement between Microsoft Corporation (or
based on where you live, one of its affiliates) and you. They apply to
the pre-release software named above. The terms also apply to any
Microsoft services or updates for the software, except to the extent
those have additional terms.
**MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS**
**MICROSOFT C/C++ EXTENSION FOR VISUAL STUDIO CODE**
IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
---
These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the pre-release software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have additional terms.
1. INSTALLATION AND USE RIGHTS. You may only use the C/C++ Extension
for Visual Studio Code with Visual Studio Code, Visual Studio or
Xamarin Studio software to help you develop and test your
applications.
---
**IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.**
2. TERMS FOR SPECIFIC COMPONENTS
a. Third Party Components. The software may include third party
components with separate legal notices or governed by other
agreements, as may be described in the ThirdPartyNotices file(s)
accompanying the software.
b. Package Managers. The software may include package managers, like
Nuget, that give you the option to download other Microsoft and third
party software packages to use with your application. Those packages
are under their own licenses, and not this agreement. Microsoft does
not distribute, license or provide any warranties for any of the third
party packages.
1. **INSTALLATION AND USE RIGHTS.**
You may only use the C/C++ Extension for Visual Studio Code with Visual Studio Code, Visual Studio or Xamarin Studio software to help you develop and test your applications.
3. DATA.
a. Data Collection. The software may collect information about you and
your use of the software, and send that to Microsoft. Microsoft may
use this information to provide services and improve our products and
services. You may opt-out of many of these scenarios, but not all, as
described in the product documentation. There are also some features
in the software that may enable you and Microsoft to collect data from
users of your applications. If you use these features, you must comply
with applicable law, including providing appropriate notices to users
of your applications together with a copy of Microsofts privacy
statement. Our privacy statement is located at
https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more
about data collection and use in the help documentation and our
privacy statement. Your use of the software operates as your consent
to these practices.
b. Processing of Personal Data. To the extent Microsoft is a processor
or subprocessor of personal data in connection with the software,
Microsoft makes the commitments in the European Union General Data
Protection Regulation Terms of the Online Services Terms to all
customers effective May 25, 2018, at
http://go.microsoft.com/?linkid=9840733.
2. **TERMS FOR SPECIFIC COMPONENTS.**
**a. Third Party components.** The software may include third party components with separate legal notices or governed by other agreements, as described in the ThirdPartyNotices file accompanying the software. Even if such components are governed by other agreements, the disclaimers and the limitations on and exclusions of damages below also apply.
**b. Package Managers.** The software may include package managers, like Nuget, that give you the option to download other Microsoft and third party software packages to use with your application. Those packages are under their own licenses, and not this agreement. Microsoft does not distribute, license or provide any warranties for any of the third party packages.
4. PRE-RELEASE SOFTWARE. This software is a pre-release version. It
may not work the way a final version of the software will. We may
change it for the final, commercial version. We also may not release a
commercial version.
3. **DATA**. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you to collect data from users of your applications. If you use these features to enable data collection in your applications, you must comply with applicable law, including providing appropriate notices to users of your applications. You can learn more about data collection and use in the help documentation and the privacy statement at https://go.microsoft.com/fwlink/?LinkID=528096. Your use of the software operates as your consent to these practices.
5. FEEDBACK. If you give feedback about the software to Microsoft, you
give to Microsoft, without charge, the right to use, share and
commercialize your feedback in any way and for any purpose. You will
not give feedback that is subject to a license that requires Microsoft
to license its software or documentation to third parties because we
include your feedback in them. These rights survive this agreement.
4. **PRE-RELEASE SOFTWARE**. This software is a pre-release version. It may not work the way a final version of the software will. We may change it for the final, commercial version. We also may not release a commercial version.
6. SCOPE OF LICENSE. The software is licensed, not sold. This
agreement only gives you some rights to use the software. Microsoft
reserves all other rights. Unless applicable law gives you more rights
despite this limitation, you may use the software only as expressly
permitted in this agreement. In doing so, you must comply with any
technical limitations in the software that only allow you to use it in
certain ways. You may not
* work around any technical limitations in the software;
* reverse engineer, decompile or disassemble the software, or attempt
to derive the source code for the software, except and to the extent
required by third party licensing terms governing use of certain open
source components that may be included with the software;
* remove, minimize, block or modify any notices of Microsoft or its
suppliers in the software;
* use the software in any way that is against the law; or
* share, publish, rent, or lease the software, or provide the software
as a stand-alone hosted solution for others to use.
5. **FEEDBACK**. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because we include your feedback in them. These rights survive this agreement.
7. EXPORT RESTRICTIONS. You must comply with all domestic and
international export laws and regulations that apply to the software,
which include restrictions on destinations, end users and end use.
For further information on export restrictions, visit
(aka.ms/exporting).
6. **SCOPE OF LICENSE**. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. For more information, see http://www.microsoftvolumelicensing.com/. You may not
* work around any technical limitations in the software;
* reverse engineer, decompile or disassemble the software, or attempt to do so, except and only to the extent required by third party licensing terms governing use of certain open-source components that may be included with the software;
* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
* use the software in any way that is against the law; or
* share, publish, rent, or lease the software, or provide the software as a stand-alone hosted as solution for others to use.
8. SUPPORT SERVICES. Because this software is “as is,” we may not
provide support services for it.
7. **EXPORT RESTRICTIONS.** You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users and end use. For further information on export restrictions, visit https://aka.ms/exporting.
9. ENTIRE AGREEMENT. This agreement, and the terms for supplements,
updates, Internet-based services and support services that you use,
are the entire agreement for the software and support services.
8. **SUPPORT SERVICES.** Because this software is “as is,” we may not provide support services for it.
10. APPLICABLE LAW. If you acquired the software in the United
States, Washington law applies to interpretation of and claims for
breach of this agreement, and the laws of the state where you live
apply to all other claims. If you acquired the software in any other
country, its laws apply.
9. **ENTIRE AGREEMENT.** This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
11. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes
certain legal rights. You may have other rights, including consumer
rights, under the laws of your state or country. Separate and apart
from your relationship with Microsoft, you may also have rights with
respect to the party from which you acquired the software. This
agreement does not change those other rights if the laws of your state
or country do not permit it to do so. For example, if you acquired the
software in one of the below regions, or mandatory country law
applies, then the following provisions apply to you:
10. **APPLICABLE LAW.** If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
a. Australia. You have statutory guarantees under the Australian
Consumer Law and nothing in this agreement is intended to affect those
rights.
11. **CONSUMER RIGHTS; REGIONAL VARIATIONS.** This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
b. Canada. If you acquired this software in Canada, you may stop
receiving updates by turning off the automatic update feature,
disconnecting your device from the Internet (if and when you re-
connect to the Internet, however, the software will resume checking
for and installing updates), or uninstalling the software. The product
documentation, if any, may also specify how to turn off updates for
your specific device or software.
**a. Australia.** You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
c. Germany and Austria.
(i) Warranty. The properly licensed software will perform
substantially as described in any Microsoft materials that accompany
the software. However, Microsoft gives no contractual guarantee in
relation to the licensed software.
(ii) Limitation of Liability. In case of intentional conduct, gross
negligence, claims based on the Product Liability Act, as well as, in
case of death or personal or physical injury, Microsoft is liable
according to the statutory law.
Subject to the foregoing clause (ii), Microsoft will only be liable
for slight negligence if Microsoft is in breach of such material
contractual obligations, the fulfillment of which facilitate the due
performance of this agreement, the breach of which would endanger the
purpose of this agreement and the compliance with which a party may
constantly trust in (so-called "cardinal obligations"). In other cases
of slight negligence, Microsoft will not be liable for slight
negligence.
**b. Canada.** If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
12. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU
BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES,
GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL
LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
**c. Germany and Austria.**
13. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU
CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST
PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
**(i)** **Warranty**. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
This limitation applies to (a) anything related to the software,
services, content (including code) on third party Internet sites, or
third party applications; and (b) claims for breach of contract,
breach of warranty, guarantee or condition, strict liability,
negligence, or other tort to the extent permitted by applicable law.
**(ii)** **Limitation of Liability**. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
It also applies even if Microsoft knew or should have known about the
possibility of the damages. The above limitation or exclusion may not
apply to you because your country may not allow the exclusion or
limitation of incidental, consequential or other damages.
Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
Please note: As this software is distributed in Quebec, Canada, some
of the clauses in this agreement are provided below in French.
12. **DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.**
Remarque : Ce logiciel étant distribué au Québec, Canada, certaines
des clauses dans ce contrat sont fournies ci-dessous en français.
13. **LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.**
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert
« tel quel ». Toute utilisation de ce logiciel est à votre seule
risque et péril. Microsoft naccorde aucune autre garantie
expresse. Vous pouvez bénéficier de droits additionnels en vertu du
droit local sur la protection des consommateurs, que ce contrat ne
peut modifier. La ou elles sont permises par le droit locale, les
garanties implicites de qualité marchande, dadéquation à un
usage particulier et dabsence de contrefaçon sont exclues.
This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ
POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses
fournisseurs une indemnisation en cas de dommages directs uniquement
à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune
indemnisation pour les autres dommages, y compris les dommages
spéciaux, indirects ou accessoires et pertes de bénéfices.
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
**Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.**
**Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.**
**EXONÉRATION DE GARANTIE.** Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft naccorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, dadéquation à un usage particulier et dabsence de contrefaçon sont exclues.
**LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.** Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
Cette limitation concerne:
* tout ce qui est relié au logiciel, aux services ou au contenu (y
compris le code) figurant sur des sites Internet tiers ou dans des
programmes tiers ; et
* les réclamations au titre de violation de contrat ou de garantie,
ou au titre de responsabilité stricte, de négligence ou dune
autre faute dans la limite autorisée par la loi en vigueur.
* tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
Elle sapplique également, même si Microsoft connaissait ou
devrait connaître l’éventualité dun tel dommage. Si votre pays
nautorise pas lexclusion ou la limitation de responsabilité
pour les dommages indirects, accessoires ou de quelque nature que ce
soit, il se peut que la limitation ou lexclusion ci-dessus ne
sappliquera pas à votre égard.
* les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou dune autre faute dans la limite autorisée par la loi en vigueur.
EFFET JURIDIQUE. Le présent contrat décrit certains droits
juridiques. Vous pourriez avoir dautres droits prévus par les lois
de votre pays. Le présent contrat ne modifie pas les droits que vous
confèrent les lois de votre pays si celles-ci ne le permettent pas.
Elle sapplique également, même si Microsoft connaissait ou devrait connaître l’éventualité dun tel dommage. Si votre pays nautorise pas lexclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou lexclusion ci-dessus ne sappliquera pas à votre égard.
**EFFET JURIDIQUE.** Le présent contrat décrit certains droits juridiques. Vous pourriez avoir dautres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
+5 -8
View File
@@ -205,11 +205,8 @@
<tr>
<td>
<div>
<h2 class="caption">April 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the April update, we added autocomplete suggestions for <code>#include</code> statements.<br/>
<br/>
We also added settings for configuration defaults and made some changes to improve the automatic configuration experience. If you set the <code>"compilerPath"</code>
property in c_cpp_properties.json, you no longer need to add system includes and defines to <code>"includePath"</code> or <code>"defines"</code><br />
<h2 class="caption">February 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the February update, we added colorization around inactive preprocessor blocks. We also accepted our first pull requests from the community. Thanks for helping to make our extension better!<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>
@@ -223,7 +220,7 @@
<td>
<div>
<h3 class="caption">Getting Started</h3>
<div><a href="https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started%20with%20IntelliSense%20configuration.md">Configuring IntelliSense</a></div>
<div><a href="https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started.md">Configuring IntelliSense</a></div>
<div><a href="https://github.com/Microsoft/vscode-cpptools/blob/master/launch.md">Configuring Debugging</a></div>
<div><a href="https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md">IntelliSense for MinGW projects</a></div>
<div><a href="https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/Windows%20Subsystem%20for%20Linux.md">IntelliSense for Windows Subsystem for Linux projects</a></div>
@@ -234,9 +231,9 @@
<td>
<div>
<h3 class="caption">Blog Posts</h3>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/03/29/visual-studio-code-cc-extension-march-2018-update/">March 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/02/20/visual-studio-code-cc-extension-feb-2018-update/">February 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/01/17/visual-studio-code-cc-extension-jan-2018-update/">January 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2017/12/11/visual-studio-code-cc-extension-dec-2017-update-support-for-more-linux-distros/">December 2017 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2017/11/09/visual-studio-code-cc-extension-nov-2017-update-multi-root-workspaces-support-is-here/">November 2017 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>
</td>
+33 -39
View File
@@ -7,41 +7,40 @@ Microsoft C/C++ Extension for Visual Studio Code incorporates components from th
1. agent-base (https://github.com/TooTallNate/node-agent-base)
2. ANTLR (http://www.antlr2.org/)
3. Boost (http://www.boost.org)
4. C++11 Sublime Text Snippets (https://github.com/Rapptz/cpp-sublime-snippet)
5. Clang (https://clang.llvm.org/)
6. debug (https://github.com/visionmedia/debug)
7. extend (https://github.com/justmoon/node-extend)
8. fd-slicer (https://github.com/andrewrk/node-fd-slicer)
9. gcc-6/libgcc (http://packages.ubuntu.com/yakkety/main/gcc-6)
10. Guidelines Support Library (https://github.com/Microsoft/GSL)
11. http-proxy-agent (https://github.com/TooTallNate/node-http-proxy-agent)
12. https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
13. jsonc-parser (https://github.com/Microsoft/node-jsonc-parser)
14. libc++ (https://libcxx.llvm.org/index.html)
15. LLDB (https://lldb.llvm.org/)
16. LLVM (http://llvm.org/)
17. MI Debug Engine (https://github.com/Microsoft/MIEngine)
18. Minimatch (https://github.com/isaacs/minimatch)
19. minimist (https://github.com/substack/minimist)
20. mkdirp (https://github.com/substack/node-mkdirp)
21. Mono (https://github.com/mono/mono)
22. ms (https://github.com/rauchg/ms.js)
23. msgpack for C/C++ (https://github.com/msgpack/msgpack-c)
24. node-http-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
25. node-https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
26. os-tmpdir (https://github.com/sindresorhus/os-tmpdir)
27. Pend (https://github.com/andrewrk/node-pend)
28. pevents (https://github.com/neosmart/pevents)
29. RapidJSON (https://github.com/miloyip/rapidjson)
30. semver (https://github.com/npm/node-semver)
31. SQLite (https://www.sqlite.org/)
4. Clang (https://clang.llvm.org/)
5. debug (https://github.com/visionmedia/debug)
6. extend (https://github.com/justmoon/node-extend)
7. fd-slicer (https://github.com/andrewrk/node-fd-slicer)
8. gcc-6/libgcc (http://packages.ubuntu.com/yakkety/main/gcc-6)
9. Guidelines Support Library (https://github.com/Microsoft/GSL)
10. http-proxy-agent (https://github.com/TooTallNate/node-http-proxy-agent)
11. https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
12. jsonc-parser (https://github.com/Microsoft/node-jsonc-parser)
13. libc++ (https://libcxx.llvm.org/index.html)
14. LLDB (https://lldb.llvm.org/)
15. LLVM (http://llvm.org/)
16. MI Debug Engine (https://github.com/Microsoft/MIEngine)
17. Minimatch (https://github.com/isaacs/minimatch)
18. minimist (https://github.com/substack/minimist)
19. mkdirp (https://github.com/substack/node-mkdirp)
20. Mono (https://github.com/mono/mono)
21. ms (https://github.com/rauchg/ms.js)
22. msgpack for C/C++ (https://github.com/msgpack/msgpack-c)
23. node-http-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
24. node-https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
25. os-tmpdir (https://github.com/sindresorhus/os-tmpdir)
26. Pend (https://github.com/andrewrk/node-pend)
27. pevents (https://github.com/neosmart/pevents)
28. RapidJSON (https://github.com/miloyip/rapidjson)
29. semver (https://github.com/npm/node-semver)
30. SQLite (https://www.sqlite.org/)
Includes:functions (from fossil) (https://fossil-scm.org)
32. Tmp (https://github.com/raszi/node-tmp)
31. Tmp (https://github.com/raszi/node-tmp)
Includes:sample code (https://blog.tompawlak.org/generate-random-values-nodejs-javascript)
33 vscode-debugadapter (https://github.com/Microsoft/vscode-debugadapter-node)
34. vscode-extension-telemetry (https://github.com/Microsoft/vscode-extension-telemetry)
35. vscode-languageserver-node (https://github.com/Microsoft/vscode-languageserver-node)
36. yauzl (https://github.com/thejoshwolfe/yauzl)
32. vscode-debugadapter (https://github.com/Microsoft/vscode-debugadapter-node)
33. vscode-extension-telemetry (https://github.com/Microsoft/vscode-extension-telemetry)
34. vscode-languageserver-node (https://github.com/Microsoft/vscode-languageserver-node)
35. yauzl (https://github.com/thejoshwolfe/yauzl)
%% agent-base NOTICES AND INFORMATION BEGIN HERE
@@ -1413,11 +1412,6 @@ SOFTWARE.
=========================================
END OF yauzl NOTICES AND INFORMATION
%% C++11 Sublime Text Snippets NOTICES AND INFORMATION BEGIN HERE
=========================================
C++ Snippets for Sublime Text (https://packagecontrol.io/packages/C%2B%2B%20Snippets)
Individual snippets based on those from the C++ Snippets for Sublime Text collection are licensed under CC0 1.0 Universal
=========================================
END OF C++11 Sublime Text Snippets NOTICES AND INFORMATION
+3 -3
View File
@@ -4,11 +4,11 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1914",
"1900",
"--pack_alignment",
"8",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_BUILD=0",
"-D_M_IX86=600",
"-D_M_IX86_FP=2"
+2 -1
View File
@@ -2,7 +2,8 @@
"defaults": [
"--clang",
"--pack_alignment",
"8"
"8",
"-D__CHAR_BIT__=8"
],
"defaults_op" : "merge"
}
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1914",
"1900",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+2 -1
View File
@@ -2,7 +2,8 @@
"defaults": [
"--clang",
"--pack_alignment",
"8"
"8",
"-D__CHAR_BIT__=8"
],
"defaults_op" : "merge"
}
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1914",
"1900",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+2 -1
View File
@@ -2,7 +2,8 @@
"defaults": [
"--clang",
"--pack_alignment",
"8"
"8",
"-D__CHAR_BIT__=8"
],
"defaults_op" : "merge"
}
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1914",
"1900",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+8
View File
@@ -28,6 +28,14 @@
{
"match": "^/dE--header_only_fallback",
"replace": "--header_only_fallback"
},
{
"match": "^/lang_c_",
"replace": "--c\n--c11"
},
{
"match": "^/lang_cpp_",
"replace": "--c++17"
}
]
}
+10 -70
View File
@@ -11,38 +11,12 @@
],
"properties": {
"name": {
"description": "Configuration identifier. Mac, Linux, and Win32 are special identifiers for configurations that will be auto-selected on those platforms, but the identifier can be anything.",
"description": "Platform name. Mac, Linux, or Win32 are the defaults unless a custom platform is added.",
"type": "string"
},
"compilerPath": {
"description": "Full path of the compiler being used, e.g. /usr/bin/gcc, to enable more accurate IntelliSense. Args can be added to modify the includes/defines used, e.g. -nostdinc++, -m32, etc., but paths with spaces must be surrounded with \\\" if args are used.",
"type": "string"
},
"cStandard": {
"description": "Version of the C language standard to use for IntelliSense.",
"type": "string",
"enum": [
"c89",
"c99",
"c11",
"${default}"
]
},
"cppStandard": {
"description": "Version of the C++ language standard to use for IntelliSense.",
"type": "string",
"enum": [
"c++98",
"c++03",
"c++11",
"c++14",
"c++17",
"${default}"
]
},
"compileCommands": {
"description": "Full path to compile_commands.json file for the workspace.",
"type": "string"
"compileCommands":{
"description": "path to compile_commands.json file for the workspace",
"type":"string"
},
"includePath": {
"description": "A list of paths for the IntelliSense engine to use while searching for included headers. Searching on these paths is not recursive.",
@@ -66,30 +40,19 @@
}
},
"intelliSenseMode": {
"description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64 and Linux/Mac default to clang-x64.",
"type": "string",
"enum": [
"msvc-x64",
"clang-x64",
"${default}"
]
},
"forcedInclude": {
"description": "A list of files that should be included before any include file in a translation unit.",
"type": "array",
"items": {
"type": "string"
}
"clang-x64"
],
"description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64 and Linux/Mac default to clang-x64."
},
"browse": {
"type": "object",
"properties": {
"limitSymbolsToIncludedHeaders": {
"description": "true to process only those files directly or indirectly included as headers, false to process all files under the specified include paths.",
"type": [
"boolean",
"string"
]
"description": "true to process only those files directly or indirectly included as headers, false to process all files under the specified include paths",
"type": "boolean"
},
"databaseFilename": {
"description": "Path to the generated symbol database. If a relative path is specified, it will be made relative to the workspace's default storage location.",
@@ -107,26 +70,6 @@
}
}
},
"env": {
"type": "object",
"description": "Custom variables that can be reused anywhere in this file using the ${variable} or ${env:variable} syntax.",
"patternProperties": {
"(?!^workspaceFolder$)(?!^workspaceRoot$)(?!^default$)(^.+$)": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
},
"additionalProperties": false
},
"version": {
"type": "integer",
"description": "Version of the configuration file. This property is managed by the extension. Please do not change it."
@@ -136,9 +79,6 @@
"configurations": {
"$ref": "#/definitions/configurations"
},
"env": {
"$ref": "#/definitions/env"
},
"version": {
"$ref": "#/definitions/version"
}
@@ -147,4 +87,4 @@
"configurations",
"version"
]
}
}
-140
View File
@@ -1,140 +0,0 @@
{
"class": {
"prefix": "class",
"body": "\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\t${2:/* data */}\npublic:\n\t${1}(${3:/* args */});\n\t~${1}();\n};\n\n${1}::${1}(${3})\n{\n}\n\n${1}::~${1}()\n{\n}\n",
"description": "Code snippet for class",
"scope": "source.c++, source.objc++"
},
"classi": {
"prefix": "classi",
"body": "\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\t${2:/* data */}\npublic:\n\t${1}(${3:/* args */}) { $0}\n\t~${1}() { }\n};",
"description": "Code snippet for class with inlined constructor/destructor",
"scope": "source.c++, source.objc++"
},
"classt": {
"prefix": "classt",
"body": "\ntemplate<typename T>\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\tT ${2:/* data */}\npublic:\n\t${1}(T ${3:/* args */});\n};\n",
"description": "Code snippet for class template",
"scope": "source.c++, source.objc++"
},
"struct": {
"prefix": "struct",
"body": "\nstruct ${1:${TM_FILENAME_BASE}}\n{\n\t${0:/* data */}\n};\n",
"description": "Code snippet for struct",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"union": {
"prefix": "union",
"body": "\nunion ${1:${TM_FILENAME_BASE}}\n{\n\t${0:/* data */}\n};\n",
"description": "Code snippet for union",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"if": {
"prefix": "if",
"body": "\nif (${1:/* condition */}) {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifel": {
"prefix": "ifel",
"body": "\nif (${1:/* condition */}) {\n\t${2:/* code */}\n}\nelse {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if() else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifelif": {
"prefix": "ifelif",
"body": "\nif (${1:/* condition */}) {\n\t${2:/* code */}\n}\nelse if(${3:/* condition */}) {\n\t${4:/* code */}\n}\nelse {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if() else if() else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"else": {
"prefix": "else",
"body": "\nelse\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"elif": {
"prefix": "elif",
"body": "\nelse if (${1:/* condition */})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for else if ()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"switch": {
"prefix": "switch",
"body": "\nswitch (${1:expression})\n{\n\tcase ${2:/* constant-expression */}:\n\t\t${3:/* code */}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n}",
"description": "Code snippet for switch",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"main": {
"prefix": "main",
"body": "\nint main(int argc, char const *argv[])\n{\n\t${1:/* code */}\n\treturn 0;\n}\n",
"description": "Code snippet for main()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"do": {
"prefix": "do_",
"body": "\ndo\n{\n\t${0:/* code */}\n} while (${1:/* condition */});\n",
"description": "Code snippet for do while loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"for": {
"prefix": "for",
"body": "\nfor(${1:size_t} ${2:i} = 0; $2 < ${3:count}; ${4:$2++})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for for loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"forr": {
"prefix": "forr",
"body": "\nfor(int ${1:i} = ${2:length} - 1; $1 >= 0; ${3:$1--})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for reverse for loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"foreach": {
"prefix": "foreach",
"body": "\nfor(${1:object} = ${2:var} in ${3:collection})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for foreach loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"forrange": {
"prefix": "forrange",
"body": "\nfor(auto&& ${1:i} : ${2:v})\n{\n\t$0\n}\n",
"description": "Code snippet for range-based forloop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"while": {
"prefix": "while",
"body": "\nwhile(${1:/* condition */}){\n\t${2:/* code */}\n}\n",
"description": "Code snippet for while loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifd": {
"prefix": "ifnd",
"body": "\n#if defined($1)\n\n${0}\n\n#endif // $1\n",
"description": "Code snippet for if defined()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifnd": {
"prefix": "ifnd",
"body": "\n#if !defined($1)\n#define ${1:MACRO}\n\n${0}\n\n#endif // $1\n",
"description": "Code snippet for if !defined()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"mitl": {
"prefix": "mitl",
"body": "\n// The MIT License (MIT)\n\n// Copyright (c) ${1:YEAR} ${2:NAME}\n\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the \"Software\"),\n// to deal in the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n${0:/* code */}\n",
"description": "Code snippet for MIT License",
"scope": ""
},
"namesp": {
"prefix": "namesp",
"body": "\nnamespace ${1:name}\n{\n\t$0\n} // $1\n",
"description": "Code snippet for namespace",
"scope": "source.c++, source.objc++"
},
"try": {
"prefix": "try",
"body": "\ntry\n{\n\t${1:/* code */}\n}\ncatch(${2:const std::exception& e})\n{\n\t${0:std::cerr << e.what() << '\\n';}\n}\n",
"description": "Code snippet for try catch block",
"scope": "source.c++, source.objc++, source.c++11"
}
}
-15
View File
@@ -9,8 +9,6 @@ const gulp = require('gulp');
const env = require('gulp-env')
const tslint = require('gulp-tslint');
const mocha = require('gulp-mocha');
const fs = require('fs');
const optionsSchemaGenerator = require('./out/tools/GenerateOptionsSchema');
gulp.task('allTests', () => {
gulp.start('unitTests');
@@ -52,7 +50,6 @@ gulp.task('integrationTests', () => {
/// Misc Tasks
const allTypeScript = [
'src/**/*.ts',
'tools/**/*.ts',
'!**/*.d.ts',
'!**/typings**'
];
@@ -76,16 +73,4 @@ gulp.task('tslint', () => {
summarizeFailureOutput: false,
emitError: false
}))
});
gulp.task('pr-check', () => {
const packageJson = JSON.parse(fs.readFileSync('./package.json').toString());
if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') {
console.log('Please make sure to not check in package.json that has been rewritten by the extension activation. If you intended to have changes in package.json, please only check-in your changes. If you did not, please run `git checkout -- package.json`.');
process.exit(1);
}
});
gulp.task('generateOptionsSchema', () => {
optionsSchemaGenerator.GenerateOptionsSchema();
});
+423 -216
View File
File diff suppressed because it is too large Load Diff
+45 -284
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "0.17.1-master",
"version": "0.15.0",
"publisher": "ms-vscode",
"preview": true,
"icon": "LanguageCCPP_color_128x.png",
@@ -12,7 +12,7 @@
},
"license": "SEE LICENSE IN LICENSE.txt",
"engines": {
"vscode": "^1.22.0"
"vscode": "^1.17.0"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-cpptools/issues",
@@ -32,11 +32,10 @@
"multi-root ready"
],
"categories": [
"Programming Languages",
"Languages",
"Debuggers",
"Formatters",
"Linters",
"Snippets"
"Linters"
],
"activationEvents": [
"*"
@@ -140,12 +139,6 @@
"description": "Controls whether suspected compile errors detected by the IntelliSense engine will be reported back to the editor. Warnings about #includes that could not be located will always be reported to the editor. This setting is ignored by the Tag Parser engine.",
"scope": "resource"
},
"C_Cpp.dimInactiveRegions": {
"type": "boolean",
"default": true,
"description": "Controls whether inactive preprocessor blocks are colored differently than active code. This setting is ignored by the Tag Parser engine.",
"scope": "resource"
},
"C_Cpp.formatting": {
"type": "string",
"enum": [
@@ -168,11 +161,10 @@
"None",
"Error",
"Warning",
"Information",
"Debug"
"Information"
],
"default": "Error",
"description": "The verbosity of logging in the Output Panel. The order of levels from least verbose to most verbose is: None < Error < Warning < Information < Debug.",
"description": "The verbosity of logging in the Output Panel. The order of levels from least verbose to most verbose is: None < Error < Warning < Information.",
"scope": "resource"
},
"C_Cpp.autoAddFileAssociations": {
@@ -202,193 +194,6 @@
"default": "checkFolders",
"description": "Instructs the extension when to use the \"files.exclude\" setting when determining which files should be added to the code navigation database while traversing through the paths in the \"browse.path\" array. \"checkFolders\" means that the exclusion filters will only be evaluated once per folder (individual files are not checked). \"checkFilesAndFolders\" means that the exclusion filters will be evaluated against every file and folder encountered. If your \"files.exclude\" setting only contains folders, then \"checkFolders\" is the best choice and will increase the speed at which the extension can initialize the code navigation database.",
"scope": "resource"
},
"C_Cpp.preferredPathSeparator": {
"type": "string",
"enum": [
"Forward Slash",
"Backslash"
],
"default": "Forward Slash",
"description": "The character used as a path separator for #include auto-completion results.",
"scope": "resource"
},
"C_Cpp.commentContinuationPatterns": {
"type": "array",
"default": [
"/**"
],
"items": {
"anyOf": [
{
"type": "string",
"description": "The pattern that begins a multiline or single line comment block. The continuation pattern defaults to ' * ' for multiline comment blocks or this string for single line comment blocks."
},
{
"type": "object",
"properties": {
"begin": {
"type": "string",
"description": "The pattern that begins a multiline or single line comment block."
},
"continue": {
"type": "string",
"description": "The text that will be inserted on the next line when Enter is pressed inside a multiline or single line comment block."
}
}
}
]
},
"description": "Defines the editor behavior for when the Enter key is pressed inside a multiline or single line comment block.",
"scope": "resource"
},
"C_Cpp.default.includePath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"includePath\" is not specified, or the values to insert if \"${default}\" is present in \"includePath\".",
"scope": "resource"
},
"C_Cpp.default.defines": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"defines\" is not specified, or the values to insert if \"${default}\" is present in \"defines\".",
"scope": "resource"
},
"C_Cpp.default.macFrameworkPath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"macFrameworkPath\" is not specified, or the values to insert if \"${default}\" is present in \"macFrameworkPath\".",
"scope": "resource"
},
"C_Cpp.default.compileCommands": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"compileCommands\" is either not specified, or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.forcedInclude": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"forcedInclude\" is not specified, or the values to insert if \"${default}\" is present in \"forcedInclude\".",
"scope": "resource"
},
"C_Cpp.default.intelliSenseMode": {
"type": [
"string",
"null"
],
"enum": [
"msvc-x64",
"clang-x64"
],
"default": null,
"description": "The value to use in a configuration if \"intelliSenseMode\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.compilerPath": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"compilerPath\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.cStandard": {
"type": [
"string",
"null"
],
"enum": [
"c89",
"c99",
"c11"
],
"default": null,
"description": "The value to use in a configuration if \"cStandard\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.cppStandard": {
"type": [
"string",
"null"
],
"enum": [
"c++98",
"c++03",
"c++11",
"c++14",
"c++17"
],
"default": null,
"description": "The value to use in a configuration if \"cppStandard\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.browse.path": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"browse.path\" is not specified, or the values to insert if \"${default}\" is present in \"browse.path\".",
"scope": "resource"
},
"C_Cpp.default.browse.databaseFilename": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"browse.databaseFilename\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.browse.limitSymbolsToIncludedHeaders": {
"type": "boolean",
"default": true,
"description": "The value to use in a configuration if \"browse.limitSymbolsToIncludedHeaders\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.systemIncludePath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use for the system include path. If set, it overrides the system include path acquired via \"compilerPath\" and \"compileCommands\" settings.",
"scope": "resource"
}
}
},
@@ -423,11 +228,6 @@
"title": "Navigate...",
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleSnippets",
"title": "Toggle Snippets",
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleErrorSquiggles",
"title": "Toggle Error Squiggles",
@@ -439,9 +239,12 @@
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleDimInactiveRegions",
"title": "Toggle Inactive Region Colorization",
"category": "C/Cpp"
"command": "workbench.action.gotoSymbol",
"title": "Go to Symbol in File..."
},
{
"command": "workbench.action.showAllSymbols",
"title": "Go to Symbol in Workspace..."
},
{
"command": "C_Cpp.ShowReleaseNotes",
@@ -534,7 +337,6 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"required": [
"program"
],
@@ -586,7 +388,7 @@
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
"default": "false"
}
}
},
@@ -611,7 +413,7 @@
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
"default": ""
}
}
},
@@ -634,7 +436,7 @@
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
"default": "true"
},
"environment": {
"type": "array",
@@ -691,12 +493,12 @@
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
"default": "true"
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
"default": "false"
},
"serverLaunchTimeout": {
"type": "integer",
@@ -711,7 +513,7 @@
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched. Note this option is ignored in some cases for technical reasons.",
"default": false
"default": "false"
},
"sourceFileMap": {
"type": "object",
@@ -721,8 +523,8 @@
}
},
"logging": {
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
@@ -761,10 +563,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "/usr/bin",
"pipeCwd": "${workspaceRoot}",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
},
"properties": {
"pipeCwd": {
@@ -803,7 +605,6 @@
}
},
"attach": {
"type": "object",
"required": [
"program",
"processId"
@@ -832,7 +633,7 @@
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
"default": "true"
},
"additionalSOLibSearchPath": {
"type": "string",
@@ -871,12 +672,12 @@
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
"default": "true"
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
"default": "false"
},
"sourceFileMap": {
"type": "object",
@@ -886,8 +687,8 @@
}
},
"logging": {
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
@@ -926,10 +727,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "/usr/bin",
"pipeCwd": "${workspaceRoot}",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
},
"properties": {
"pipeCwd": {
@@ -964,31 +765,6 @@
"default": {}
}
}
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The debugger command to execute.",
"default": ""
},
"description": {
"type": "string",
"description": "Optional description for the command.",
"default": ""
},
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
}
}
},
"default": []
}
}
}
@@ -1010,7 +786,6 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"required": [
"program",
"cwd"
@@ -1074,7 +849,7 @@
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched.",
"default": false
"default": "false"
},
"sourceFileMap": {
"type": "object",
@@ -1113,7 +888,6 @@
}
},
"attach": {
"type": "object",
"required": [
"processId"
],
@@ -1263,49 +1037,36 @@
"[c]": {
"editor.autoIndent": false
}
},
"snippets": [
{
"language": "cpp",
"path": "./cpp_snippets.json"
},
{
"language": "c",
"path": "./cpp_snippets.json"
}
]
}
},
"scripts": {
"compile": "npm run vscode:prepublish",
"generateOptionsSchema": "gulp generateOptionsSchema",
"compile": "npm run vscode:prepublish && tsc -p ./",
"integrationTests": "gulp integrationTests",
"postinstall": "node ./node_modules/vscode/bin/install",
"pretest": "tsc -p ./",
"pr-check": "gulp pr-check",
"test": "gulp allTests",
"tslint": "gulp tslint",
"unitTests": "gulp unitTests",
"vscode:prepublish": "node ./src/Support/prepublish.js",
"vscode:prepublish": "npm install && tsc -p ./ && node ./out/src/Debugger/copyScript.js",
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.46",
"gulp": "3.9.1",
"gulp-env": "0.4.0",
"gulp-mocha": "5.0.0",
"gulp-tslint": "8.1.2",
"gulp": "3.9.1",
"mocha": "^4.0.1",
"tslint": "5.8.0",
"tslint-microsoft-contrib": "5.0.1",
"tslint-no-unused-expression-chai": "0.0.3",
"tslint": "5.8.0",
"typescript": "^2.5.3",
"vrsource-tslint-rules": "^5.8.2",
"vscode": "^1.1.17"
"vscode": "^1.1.6"
},
"dependencies": {
"http-proxy-agent": "~2.0.0",
"https-proxy-agent": "~2.2.0",
"https-proxy-agent": "~2.1.0",
"jsonc-parser": "^1.0.0",
"minimatch": "~3.0.4",
"mkdirp": "~0.5.1",
@@ -1313,13 +1074,13 @@
"vscode-debugadapter": "~1.24.0",
"vscode-debugprotocol": "~1.24.0",
"vscode-extension-telemetry": "~0.0.11",
"vscode-languageclient": "3.5.1",
"vscode-languageclient": "~3.4.5",
"yauzl": "~2.8.0"
},
"runtimeDependencies": [
{
"description": "C/C++ language components (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?linkid=874214",
"url": "https://go.microsoft.com/fwlink/?linkid=866913",
"platforms": [
"linux"
],
@@ -1333,7 +1094,7 @@
},
{
"description": "C/C++ language components (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?linkid=874215",
"url": "https://go.microsoft.com/fwlink/?linkid=866914",
"platforms": [
"linux"
],
@@ -1349,7 +1110,7 @@
},
{
"description": "C/C++ language components (OS X)",
"url": "https://go.microsoft.com/fwlink/?linkid=874216",
"url": "https://go.microsoft.com/fwlink/?linkid=866915",
"platforms": [
"darwin"
],
@@ -1360,7 +1121,7 @@
},
{
"description": "C/C++ language components (Windows)",
"url": "https://go.microsoft.com/fwlink/?linkid=874217",
"url": "https://go.microsoft.com/fwlink/?linkid=866916",
"platforms": [
"win32"
],
@@ -1368,7 +1129,7 @@
},
{
"description": "ClangFormat (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?LinkID=872607",
"url": "https://go.microsoft.com/fwlink/?LinkID=848955",
"platforms": [
"linux"
],
@@ -1381,7 +1142,7 @@
},
{
"description": "ClangFormat (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?LinkID=872608",
"url": "https://go.microsoft.com/fwlink/?LinkID=864640",
"platforms": [
"linux"
],
@@ -1396,7 +1157,7 @@
},
{
"description": "ClangFormat (OS X)",
"url": "https://go.microsoft.com/fwlink/?LinkID=872609",
"url": "https://go.microsoft.com/fwlink/?LinkID=848956",
"platforms": [
"darwin"
],
@@ -1406,7 +1167,7 @@
},
{
"description": "ClangFormat (Windows)",
"url": "https://go.microsoft.com/fwlink/?LinkID=872610",
"url": "https://go.microsoft.com/fwlink/?LinkID=848957",
"platforms": [
"win32"
],
@@ -1474,7 +1235,7 @@
},
{
"description": "Visual Studio Windows Debugger",
"url": "https://go.microsoft.com/fwlink/?linkid=872985",
"url": "https://go.microsoft.com/fwlink/?linkid=852926",
"platforms": [
"win32"
],
+4 -36
View File
@@ -3,15 +3,10 @@
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
import { execChildProcess } from '../common';
import { PsProcessParser } from './nativeAttach';
import * as debugUtils from './utils';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as util from '../common';
import * as vscode from 'vscode';
export interface AttachItem extends vscode.QuickPickItem {
id: string;
@@ -54,47 +49,20 @@ export class RemoteAttachPicker {
private _channel: vscode.OutputChannel = null;
public ShowAttachEntries(config: any): Promise<string> {
public ShowAttachEntries(args: any): Promise<string> {
return util.isExtensionReady().then(ready => {
if (!ready) {
util.displayExtensionNotReadyPrompt();
} else {
this._channel.clear();
let pipeTransport: any = config ? config.pipeTransport : null;
let pipeTransport: any = args ? args.pipeTransport : null;
if (pipeTransport === null) {
return Promise.reject<string>(new Error("Chosen debug configuration does not contain pipeTransport"));
}
let pipeProgram: string = null;
if (os.platform() === 'win32' &&
pipeTransport.pipeProgram &&
!fs.existsSync(pipeTransport.pipeProgram)) {
const pipeProgramStr: string = pipeTransport.pipeProgram.toLowerCase().trim();
const expectedArch: debugUtils.ArchType = debugUtils.ArchType[process.arch];
// Check for pipeProgram
if (!fs.existsSync(config.pipeTransport.pipeProgram)) {
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, expectedArch);
}
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
if (!pipeProgram && config.pipeTransport.pipeCwd) {
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
if (!fs.existsSync(newPipeProgramStr)) {
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, expectedArch);
}
}
}
if (!pipeProgram) {
pipeProgram = pipeTransport.pipeProgram;
}
let pipeProgram: string = pipeTransport.pipeProgram;
let pipeArgs: string[] = pipeTransport.pipeArgs;
let argList: string = RemoteAttachPicker.createArgumentList(pipeArgs);
@@ -3,11 +3,8 @@
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as debugUtils from './utils';
import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import { IConfiguration, IConfigurationSnippet, DebuggerType, MIConfigurations, WindowsConfigurations, WSLConfigurations, PipeTransportConfigurations } from './configurations';
import { parse } from 'jsonc-parser';
@@ -37,29 +34,6 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
return undefined;
}
// Modify WSL config for OpenDebugAD7
if (os.platform() === 'win32' &&
config.pipeTransport &&
config.pipeTransport.pipeProgram) {
let replacedPipeProgram: string = null;
const pipeProgramStr: string = config.pipeTransport.pipeProgram.toLowerCase().trim();
// OpenDebugAD7 is a 32-bit process. Make sure the WSL pipe transport is using the correct program.
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, debugUtils.ArchType.ia32);
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
if (!replacedPipeProgram && !path.isAbsolute(pipeProgramStr) && config.pipeTransport.pipeCwd) {
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, debugUtils.ArchType.ia32);
}
if (replacedPipeProgram) {
config.pipeTransport.pipeProgram = replacedPipeProgram;
}
}
return config;
}
}
+25 -27
View File
@@ -31,7 +31,7 @@ function formatString(format: string, args: string[]): string {
return format;
}
function createLaunchString(name: string, type: string, executable: string): string {
function CreateLaunchString(name: string, type: string, executable: string): string {
return `"name": "${name}",
"type": "${type}",
"request": "launch",
@@ -44,7 +44,7 @@ function createLaunchString(name: string, type: string, executable: string): str
`;
}
function createAttachString(name: string, type: string, executable: string): string {
function CreateAttachString(name: string, type: string, executable: string): string {
return formatString(`
"name": "${name}",
"type": "${type}",
@@ -53,7 +53,7 @@ function createAttachString(name: string, type: string, executable: string): str
`, [type === "cppdbg" ? `${os.EOL}"program": "${"enter program name, for example $\{workspaceFolder\}/" + executable}",` : ""]);
}
function createRemoteAttachString(name: string, type: string, executable: string): string {
function CreateRemoteAttachString(name: string, type: string, executable: string): string {
return `
"name": "${name}",
"type": "${type}",
@@ -63,12 +63,12 @@ function createRemoteAttachString(name: string, type: string, executable: string
`;
}
function createPipeTransportString(pipeProgram: string, debuggerProgram: string, pipeArgs: string[] = []): string {
function CreatePipeTransportString(pipeProgram: string, debuggerProgram: string): string {
return `
"pipeTransport": {
\t"debuggerPath": "/usr/bin/${debuggerProgram}",
\t"pipeProgram": "${pipeProgram}",
\t"pipeArgs": ${JSON.stringify(pipeArgs)},
\t"pipeArgs": [],
\t"pipeCwd": ""
}`;
}
@@ -106,7 +106,7 @@ export class MIConfigurations extends Configuration {
let name: string = `(${this.MIMode}) Launch`;
let body: string = formatString(`{
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -124,10 +124,9 @@ this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalPrope
let name: string = `(${this.MIMode}) Attach`;
let body: string = formatString(`{
\t${indentJsonString(createAttachString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
\t${indentJsonString(CreateAttachString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : ""]);
return {
"label": this.snippetPrefix + name,
@@ -146,8 +145,8 @@ export class PipeTransportConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -163,12 +162,12 @@ export class PipeTransportConfigurations extends Configuration {
public GetAttachConfiguration(): IConfigurationSnippet {
let name: string = `(${this.MIMode}) Pipe Attach`;
let body: string = formatString(`
let body: string = `
{
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
\t${indentJsonString(CreateRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"
}`;
return {
"label": this.snippetPrefix + name,
"description": `Pipe Attach with ${this.MIMode}.`,
@@ -186,7 +185,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(createLaunchString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(CreateLaunchString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -204,7 +203,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(createAttachString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(CreateAttachString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -218,16 +217,15 @@ export class WindowsConfigurations extends Configuration {
}
export class WSLConfigurations extends Configuration {
// Detects if the current VSCode is 32-bit and uses the correct bash.exe
public bashPipeProgram = process.arch === 'ia32' ? "${env:windir}\\\\sysnative\\\\bash.exe" : "${env:windir}\\\\system32\\\\bash.exe";
public bashPipeProgram = "C:\\\\Windows\\\\sysnative\\\\bash.exe";
public GetLaunchConfiguration(): IConfigurationSnippet {
let name: string = `(${this.MIMode}) Bash on Windows Launch`;
let body: string = formatString(`
{
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
@@ -241,11 +239,11 @@ export class WSLConfigurations extends Configuration {
public GetAttachConfiguration(): IConfigurationSnippet {
let name: string = `(${this.MIMode}) Bash on Windows Attach`;
let body: string = formatString(`
let body: string = `
{
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
\t${indentJsonString(CreateAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode))}
}`;
return {
"label": this.snippetPrefix + name,
@@ -81,7 +81,7 @@ function enableDevWorkflow(): Boolean {
return false;
}
return (EnableDevWorkflow || (process.env.CPPTOOLS_DEV !== undefined));
return (EnableDevWorkflow || (process.env.CPPTOOLS_DEV !== null));
}
function copySourceDependencies(): void {
@@ -200,6 +200,8 @@ function makeDirectory(dir: string): void {
}
}
let devWorkFlowMessage: string = '\nWARNING: If you are trying to build and run the extension locally, please set the environment variable CPPTOOLS_DEV=1 and try again.\n';
if (enableDevWorkflow()) {
removeFolder("./debugAdapters");
}
@@ -211,6 +213,5 @@ if (enableDevWorkflow()) {
copyMonoDependencies();
copyBinaryDependencies();
} else {
console.warn('WARNING: Debugger dependencies are missing.');
console.log('If you are trying to build and run the extension from source and need the debugger dependencies, set the environment variable CPPTOOLS_DEV=1 and try again.');
console.warn(devWorkFlowMessage);
}
-1
View File
@@ -34,7 +34,6 @@ export function initialize(): void {
configurationProvider.getConfigurationSnippets();
const launchJsonDocumentSelector: vscode.DocumentSelector = [{
scheme: 'file',
language: 'jsonc',
pattern: '**/launch.json'
}];
-49
View File
@@ -1,49 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
export enum ArchType {
ia32,
x64
}
export class ArchitectureReplacer {
public static checkAndReplaceWSLPipeProgram(pipeProgramStr: string, expectedArch: ArchType): string {
let replacedPipeProgram: string = null;
const winDir: string = process.env.WINDIR ? process.env.WINDIR.toLowerCase() : null;
const winDirAltDirSep: string = process.env.WINDIR ? process.env.WINDIR.replace('\\', '/').toLowerCase() : null;
const winDirEnv: string = "${env:windir}";
if (winDir && winDirAltDirSep && (pipeProgramStr.indexOf(winDir) === 0 || pipeProgramStr.indexOf(winDirAltDirSep) === 0 || pipeProgramStr.indexOf(winDirEnv) === 0)) {
if (expectedArch === ArchType.x64) {
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "sysnative");
if (pathSep) {
// User has sysnative but we expect 64 bit. Should be using System32 since sysnative is a 32bit concept.
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}sysnative${pathSep}`, `${pathSep}system32${pathSep}`);
}
} else if (expectedArch === ArchType.ia32) {
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "system32");
if (pathSep) {
// User has System32 but we expect 32 bit. Should be using sysnative
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}system32${pathSep}`, `${pathSep}sysnative${pathSep}`);
}
}
}
return replacedPipeProgram;
}
// Checks to see if the folder name is in the path using both win and unix style path seperators.
// Returns the path seperator it detected if the folder is in the path.
// Or else it returns empty string to indicate it did not find it in the path.
public static checkForFolderInPath(path: string, folder: string): string {
if (path.indexOf(`/${folder}/`) >= 0) {
return '/';
} else if (path.indexOf(`\\${folder}\\`) >= 0) {
return '\\';
}
return "";
}
}
+136 -67
View File
@@ -21,8 +21,6 @@ import { createProtocolFilter } from './protocolFilter';
import { DataBinding } from './dataBinding';
import minimatch = require("minimatch");
import * as logger from '../logger';
import { updateLanguageConfigurations } from './extension';
import { SettingsTracker, getTracker } from './settingsTracker';
let ui: UI;
@@ -45,7 +43,7 @@ interface ReportStatusNotificationBody {
status: string;
}
interface QueryCompilerDefaultsParams {
interface QueryDefaultPathsParams {
}
interface FolderSettingsParams {
@@ -89,7 +87,7 @@ interface DecorationRangesPair {
// Requests
const NavigationListRequest: RequestType<TextDocumentIdentifier, string, void, void> = new RequestType<TextDocumentIdentifier, string, void, void>('cpptools/requestNavigationList');
const GoToDeclarationRequest: RequestType<void, void, void, void> = new RequestType<void, void, void, void>('cpptools/goToDeclaration');
const QueryCompilerDefaultsRequest: RequestType<QueryCompilerDefaultsParams, configs.CompilerDefaults, void, void> = new RequestType<QueryCompilerDefaultsParams, configs.CompilerDefaults, void, void>('cpptools/queryCompilerDefaults');
const QueryDefaultPathsRequest: RequestType<QueryDefaultPathsParams, configs.DefaultPaths, void, void> = new RequestType<QueryDefaultPathsParams, configs.DefaultPaths, void, void>('cpptools/queryDefaultPaths');
const SwitchHeaderSourceRequest: RequestType<SwitchHeaderSourceParams, string, void, void> = new RequestType<SwitchHeaderSourceParams, string, void, void>('cpptools/didSwitchHeaderSource');
// Notifications to the server
@@ -116,7 +114,92 @@ const DebugProtocolNotification: NotificationType<OutputNotificationBody, void>
const DebugLogNotification: NotificationType<OutputNotificationBody, void> = new NotificationType<OutputNotificationBody, void>('cpptools/debugLog');
const InactiveRegionNotification: NotificationType<InactiveRegionParams, void> = new NotificationType<InactiveRegionParams, void>('cpptools/inactiveRegions');
let failureMessageShown: boolean = false;
const maxSettingLengthForTelemetry: number = 50;
let previousCppSettings: { [key: string]: any } = {};
/**
* track settings changes for telemetry
*/
function collectSettingsForTelemetry(filter: (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean, resource: vscode.Uri): { [key: string]: string } {
let settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", resource);
let result: { [key: string]: string } = {};
for (let key in settings) {
if (settings.inspect(key).defaultValue === undefined) {
continue; // ignore methods and settings that don't exist
}
let val: any = settings.get(key);
if (val instanceof Object) {
continue; // ignore settings that are objects since tostring on those is not useful (e.g. navigation.length)
}
// Skip values that don't match the setting's enum.
let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
if (curSetting) {
let curEnum: any[] = curSetting["enum"];
if (curEnum && curEnum.indexOf(val) === -1) {
continue;
}
}
if (filter(key, val, settings)) {
previousCppSettings[key] = val;
switch (String(key).toLowerCase()) {
case "clang_format_path": {
continue;
}
case "clang_format_style":
case "clang_format_fallbackstyle": {
let newKey: string = String(key) + "2";
if (val) {
switch (String(val).toLowerCase()) {
case "visual studio":
case "llvm":
case "google":
case "chromium":
case "mozilla":
case "webkit":
case "file":
case "none": {
result[newKey] = String(previousCppSettings[key]);
break;
}
default: {
result[newKey] = "...";
break;
}
}
} else {
result[newKey] = "null";
}
key = newKey;
break;
}
default: {
result[key] = String(previousCppSettings[key]);
break;
}
}
if (result[key].length > maxSettingLengthForTelemetry) {
result[key] = result[key].substr(0, maxSettingLengthForTelemetry) + "...";
}
}
}
return result;
}
function initializeSettingsCache(resource: vscode.Uri): void {
collectSettingsForTelemetry(() => true, resource);
}
function getNonDefaultSettings(resource: vscode.Uri): { [key: string]: string } {
let filter: (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => {
return val !== settings.inspect(key).defaultValue;
};
initializeSettingsCache(resource);
return collectSettingsForTelemetry(filter, resource);
}
interface ClientModel {
isTagParsing: DataBinding<boolean>;
@@ -170,14 +253,14 @@ class DefaultClient implements Client {
private disposables: vscode.Disposable[] = [];
private configuration: configs.CppProperties;
private rootPathFileWatcher: vscode.FileSystemWatcher;
private rootFolder: vscode.WorkspaceFolder | undefined;
private workspaceRoot: vscode.WorkspaceFolder | undefined;
private trackedDocuments = new Set<vscode.TextDocument>();
private outputChannel: vscode.OutputChannel;
private debugChannel: vscode.OutputChannel;
private crashTimes: number[] = [];
private failureMessageShown = new PersistentState<boolean>("DefaultClient.failureMessageShown", false);
private isSupported: boolean = true;
private inactiveRegionsDecorations = new Map<string, DecorationRangesPair>();
private settingsTracker: SettingsTracker;
// The "model" that is displayed via the UI (status bar).
private model: ClientModel = {
@@ -195,16 +278,16 @@ class DefaultClient implements Client {
public get ActiveConfigChanged(): vscode.Event<string> { return this.model.activeConfigName.ValueChanged; }
/**
* don't use this.rootFolder directly since it can be undefined
* don't use this.workspaceRoot directly since it can be undefined
*/
public get RootPath(): string {
return (this.rootFolder) ? this.rootFolder.uri.fsPath : "";
return (this.workspaceRoot) ? this.workspaceRoot.uri.fsPath : "";
}
public get RootUri(): vscode.Uri {
return (this.rootFolder) ? this.rootFolder.uri : null;
return (this.workspaceRoot) ? this.workspaceRoot.uri : null;
}
public get Name(): string {
return this.getName(this.rootFolder);
return this.getName(this.workspaceRoot);
}
public get TrackedDocuments(): Set<vscode.TextDocument> {
return this.trackedDocuments;
@@ -228,12 +311,12 @@ class DefaultClient implements Client {
languageClient.registerProposedFeatures();
languageClient.start(); // This returns Disposable, but doesn't need to be tracked because we call .stop() explicitly in our dispose()
util.setProgress(util.getProgressExecutableStarted());
this.rootFolder = workspaceFolder;
this.workspaceRoot = workspaceFolder;
ui = getUI();
ui.bind(this);
this.onReadyPromise = languageClient.onReady().then(() => {
this.configuration = new configs.CppProperties(this.RootUri);
this.configuration = new configs.CppProperties(this.RootPath);
this.configuration.ConfigurationsChanged((e) => this.onConfigurationsChanged(e));
this.configuration.SelectionChanged((e) => this.onSelectedConfigurationChanged(e));
this.configuration.CompileCommandsChanged((e) => this.onCompileCommandsChanged(e));
@@ -241,37 +324,30 @@ class DefaultClient implements Client {
// The configurations will not be sent to the language server until the default include paths and frameworks have been set.
// The event handlers must be set before this happens.
languageClient.sendRequest(QueryCompilerDefaultsRequest, {}).then((compilerDefaults: configs.CompilerDefaults) => {
this.configuration.CompilerDefaults = compilerDefaults;
languageClient.sendRequest(QueryDefaultPathsRequest, {}).then((paths: configs.DefaultPaths) => {
this.configuration.DefaultPaths = paths;
});
// Once this is set, we don't defer any more callbacks.
this.languageClient = languageClient;
this.settingsTracker = getTracker(this.RootUri);
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", this.settingsTracker.getUserModifiedSettings());
failureMessageShown = false;
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", getNonDefaultSettings(this.RootUri));
this.failureMessageShown.Value = false;
// Listen for messages from the language server.
this.registerNotifications();
this.registerFileWatcher();
}, (err) => {
}, () => {
this.isSupported = false; // Running on an OS we don't support yet.
if (!failureMessageShown) {
failureMessageShown = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: " + String(err));
if (!this.failureMessageShown.Value) {
this.failureMessageShown.Value = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled.");
}
});
} catch (err) {
} catch {
this.isSupported = false; // Running on an OS we don't support yet.
if (!failureMessageShown) {
failureMessageShown = true;
let additionalInfo: string;
if (err.code === "EPERM") {
additionalInfo = `EPERM: Check permissions for '${getLanguageServerFileName()}'`;
} else {
additionalInfo = String(err);
}
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: " + additionalInfo);
if (!this.failureMessageShown.Value) {
this.failureMessageShown.Value = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled.");
}
}
}
@@ -317,14 +393,9 @@ class DefaultClient implements Client {
intelliSenseEngineFallback: settings.intelliSenseEngineFallback,
autocomplete: settings.autoComplete,
errorSquiggles: settings.errorSquiggles,
dimInactiveRegions: settings.dimInactiveRegions,
loggingLevel: settings.loggingLevel,
workspaceParsingPriority: settings.workspaceParsingPriority,
exclusionPolicy: settings.exclusionPolicy,
preferredPathSeparator: settings.preferredPathSeparator,
default: {
systemIncludePath: settings.defaultSystemIncludePath
}
exclusionPolicy: settings.exclusionPolicy
},
middleware: createProtocolFilter(this, allClients), // Only send messages directed at this client.
errorHandler: {
@@ -361,26 +432,25 @@ class DefaultClient implements Client {
}
public onDidChangeSettings(): void {
let changedSettings: { [key: string] : string} = this.settingsTracker.getChangedSettings();
// This relies on getNonDefaultSettings being called first.
console.assert(Object.keys(previousCppSettings).length > 0);
let filter: (key: string, val: string) => boolean = (key: string, val: string) => {
return !(key in previousCppSettings) || val !== previousCppSettings[key];
};
let changedSettings: any = collectSettingsForTelemetry(filter, this.RootUri);
if (Object.keys(changedSettings).length > 0) {
if (changedSettings["commentContinuationPatterns"]) {
updateLanguageConfigurations();
}
this.configuration.onDidChangeSettings();
telemetry.logLanguageServerEvent("CppSettingsChange", changedSettings, null);
}
}
public onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {
let settings: CppSettings = new CppSettings(this.RootUri);
if (settings.dimInactiveRegions) {
//Apply text decorations to inactive regions
for (let e of editors) {
let valuePair: DecorationRangesPair = this.inactiveRegionsDecorations.get(e.document.uri.toString());
if (valuePair) {
e.setDecorations(valuePair.decoration, valuePair.ranges); // VSCode clears the decorations when the text editor becomes invisible
}
//Apply text decorations to inactive regions
for (let e of editors) {
let valuePair: DecorationRangesPair = this.inactiveRegionsDecorations.get(e.document.uri.toString());
if (valuePair) {
e.setDecorations(valuePair.decoration, valuePair.ranges); // VSCode clears the decorations when the text editor becomes invisible
}
}
}
@@ -442,15 +512,15 @@ class DefaultClient implements Client {
}
/**
* listen for file created/deleted events under the ${workspaceFolder} folder
* listen for file created/deleted events under the ${workspaceRoot} folder
*/
private registerFileWatcher(): void {
console.assert(this.languageClient !== undefined, "This method must not be called until this.languageClient is set in \"onReady\"");
if (this.rootFolder) {
if (this.workspaceRoot) {
// WARNING: The default limit on Linux is 8k, so for big directories, this can cause file watching to fail.
this.rootPathFileWatcher = vscode.workspace.createFileSystemWatcher(
"**/*",
path.join(this.RootPath, "*"),
false /*ignoreCreateEvents*/,
true /*ignoreChangeEvents*/,
false /*ignoreDeleteEvents*/);
@@ -476,10 +546,16 @@ class DefaultClient implements Client {
console.assert(this.languageClient !== undefined, "This method must not be called until this.languageClient is set in \"onReady\"");
this.languageClient.onNotification(DebugProtocolNotification, (output) => {
let outputEditorExist: boolean = vscode.window.visibleTextEditors.some((editor: vscode.TextEditor) => {
return editor.document.uri.scheme === "output";
});
if (!this.debugChannel) {
this.debugChannel = vscode.window.createOutputChannel(`C/C++ Debug Protocol: ${this.Name}`);
this.disposables.push(this.debugChannel);
}
if (!outputEditorExist) {
this.debugChannel.show();
}
this.debugChannel.appendLine("");
this.debugChannel.appendLine("************************************************************************************************************************");
this.debugChannel.append(`${output}`);
@@ -594,10 +670,7 @@ class DefaultClient implements Client {
if (showIntelliSenseFallbackMessage.Value) {
let learnMorePanel: string = "Learn More";
let dontShowAgain: string = "Don't Show Again";
let fallbackMsg: string = this.configuration.VcpkgInstalled ?
"Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers." :
"Configure your IntelliSense settings to help find missing headers.";
vscode.window.showInformationMessage(fallbackMsg, learnMorePanel, dontShowAgain).then((value) => {
vscode.window.showInformationMessage("Configure includePath for better IntelliSense results.", learnMorePanel, dontShowAgain).then((value) => {
switch (value) {
case learnMorePanel:
let uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`);
@@ -624,8 +697,7 @@ class DefaultClient implements Client {
private updateInactiveRegions(params: InactiveRegionParams): void {
let renderOptions: vscode.DecorationRenderOptions = {
light: { color: "rgba(175,175,175,1.0)" },
dark: { color: "rgba(155,155,155,1.0)" },
rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen
dark: { color: "rgba(155,155,155,1.0)" }
};
let decoration: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType(renderOptions);
@@ -653,13 +725,10 @@ class DefaultClient implements Client {
this.inactiveRegionsDecorations.set(params.uri, toInsert);
}
let settings: CppSettings = new CppSettings(this.RootUri);
if (settings.dimInactiveRegions) {
// Apply the decorations to all *visible* text editors
let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === params.uri);
for (let e of editors) {
e.setDecorations(decoration, ranges);
}
// Apply the decorations to all *visible* text editors
let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === params.uri);
for (let e of editors) {
e.setDecorations(decoration, ranges);
}
}
@@ -8,7 +8,6 @@ import * as vscode from 'vscode';
import * as util from '../common';
import * as telemetry from '../telemetry';
import * as cpptools from './client';
import * as path from 'path';
const defaultClientKey: string = "@@default@@";
export interface ClientKey {
@@ -83,7 +82,7 @@ export class ClientCollection {
public checkOwnership(client: cpptools.Client, document: vscode.TextDocument): boolean {
let owners: cpptools.Client[] = [];
this.languageClients.forEach(languageClient => {
if (document.uri.fsPath.startsWith(languageClient.RootPath + path.sep)) {
if (document.uri.fsPath.startsWith(languageClient.RootPath)) {
owners.push(languageClient);
}
});
+141 -292
View File
@@ -8,68 +8,106 @@ import * as path from 'path';
import * as fs from "fs";
import * as vscode from 'vscode';
import * as util from '../common';
import * as telemetry from '../telemetry';
import { PersistentFolderState } from './persistentState';
import { CppSettings } from './settings';
const configVersion: number = 4;
const configVersion: number = 3;
// No properties are set in the config since we want to apply vscode settings first (if applicable).
// That code won't trigger if another value is already set.
// The property defaults are moved down to applyDefaultIncludePathsAndFrameworks.
function getDefaultConfig(): Configuration {
if (process.platform === 'darwin') {
return { name: "Mac", browse: {} };
} else if (process.platform === 'win32') {
return { name: "Win32", browse: {} };
} else {
return { name: "Linux", browse: {} };
}
let defaultSettings: string = `{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"$\{workspaceRoot\}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"$\{workspaceRoot\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
]
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"$\{workspaceRoot\}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"$\{workspaceRoot\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
"$\{workspaceRoot\}"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
"$\{workspaceRoot\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": ${configVersion}
}
`;
function getDefaultCppProperties(): ConfigurationJson {
return {
configurations: [getDefaultConfig()],
version: configVersion
};
}
interface ConfigurationJson {
configurations: Configuration[];
env?: {[key: string]: string | string[]};
version: number;
export interface Browse {
path?: string[];
limitSymbolsToIncludedHeaders?: boolean;
databaseFilename?: string;
}
export interface Configuration {
name: string;
compilerPath?: string;
cStandard?: string;
cppStandard?: string;
includePath?: string[];
macFrameworkPath?: string[];
defines?: string[];
intelliSenseMode?: string;
compileCommands?: string;
forcedInclude?: string[];
browse?: Browse;
}
export interface Browse {
path?: string[];
limitSymbolsToIncludedHeaders?: boolean | string;
databaseFilename?: string;
}
export interface CompilerDefaults {
compilerPath: string;
cStandard: string;
cppStandard: string;
export interface DefaultPaths {
includes: string[];
frameworks: string[];
intelliSenseMode: string;
}
interface ConfigurationJson {
configurations: Configuration[];
version: number;
}
export class CppProperties {
private rootUri: vscode.Uri;
private propertiesFile: vscode.Uri = null;
private readonly configFolder: string;
private configurationJson: ConfigurationJson = null;
@@ -77,38 +115,27 @@ export class CppProperties {
private configFileWatcher: vscode.FileSystemWatcher = null;
private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
private compileCommandFileWatchers: fs.FSWatcher[] = [];
private defaultCompilerPath: string = null;
private defaultCStandard: string = null;
private defaultCppStandard: string = null;
private defaultIncludes: string[] = null;
private defaultFrameworks: string[] = null;
private vcpkgIncludes: string[] = [];
private vcpkgPathReady: boolean = false;
private defaultIntelliSenseMode: string = null;
private readonly configurationGlobPattern: string = "**/c_cpp_properties.json"; // TODO: probably should be a single file, not all files...
private disposables: vscode.Disposable[] = [];
private configurationsChanged = new vscode.EventEmitter<Configuration[]>();
private selectionChanged = new vscode.EventEmitter<number>();
private compileCommandsChanged = new vscode.EventEmitter<string>();
// Any time the default settings are parsed and assigned to `this.configurationJson`,
// Any time the `defaultSettings` are parsed and assigned to `this.configurationJson`,
// we want to track when the default includes have been added to it.
private configurationIncomplete: boolean = true;
constructor(rootUri: vscode.Uri) {
console.assert(rootUri !== undefined);
this.rootUri = rootUri;
let rootPath: string = rootUri ? rootUri.fsPath : "";
constructor(rootPath: string) {
console.assert(rootPath !== undefined);
this.currentConfigurationIndex = new PersistentFolderState<number>("CppProperties.currentConfigurationIndex", -1, rootPath);
this.configFolder = path.join(rootPath, ".vscode");
this.resetToDefaultSettings(this.currentConfigurationIndex.Value === -1);
let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json");
if (fs.existsSync(configFilePath)) {
this.propertiesFile = vscode.Uri.file(configFilePath);
this.parsePropertiesFile();
}
if (!this.configurationJson) {
this.resetToDefaultSettings(this.CurrentConfiguration === -1);
}
this.configFileWatcher = vscode.workspace.createFileSystemWatcher(path.join(this.configFolder, this.configurationGlobPattern));
@@ -128,8 +155,6 @@ export class CppProperties {
this.handleConfigurationChange();
});
this.buildVcpkgIncludePath();
this.disposables.push(vscode.Disposable.from(this.configurationsChanged, this.selectionChanged, this.compileCommandsChanged));
}
@@ -145,23 +170,15 @@ export class CppProperties {
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.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
public set DefaultPaths(paths: DefaultPaths) {
this.defaultIncludes = paths.includes;
this.defaultFrameworks = paths.frameworks;
// 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();
}
public get VcpkgInstalled(): boolean {
return this.vcpkgIncludes.length > 0;
}
private onConfigurationsChanged(): void {
this.configurationsChanged.fire(this.Configurations);
}
@@ -174,19 +191,8 @@ export class CppProperties {
this.compileCommandsChanged.fire(path);
}
public onDidChangeSettings(): void {
// Default settings may have changed in a way that affects the configuration.
// Just send another message since the language server will sort out whether anything important changed or not.
if (!this.propertiesFile) {
this.resetToDefaultSettings(true);
this.handleConfigurationChange();
} else if (!this.configurationIncomplete) {
this.handleConfigurationChange();
}
}
private resetToDefaultSettings(resetIndex: boolean): void {
this.configurationJson = getDefaultCppProperties();
this.configurationJson = JSON.parse(defaultSettings);
if (resetIndex || this.CurrentConfiguration < 0 ||
this.CurrentConfiguration >= this.configurationJson.configurations.length) {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(this.configurationJson);
@@ -194,86 +200,29 @@ export class CppProperties {
this.configurationIncomplete = true;
}
private applyDefaultIncludePathsAndFrameworks(): void {
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks && this.vcpkgPathReady) {
let configuration: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
let settings: CppSettings = new CppSettings(this.rootUri);
// Anything that has a vscode setting for it will be resolved in updateServerOnFolderSettingsChange.
// So if a property is currently unset, but has a vscode setting, don't set it yet, otherwise the linkage
// to the setting will be lost if this configuration is saved into a c_cpp_properties.json file.
// Only add settings from the default compiler if user hasn't explicitly set the corresponding VS Code setting.
if (!settings.defaultIncludePath) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.includePath = ["${workspaceFolder}/**"].concat(this.vcpkgIncludes);
}
if (!settings.defaultBrowsePath) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.browse.path = ["${workspaceFolder}"].concat(this.vcpkgIncludes);
}
if (!settings.defaultDefines) {
configuration.defines = (process.platform === 'win32') ? ["_DEBUG", "UNICODE", "_UNICODE"] : [];
}
if (!settings.defaultMacFrameworkPath && process.platform === 'darwin') {
configuration.macFrameworkPath = this.defaultFrameworks;
}
if (!settings.defaultCompilerPath && this.defaultCompilerPath) {
configuration.compilerPath = this.defaultCompilerPath;
}
if (!settings.defaultCStandard && this.defaultCStandard) {
configuration.cStandard = this.defaultCStandard;
}
if (!settings.defaultCppStandard && this.defaultCppStandard) {
configuration.cppStandard = this.defaultCppStandard;
}
if (!settings.defaultIntelliSenseMode) {
configuration.intelliSenseMode = this.defaultIntelliSenseMode;
private applyDefaultIncludePathsAndFrameworks(): void {
if (this.configurationIncomplete && this.defaultIncludes !== undefined && this.defaultFrameworks !== undefined) {
this.configurationJson.configurations[this.CurrentConfiguration].includePath = this.defaultIncludes;
this.configurationJson.configurations[this.CurrentConfiguration].browse.path = this.defaultIncludes;
if (process.platform === 'darwin') {
this.configurationJson.configurations[this.CurrentConfiguration].macFrameworkPath = this.defaultFrameworks;
}
this.configurationIncomplete = false;
}
}
private async buildVcpkgIncludePath(): Promise<void> {
try {
// Check for vcpkg instance and include relevent paths if found.
if (await util.checkFileExists(util.getVcpkgPathDescriptorFile())) {
let vcpkgRoot: string = await util.readFileText(util.getVcpkgPathDescriptorFile());
vcpkgRoot = vcpkgRoot.trim();
if (await util.checkDirectoryExists(vcpkgRoot)) {
let vcpkgInstalledPath: string = path.join(vcpkgRoot, "/installed");
let list: string[] = await util.readDir(vcpkgInstalledPath);
if (list !== undefined) {
// For every *directory* in the list (non-recursive). Each directory is basically a platform.
list.forEach((entry) => {
if (entry !== "vcpkg") {
let pathToCheck: string = path.join(vcpkgInstalledPath, entry);
if (fs.existsSync(pathToCheck)) {
let p: string = path.join(pathToCheck, "include");
if (fs.existsSync(p)) {
this.vcpkgIncludes.push(p);
}
}
}
});
}
}
}
} catch (error) {} finally {
this.vcpkgPathReady = true;
this.handleConfigurationChange();
}
}
private getConfigIndexForPlatform(config: any): number {
if (this.configurationJson.configurations.length > 3) {
return this.configurationJson.configurations.length - 1; // Default to the last custom configuration.
}
let nodePlatform: NodeJS.Platform = process.platform;
let plat: string;
if (process.platform === 'darwin') {
plat = "Mac";
} else if (process.platform === 'win32') {
plat = "Win32";
} else {
if (nodePlatform === 'linux') {
plat = "Linux";
} else if (nodePlatform === 'darwin') {
plat = "Mac";
} else if (nodePlatform === 'win32') {
plat = "Win32";
}
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
if (config.configurations[i].name === plat) {
@@ -289,12 +238,14 @@ export class CppProperties {
return "clang-x64";
} else if (name === "Win32") {
return "msvc-x64";
} else if (process.platform === 'win32') {
// Custom configs default to the OS's preference.
return "msvc-x64";
} else {
return "clang-x64";
// Custom configs default to the OS's preference.
let nodePlatform: NodeJS.Platform = process.platform;
if (nodePlatform === 'linux' || nodePlatform === 'darwin') {
return "clang-x64";
}
}
return "msvc-x64";
}
private includePathConverted(): boolean {
@@ -308,12 +259,7 @@ export class CppProperties {
public addToIncludePathCommand(path: string): void {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
telemetry.logLanguageServerEvent("addToIncludePath");
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
if (config.includePath === undefined) {
config.includePath = ["${default}"];
}
config.includePath.splice(config.includePath.length, 0, path);
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
this.updateServerOnFolderSettingsChange();
@@ -329,83 +275,30 @@ export class CppProperties {
this.onSelectionChanged();
}
private resolveDefaults(entries: string[], defaultValue: string[]): string[] {
private resolveAndSplit(paths: string[]): string[] {
let result: string[] = [];
entries.forEach(entry => {
if (entry === "${default}") {
// package.json default values for string[] properties is null.
// If no default is set, return an empty array instead of an array with `null` in it.
if (defaultValue !== null) {
result = result.concat(defaultValue);
}
} else {
result.push(entry);
}
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e);
result = result.concat(entries);
});
return result;
}
private resolveAndSplit(paths: string[] | undefined, defaultValue: string[]): string[] {
let result: string[] = [];
if (paths) {
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry, this.configurationJson.env).split(";").filter(e => e);
entries = this.resolveDefaults(entries, defaultValue);
result = result.concat(entries);
});
}
return result;
}
private resolveVariables(input: string | boolean, defaultValue: string | boolean): string | boolean {
if (input === undefined || input === "${default}") {
input = defaultValue;
}
if (typeof input === "boolean") {
return input;
}
return util.resolveVariables(input, this.configurationJson.env);
}
private updateConfiguration(property: string[], defaultValue: string[]): string[];
private updateConfiguration(property: string, defaultValue: string): string;
private updateConfiguration(property: string | boolean, defaultValue: boolean): boolean;
private updateConfiguration(property, defaultValue): any {
if (typeof property === "string" || typeof defaultValue === "string") {
return this.resolveVariables(property, defaultValue);
} else if (typeof property === "boolean" || typeof defaultValue === "boolean") {
return this.resolveVariables(property, defaultValue);
} else if (property instanceof Array || defaultValue instanceof Array) {
if (property) {
return this.resolveAndSplit(property, defaultValue);
} else if (property === undefined && defaultValue) {
return this.resolveAndSplit(defaultValue, []);
}
}
return property;
}
private updateServerOnFolderSettingsChange(): void {
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let configuration: Configuration = this.configurationJson.configurations[i];
configuration.includePath = this.updateConfiguration(configuration.includePath, settings.defaultIncludePath);
configuration.defines = this.updateConfiguration(configuration.defines, settings.defaultDefines);
configuration.macFrameworkPath = this.updateConfiguration(configuration.macFrameworkPath, settings.defaultMacFrameworkPath);
configuration.forcedInclude = this.updateConfiguration(configuration.forcedInclude, settings.defaultForcedInclude);
configuration.compileCommands = this.updateConfiguration(configuration.compileCommands, settings.defaultCompileCommands);
configuration.compilerPath = this.updateConfiguration(configuration.compilerPath, settings.defaultCompilerPath);
configuration.cStandard = this.updateConfiguration(configuration.cStandard, settings.defaultCStandard);
configuration.cppStandard = this.updateConfiguration(configuration.cppStandard, settings.defaultCppStandard);
configuration.intelliSenseMode = this.updateConfiguration(configuration.intelliSenseMode, settings.defaultIntelliSenseMode);
if (!configuration.browse) {
configuration.browse = {};
if (configuration.includePath !== undefined) {
configuration.includePath = this.resolveAndSplit(configuration.includePath);
}
if (configuration.browse !== undefined && configuration.browse.path !== undefined) {
configuration.browse.path = this.resolveAndSplit(configuration.browse.path);
}
if (configuration.macFrameworkPath !== undefined) {
configuration.macFrameworkPath = this.resolveAndSplit(configuration.macFrameworkPath);
}
if (configuration.compileCommands !== undefined) {
configuration.compileCommands = util.resolveVariables(configuration.compileCommands);
}
configuration.browse.path = this.updateConfiguration(configuration.browse.path, settings.defaultBrowsePath);
configuration.browse.limitSymbolsToIncludedHeaders = this.updateConfiguration(configuration.browse.limitSymbolsToIncludedHeaders, settings.defaultLimitSymbolsToIncludedHeaders);
configuration.browse.databaseFilename = this.updateConfiguration(configuration.browse.databaseFilename, settings.defaultDatabaseFilename);
}
this.updateCompileCommandsFileWatchers();
@@ -425,18 +318,13 @@ export class CppProperties {
filePaths.add(c.compileCommands);
}
});
try {
filePaths.forEach((path: string) => {
this.compileCommandFileWatchers.push(fs.watch(path, (event: string, filename: string) => {
if (event !== "rename") {
this.onCompileCommandsChanged(path);
}
}));
});
} catch (e) {
// The file watcher limit is hit.
// TODO: Check if the compile commands file has a higher timestamp during the interval timer.
}
filePaths.forEach((path: string) => {
this.compileCommandFileWatchers.push(fs.watch(path, (event: string, filename: string) => {
if (event !== "rename") {
this.onCompileCommandsChanged(path);
}
}));
});
}
public handleConfigurationEditCommand(onSuccess: (document: vscode.TextDocument) => void): void {
@@ -508,11 +396,7 @@ export class CppProperties {
// Try to use the same configuration as before the change.
let newJson: ConfigurationJson = JSON.parse(readResults);
if (!newJson || !newJson.configurations || newJson.configurations.length === 0) {
throw { message: "Invalid configuration file. There must be at least one configuration present in the array." };
}
if (!this.configurationIncomplete && this.configurationJson && this.configurationJson.configurations &&
this.CurrentConfiguration >= 0 && this.CurrentConfiguration < this.configurationJson.configurations.length) {
if (!this.configurationIncomplete && newJson.configurations && this.configurationJson) {
for (let i: number = 0; i < newJson.configurations.length; i++) {
if (newJson.configurations[i].name === this.configurationJson.configurations[this.CurrentConfiguration].name) {
this.currentConfigurationIndex.Value = i;
@@ -521,22 +405,20 @@ export class CppProperties {
}
}
this.configurationJson = newJson;
if (this.CurrentConfiguration < 0 || this.CurrentConfiguration >= newJson.configurations.length) {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(newJson);
}
// Remove disallowed variable overrides
if (this.configurationJson.env) {
delete this.configurationJson.env['workspaceRoot'];
delete this.configurationJson.env['workspaceFolder'];
delete this.configurationJson.env['default'];
}
// Warning: There is a chance that this is incorrect in the event that the c_cpp_properties.json file was created before
// the system includes were available.
this.configurationIncomplete = false;
let dirty: boolean = false;
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined) {
dirty = true;
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
}
if (this.configurationJson.version !== configVersion) {
dirty = true;
if (this.configurationJson.version === undefined) {
@@ -545,10 +427,6 @@ export class CppProperties {
if (this.configurationJson.version === 2) {
this.updateToVersion3();
}
if (this.configurationJson.version === 3) {
this.updateToVersion4();
} else {
this.configurationJson.version = configVersion;
vscode.window.showErrorMessage('Unknown version number found in c_cpp_properties.json. Some features may not work as expected.');
@@ -556,12 +434,7 @@ export class CppProperties {
}
if (dirty) {
try {
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
} catch {
// 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?)');
}
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
}
} catch (err) {
vscode.window.showErrorMessage('Failed to parse "' + this.propertiesFile.fsPath + '": ' + err.message);
@@ -589,7 +462,7 @@ export class CppProperties {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
// Look for Mac configs and extra configs on Mac systems
if (config.name === "Mac" || (process.platform === 'darwin' && config.name !== "Win32" && config.name !== "Linux")) {
if (config.name === "Mac" || (process.platform === "darwin" && config.name !== "Win32" && config.name !== "Linux")) {
if (config.macFrameworkPath === undefined) {
config.macFrameworkPath = [
"/System/Library/Frameworks",
@@ -600,30 +473,6 @@ export class CppProperties {
}
}
private updateToVersion4(): void {
this.configurationJson.version = 4;
// Update intelliSenseMode, compilerPath, cStandard, and cppStandard with the defaults if they're missing.
// If VS Code settings exist for these properties, don't add them to c_cpp_properties.json
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined && !settings.defaultIntelliSenseMode) {
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
// Don't set the default if compileCommands exist, until it is fixed to have the correct value.
if (config.compilerPath === undefined && this.defaultCompilerPath && !config.compileCommands && !settings.defaultCompilerPath) {
config.compilerPath = this.defaultCompilerPath;
}
if (!config.cStandard && this.defaultCStandard && !settings.defaultCStandard) {
config.cStandard = this.defaultCStandard;
}
if (!config.cppStandard && this.defaultCppStandard && !settings.defaultCppStandard) {
config.cppStandard = this.defaultCppStandard;
}
}
}
public checkCppProperties(): void {
// Check for change properties in case of file watcher failure.
let propertiesFile: string = path.join(this.configFolder, "c_cpp_properties.json");
+58 -106
View File
@@ -14,7 +14,6 @@ import { Client } from './client';
import { ClientCollection } from './clientCollection';
import { CppSettings } from './settings';
import { PersistentWorkspaceState } from './persistentState';
import { getLanguageConfig } from './languageConfig';
import * as os from 'os';
let prevCrashFile: string;
@@ -22,12 +21,41 @@ let clients: ClientCollection;
let activeDocument: string;
let ui: UI;
let disposables: vscode.Disposable[] = [];
let languageConfigurations: vscode.Disposable[] = [];
let intervalTimer: NodeJS.Timer;
let realActivationOccurred: boolean = false;
let tempCommands: vscode.Disposable[] = [];
let activatedPreviously: PersistentWorkspaceState<boolean>;
// Add ' * ' on new lines after multiline comment with '/**' started
// Copied from vscode/extensions/typescript/src/typescriptMain.ts
const multilineCommentRules: any = {
onEnterRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: ' * ' }
}, {
// e.g. /** ...|
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
action: { indentAction: vscode.IndentAction.None, appendText: ' * ' }
}, {
// e.g. * ...|
beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
action: { indentAction: vscode.IndentAction.None, appendText: '* ' }
}, {
// e.g. */|
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
action: { indentAction: vscode.IndentAction.None, removeText: 1 }
},
{
// e.g. *-----*/|
beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
action: { indentAction: vscode.IndentAction.None, removeText: 1 }
}
]
};
/**
* activate: set up the extension for language services
*/
@@ -47,28 +75,14 @@ export function activate(activationEventOccurred: boolean): void {
// Check if an activation event has already occurred.
if (activationEventOccurred) {
onActivationEvent();
return;
return onActivationEvent();
}
// 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) {
let config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json");
if (fs.existsSync(config)) {
onActivationEvent();
return;
}
}
}
// handle "onLanguage:cpp" and "onLanguage:c" activation events.
if (vscode.workspace.textDocuments !== undefined && vscode.workspace.textDocuments.length > 0) {
for (let i: number = 0; i < vscode.workspace.textDocuments.length; ++i) {
let document: vscode.TextDocument = vscode.workspace.textDocuments[i];
if (document.languageId === "cpp" || document.languageId === "c") {
onActivationEvent();
return;
return onActivationEvent();
}
}
}
@@ -114,21 +128,14 @@ function realActivation(): void {
disposables.push(vscode.window.onDidChangeTextEditorSelection(onDidChangeTextEditorSelection));
disposables.push(vscode.window.onDidChangeVisibleTextEditors(onDidChangeVisibleTextEditors));
updateLanguageConfigurations();
disposables.push(vscode.languages.setLanguageConfiguration('c', multilineCommentRules));
disposables.push(vscode.languages.setLanguageConfiguration('cpp', multilineCommentRules));
reportMacCrashes();
intervalTimer = setInterval(onInterval, 2500);
}
export function updateLanguageConfigurations(): void {
languageConfigurations.forEach(d => d.dispose());
languageConfigurations = [];
languageConfigurations.push(vscode.languages.setLanguageConfiguration('c', getLanguageConfig('c', clients.ActiveClient.RootUri)));
languageConfigurations.push(vscode.languages.setLanguageConfiguration('cpp', getLanguageConfig('cpp', clients.ActiveClient.RootUri)));
}
/*********************************************
* workspace events
*********************************************/
@@ -206,9 +213,7 @@ function registerCommands(): void {
disposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationEdit', onEditConfiguration));
disposables.push(vscode.commands.registerCommand('C_Cpp.AddToIncludePath', onAddToIncludePath));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleErrorSquiggles', onToggleSquiggles));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleSnippets', onToggleSnippets));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleIncludeFallback', onToggleIncludeFallback));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleDimInactiveRegions', onToggleDimInactiveRegions));
disposables.push(vscode.commands.registerCommand('C_Cpp.ShowReleaseNotes', onShowReleaseNotes));
disposables.push(vscode.commands.registerCommand('C_Cpp.PauseParsing', onPauseParsing));
disposables.push(vscode.commands.registerCommand('C_Cpp.ResumeParsing', onResumeParsing));
@@ -344,47 +349,6 @@ function onToggleSquiggles(): void {
settings.toggleSetting("errorSquiggles", "Enabled", "Disabled");
}
function onToggleSnippets(): void {
onActivationEvent();
// This will apply to all clients as it's a global toggle. It will require a reload.
const snippetsCatName: string = "Snippets";
let newPackageJson: any = util.getRawPackageJson();
if (newPackageJson.categories.findIndex(cat => cat === snippetsCatName) === -1) {
// Add the Snippet category and snippets node.
newPackageJson.categories.push(snippetsCatName);
newPackageJson.contributes.snippets = [{"language": "cpp", "path": "./cpp_snippets.json"}, {"language": "c", "path": "./cpp_snippets.json"}];
fs.writeFile(util.getPackageJsonPath(), util.stringifyPackageJson(newPackageJson), () => {
showReloadPrompt("Reload Window to finish enabling C++ snippets");
});
} else {
// Remove the category and snippets node.
let ndxCat: number = newPackageJson.categories.indexOf(snippetsCatName);
if (ndxCat !== -1) {
newPackageJson.categories.splice(ndxCat, 1);
}
delete newPackageJson.contributes.snippets;
fs.writeFile(util.getPackageJsonPath(), util.stringifyPackageJson(newPackageJson), () => {
showReloadPrompt("Reload Window to finish disabling C++ snippets");
});
}
}
function showReloadPrompt(msg: string): void {
let reload: string = "Reload";
vscode.window.showInformationMessage(msg, reload).then(value => {
if (value === reload) {
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
});
}
function onToggleIncludeFallback(): void {
onActivationEvent();
// This only applies to the active client.
@@ -392,13 +356,6 @@ function onToggleIncludeFallback(): void {
settings.toggleSetting("intelliSenseEngineFallback", "Enabled", "Disabled");
}
function onToggleDimInactiveRegions(): void {
onActivationEvent();
// This only applies to the active client.
let settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri);
settings.update<boolean>("dimInactiveRegions", !settings.dimInactiveRegions);
}
function onShowReleaseNotes(): void {
onActivationEvent();
util.showReleaseNotes();
@@ -440,33 +397,29 @@ function reportMacCrashes(): void {
}
// vscode.workspace.createFileSystemWatcher only works in workspace folders.
try {
fs.watch(crashFolder, (event, filename) => {
if (event !== "rename") {
return;
}
if (filename === prevCrashFile) {
return;
}
prevCrashFile = filename;
if (!filename.startsWith("Microsoft.VSCode.CPP.")) {
return;
}
// Wait 5 seconds to allow time for the crash log to finish being written.
setTimeout(() => {
fs.readFile(path.resolve(crashFolder, filename), 'utf8', (err, data) => {
if (err) {
// Try again?
fs.readFile(path.resolve(crashFolder, filename), 'utf8', handleCrashFileRead);
return;
}
handleCrashFileRead(err, data);
});
}, 5000);
});
} catch (e) {
// The file watcher limit is hit (may not be possible on Mac, but just in case).
}
fs.watch(crashFolder, (event, filename) => {
if (event !== "rename") {
return;
}
if (filename === prevCrashFile) {
return;
}
prevCrashFile = filename;
if (!filename.startsWith("Microsoft.VSCode.CPP.")) {
return;
}
// Wait 5 seconds to allow time for the crash log to finish being written.
setTimeout(() => {
fs.readFile(path.resolve(crashFolder, filename), 'utf8', (err, data) => {
if (err) {
// Try again?
fs.readFile(path.resolve(crashFolder, filename), 'utf8', handleCrashFileRead);
return;
}
handleCrashFileRead(err, data);
});
}, 5000);
});
});
}
}
@@ -499,7 +452,6 @@ export function deactivate(): Thenable<void> {
telemetry.logLanguageServerEvent("LanguageServerShutdown");
clearInterval(intervalTimer);
disposables.forEach(d => d.dispose());
languageConfigurations.forEach(d => d.dispose());
ui.dispose();
return clients.dispose();
}
@@ -1,321 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as vscode from 'vscode';
import { CppSettings } from './settings';
import { getOutputChannel } from '../logger';
export interface CommentPattern {
begin: string;
continue: string;
}
const escapeChars: RegExp = /[\\\^\$\*\+\?\{\}\(\)\.\!\=\|\[\]\ \/]/; // characters that should be escaped.
// Insert '\\' in front of regexp escape chars.
function escape(chars: string): string {
let result: string = "";
for (let char of chars) {
if (char.match(escapeChars)) {
result += `\\${char}`;
} else {
result += char;
}
}
return result;
}
// BEWARE: below are string representations of regular expressions, so the backslashes must all be escaped.
function getMLBeginPattern(insert: string): string | undefined {
if (insert && insert.startsWith("/*")) {
let match: string = escape(insert.substr(2)); // trim the leading '/*' and escape any troublesome characters.
return `^\\s*\\/\\*${match}(?!\\/)([^\\*]|\\*(?!\\/))*$`;
}
return undefined;
}
function getMLSplitAfterPattern(): string {
return "^\\s*\\*\\/$";
}
function getMLContinuePattern(insert: string): string | undefined {
if (insert) {
let match: string = escape(insert.trimRight());
if (match) {
let right: string = escape(insert.substr(insert.trimRight().length));
return `^\\s*${match}(${right}([^\\*]|\\*(?!\\/))*)?$`;
}
// else: if the continuation is just whitespace, vscode already does indentation preservation.
}
return undefined;
}
function getMLEndPattern(insert: string): string | undefined {
if (insert) {
let match: string = escape(insert.trimRight().trimLeft());
if (match) {
return `^\\s*${match}[^/]*\\*\\/\\s*$`;
}
// else: if the continuation is just whitespace, don't mess with indentation
// since we don't know if this is a continuation line or not.
}
return undefined;
}
function getMLEmptyEndPattern(insert: string): string | undefined {
if (insert) {
insert = insert.trimRight();
if (insert) {
if (insert.endsWith('*')) {
insert = insert.substr(0, insert.length - 1);
}
let match: string = escape(insert.trimRight());
return `^\\s*${match}\\*\\/\\s*$`;
}
// else: if the continuation is just whitespace, don't mess with indentation
// since we don't know if this is a continuation line or not.
}
return undefined;
}
function getSLBeginPattern(insert: string): string | undefined {
if (insert) {
let match: string = escape(insert.trimRight());
return `^\\s*${match}.*$`;
}
return undefined;
}
function getSLContinuePattern(insert: string): string | undefined {
if (insert) {
let match: string = escape(insert.trimRight());
return `^\\s*${match}.+$`;
}
return undefined;
}
function getSLEndPattern(insert: string): string | undefined {
if (insert) {
let match: string = escape(insert);
let trimmed: string = escape(insert.trimRight());
if (match !== trimmed) {
match = `(${match}|${trimmed})`;
}
return `^\\s*${match}$`;
}
return undefined;
}
// When Enter is pressed while the cursor is between '/**' and '*/' on the same line.
function getMLSplitRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let beforePattern: string | undefined = getMLBeginPattern(comment.begin);
if (beforePattern) {
return {
beforeText: new RegExp(beforePattern),
afterText: new RegExp(getMLSplitAfterPattern()),
action: {
indentAction: vscode.IndentAction.IndentOutdent,
appendText: comment.continue ? comment.continue : ''
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is after '/**' and there is no '*/' on the same line after the cursor
function getMLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let beforePattern: string | undefined = getMLBeginPattern(comment.begin);
if (beforePattern) {
return {
beforeText: new RegExp(beforePattern),
action: {
indentAction: vscode.IndentAction.None,
appendText: comment.continue ? comment.continue : ''
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is after the continuation pattern
function getMLContinuationRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let continuePattern: string = getMLContinuePattern(comment.continue);
if (continuePattern) {
return {
beforeText: new RegExp(continuePattern),
action: {
indentAction: vscode.IndentAction.None,
appendText: comment.continue.trimLeft()
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is after '*/' (and '*/' plus leading whitespace is all that is on the line)
function getMLEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let endPattern: string = getMLEndPattern(comment.continue);
if (endPattern) {
return {
beforeText: new RegExp(endPattern),
action: {
indentAction: vscode.IndentAction.None,
removeText: comment.continue.length - comment.continue.trimLeft().length
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is after the continuation pattern and '*/'
function getMLEmptyEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let endPattern: string = getMLEmptyEndPattern(comment.continue);
if (endPattern) {
return {
beforeText: new RegExp(endPattern),
action: {
indentAction: vscode.IndentAction.None,
removeText: comment.continue.length - comment.continue.trimLeft().length
}
};
}
}
return undefined;
}
// When the continue rule is different than the begin rule for single line comments
function getSLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let continuePattern: string = getSLBeginPattern(comment.begin);
if (continuePattern) {
return {
beforeText: new RegExp(continuePattern),
action: {
indentAction: vscode.IndentAction.None,
appendText: comment.continue.trimLeft()
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is after the continuation pattern plus at least one other character.
function getSLContinuationRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let continuePattern: string = getSLContinuePattern(comment.continue);
if (continuePattern) {
return {
beforeText: new RegExp(continuePattern),
action: {
indentAction: vscode.IndentAction.None,
appendText: comment.continue.trimLeft()
}
};
}
}
return undefined;
}
// When Enter is pressed while the cursor is immediately after the continuation pattern
function getSLEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined {
if (comment) {
let endPattern: string = getSLEndPattern(comment.continue);
if (endPattern) {
return {
beforeText: new RegExp(endPattern),
action: {
indentAction: vscode.IndentAction.None,
removeText: comment.continue.length - comment.continue.trimLeft().length
}
};
}
}
return undefined;
}
interface Rules {
begin: vscode.OnEnterRule[];
continue: vscode.OnEnterRule[];
end: vscode.OnEnterRule[];
}
export function getLanguageConfig(languageId: string, resource?: vscode.Uri): vscode.LanguageConfiguration {
let settings: CppSettings = new CppSettings(resource);
let patterns: (string | CommentPattern)[] = settings.commentContinuationPatterns;
return getLanguageConfigFromPatterns(languageId, patterns);
}
export function getLanguageConfigFromPatterns(languageId: string, patterns: (string | CommentPattern)[]): vscode.LanguageConfiguration {
let beginPatterns: string[] = []; // avoid duplicate rules
let continuePatterns: string[] = []; // avoid duplicate rules
let duplicates: boolean = false;
let beginRules: vscode.OnEnterRule[] = [];
let continueRules: vscode.OnEnterRule[] = [];
let endRules: vscode.OnEnterRule[] = [];
patterns.forEach(pattern => {
let c: CommentPattern = (typeof pattern === "string") ? { begin: pattern, continue: pattern.startsWith('/*') ? " * " : pattern } : <CommentPattern>pattern;
let r: Rules = constructCommentRules(c, languageId);
if (beginPatterns.indexOf(c.begin) < 0) {
if (r.begin && r.begin.length > 0) {
beginRules = beginRules.concat(r.begin);
}
beginPatterns.push(c.begin);
} else {
duplicates = true;
}
if (continuePatterns.indexOf(c.continue) < 0) {
if (r.continue && r.continue.length > 0) {
continueRules = continueRules.concat(r.continue);
}
if (r.end && r.end.length > 0) {
endRules = endRules.concat(r.end);
}
continuePatterns.push(c.continue);
}
});
if (duplicates) {
getOutputChannel().appendLine("Duplicate multiline comment patterns detected.");
}
return { onEnterRules: beginRules.concat(continueRules).concat(endRules).filter(e => (e)) }; // Remove any 'undefined' entries
}
function constructCommentRules(comment: CommentPattern, languageId: string): Rules {
if (comment && comment.begin && comment.begin.startsWith('/*') && (languageId === 'c' || languageId === 'cpp')) {
return {
begin: [
getMLSplitRule(comment),
getMLFirstLineRule(comment)
],
continue: [ getMLContinuationRule(comment) ],
end: [
getMLEmptyEndRule(comment),
getMLEndRule(comment)
]
};
} else if (comment && comment.begin && comment.begin.startsWith('//') && languageId === 'cpp') {
return {
begin: (comment.begin === comment.continue) ? [] : [ getSLFirstLineRule(comment) ],
continue: [ getSLContinuationRule(comment) ],
end: [ getSLEndRule(comment) ]
};
}
return {
begin: [],
continue: [],
end: []
};
}
-20
View File
@@ -5,7 +5,6 @@
'use strict';
import * as vscode from 'vscode';
import { CommentPattern } from './languageConfig';
function getTarget(): vscode.ConfigurationTarget {
return (vscode.workspace.workspaceFolders) ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Global;
@@ -39,36 +38,17 @@ export class CppSettings extends Settings {
public get intelliSenseEngine(): string { return super.Section.get<string>("intelliSenseEngine"); }
public get intelliSenseEngineFallback(): string { return super.Section.get<string>("intelliSenseEngineFallback"); }
public get errorSquiggles(): string { return super.Section.get<string>("errorSquiggles"); }
public get dimInactiveRegions(): boolean { return super.Section.get<boolean>("dimInactiveRegions"); }
public get autoComplete(): string { return super.Section.get<string>("autocomplete"); }
public get loggingLevel(): string { return super.Section.get<string>("loggingLevel"); }
public get navigationLength(): number { return super.Section.get<number>("navigation.length", 60); }
public get autoAddFileAssociations(): boolean { return super.Section.get<boolean>("autoAddFileAssociations"); }
public get workspaceParsingPriority(): boolean { return super.Section.get<boolean>("workspaceParsingPriority"); }
public get exclusionPolicy(): boolean { return super.Section.get<boolean>("exclusionPolicy"); }
public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); }
public get preferredPathSeparator(): string { return super.Section.get<string>("preferredPathSeparator"); }
public get defaultIncludePath(): string[] { return super.Section.get<string[]>("default.includePath"); }
public get defaultDefines(): string[] { return super.Section.get<string[]>("default.defines"); }
public get defaultMacFrameworkPath(): string[] { return super.Section.get<string[]>("default.macFrameworkPath"); }
public get defaultCompileCommands(): string { return super.Section.get<string>("default.compileCommands"); }
public get defaultForcedInclude(): string[] { return super.Section.get<string[]>("default.forcedInclude"); }
public get defaultIntelliSenseMode(): string { return super.Section.get<string>("default.intelliSenseMode"); }
public get defaultCompilerPath(): string { return super.Section.get<string>("default.compilerPath"); }
public get defaultCStandard(): string { return super.Section.get<string>("default.cStandard"); }
public get defaultCppStandard(): string { return super.Section.get<string>("default.cppStandard"); }
public get defaultBrowsePath(): string[] { return super.Section.get<string[]>("default.browse.path"); }
public get defaultDatabaseFilename(): string { return super.Section.get<string>("default.browse.databaseFilename"); }
public get defaultLimitSymbolsToIncludedHeaders(): boolean { return super.Section.get<boolean>("default.browse.limitSymbolsToIncludedHeaders"); }
public get defaultSystemIncludePath(): string[] { return super.Section.get<string[]>("default.systemIncludePath"); }
public toggleSetting(name: string, value1: string, value2: string): void {
let value: string = super.Section.get<string>(name);
super.Section.update(name, value === value1 ? value2 : value1, getTarget());
}
public update<T>(name: string, value: T): void {
super.Section.update(name, value);
}
}
export class OtherSettings {
@@ -1,190 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as vscode from 'vscode';
import * as util from '../common';
/**
* track settings changes for telemetry
*/
type FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean;
type KeyValuePair = { key: string; value: string };
const maxSettingLengthForTelemetry: number = 50;
let cache: SettingsTracker = undefined;
export class SettingsTracker {
private previousCppSettings: { [key: string]: any } = {};
private resource: vscode.Uri;
constructor(resource: vscode.Uri) {
this.resource = resource;
this.collectSettings(() => true);
}
public getUserModifiedSettings(): { [key: string]: string } {
let filter: FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => {
return !this.areEqual(val, settings.inspect(key).defaultValue);
};
return this.collectSettings(filter);
}
public getChangedSettings(): { [key: string]: string } {
let filter: FilterFunction = (key: string, val: string) => {
return !(key in this.previousCppSettings) || !this.areEqual(val, this.previousCppSettings[key]);
};
return this.collectSettings(filter);
}
private collectSettings(filter: FilterFunction): { [key: string]: string } {
let settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", this.resource);
let result: { [key: string]: string } = {};
for (let key in settings) {
let val: any = this.getSetting(settings, key);
if (val === undefined) {
continue;
}
if (val instanceof Object && !(val instanceof Array)) {
for (let subKey in val) {
let newKey: string = key + "." + subKey;
let subVal: any = this.getSetting(settings, newKey);
if (subVal === undefined) {
continue;
}
let entry: KeyValuePair = this.filterAndSanitize(newKey, subVal, settings, filter);
if (entry && entry.key && entry.value) {
result[entry.key] = entry.value;
}
}
continue;
}
let entry: KeyValuePair = this.filterAndSanitize(key, val, settings, filter);
if (entry && entry.key && entry.value) {
result[entry.key] = entry.value;
}
}
return result;
}
private getSetting(settings: vscode.WorkspaceConfiguration, key: string): any {
// Ignore methods and settings that don't exist
if (settings.inspect(key).defaultValue !== undefined) {
let val: any = settings.get(key);
if (val instanceof Object) {
return val; // It's a sub-section.
}
// Only return values that match the setting's type and enum (if applicable).
let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
if (curSetting) {
let type: string = this.typeMatch(val, curSetting["type"]);
if (type) {
if (type !== "string") {
return val;
}
let curEnum: any[] = curSetting["enum"];
if (curEnum && curEnum.indexOf(val) === -1) {
return "<invalid>";
}
return val;
}
}
}
return undefined;
}
private typeMatch(value: any, type?: string | string[]): string {
if (type) {
if (type instanceof Array) {
for (let i: number = 0; i < type.length; i++) {
let t: string = type[i];
if (t) {
if (typeof value === t) {
return t;
}
if (t === "array" && value instanceof Array) {
return t;
}
if (t === "null" && value === null) {
return t;
}
}
}
} else if (typeof type === "string" && typeof value === type) {
return type;
}
}
return undefined;
}
private filterAndSanitize(key: string, val: any, settings: vscode.WorkspaceConfiguration, filter: FilterFunction): KeyValuePair {
if (filter(key, val, settings)) {
let value: string;
this.previousCppSettings[key] = val;
switch (key) {
case "clang_format_style":
case "clang_format_fallbackStyle": {
let newKey: string = key + "2";
if (val) {
switch (String(val).toLowerCase()) {
case "visual studio":
case "llvm":
case "google":
case "chromium":
case "mozilla":
case "webkit":
case "file":
case "none": {
value = String(this.previousCppSettings[key]);
break;
}
default: {
value = "...";
break;
}
}
} else {
value = "null";
}
key = newKey;
break;
}
case "commentContinuationPatterns": {
value = this.areEqual(val, settings.inspect(key).defaultValue) ? "<default>" : "..."; // Track whether it's being used, but nothing specific about it.
break;
}
default: {
if (key === "clang_format_path" || 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]);
}
}
}
if (value && value.length > maxSettingLengthForTelemetry) {
value = value.substr(0, maxSettingLengthForTelemetry) + "...";
}
return {key: key, value: value};
}
}
private areEqual(value1: any, value2: any): boolean {
if (value1 instanceof Object && value2 instanceof Object) {
return JSON.stringify(value1) === JSON.stringify(value2);
}
return value1 === value2;
}
}
export function getTracker(resource: vscode.Uri): SettingsTracker {
if (!cache) {
cache = new SettingsTracker(resource);
}
return cache;
}
+6 -9
View File
@@ -43,7 +43,7 @@ export class UI {
this.browseEngineStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 0);
this.browseEngineStatusBarItem.text = "";
this.browseEngineStatusBarItem.tooltip = "Discovering files...";
this.browseEngineStatusBarItem.color = new vscode.ThemeColor("statusBar.foreground");
this.browseEngineStatusBarItem.color = "White";
this.browseEngineStatusBarItem.command = "C_Cpp.ShowParsingCommands";
this.ShowDBIcon = true;
}
@@ -110,15 +110,12 @@ export class UI {
public activeDocumentChanged(): void {
let activeEditor: vscode.TextEditor = vscode.window.activeTextEditor;
let isCpp: boolean = (activeEditor && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c"));
let show: boolean = (activeEditor && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c"));
// It's sometimes desirable to see the config and icons when making settings changes.
let isSettingsJson: boolean = (activeEditor && (activeEditor.document.fileName.endsWith("c_cpp_properties.json") || activeEditor.document.fileName.endsWith("settings.json")));
this.ShowConfiguration = isCpp || isSettingsJson;
this.ShowDBIcon = isCpp || isSettingsJson;
this.ShowFlameIcon = isCpp || isSettingsJson;
this.ShowNavigation = isCpp;
this.ShowConfiguration = show;
this.ShowDBIcon = show;
this.ShowFlameIcon = show;
this.ShowNavigation = show;
}
public bind(client: Client): void {
-34
View File
@@ -1,34 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
/**
* This file is used during local debugging of the extension and should not be referenced by any
* other source files.
*/
const fs = require("fs");
const cp = require("child_process");
const path = require("path");
if (!process.env.CPPTOOLS_DEV && fs.existsSync('./node_modules')) {
console.warn("WARNING: Skipping npm install since it appears to have been executed already.");
} else {
console.log(">> npm install");
cp.execSync("npm install", { stdio: [0, 1, 2] });
}
// Compile the TypeScript code
console.log(">> tsc -p ./");
cp.execSync("tsc -p ./", {stdio:[0, 1, 2]});
// If the required debugger file doesn't exist, make sure it is copied.
if (process.env.CPPTOOLS_DEV || !fs.existsSync('./debugAdapters/bin/cppdbg.ad7Engine.json')) {
const copyDebuggerDependenciesJSFile = './out/src/Support/copyDebuggerDependencies.js';
// Required for nightly builds. Nightly builds do not enable CPPTOOLS_DEV.
console.log(">> node " + copyDebuggerDependenciesJSFile);
cp.execSync("node " + copyDebuggerDependenciesJSFile, { stdio: [0, 1, 2] });
}
+7 -8
View File
@@ -35,7 +35,7 @@ function downloadCpptoolsJson(urlString): Promise<void> {
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.getHttpsProxyAgent(),
agent: util.GetHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true)
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
@@ -80,17 +80,16 @@ export function downloadCpptoolsJsonPkg(): Promise<void> {
export function processCpptoolsJson(cpptoolsString: string): Promise<void> {
let cpptoolsObject: any = JSON.parse(cpptoolsString);
let intelliSenseEnginePercentage: number = cpptoolsObject.intelliSenseEngine_default_percentage;
let packageJson: any = util.getRawPackageJson();
if (!packageJson.extensionFolderPath.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (!util.packageJson.extensionFolderPath.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (util.extensionContext.globalState.get<number>(userBucketString, userBucketMax + 1) <= intelliSenseEnginePercentage) {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
if (prevIntelliSenseEngineDefault !== util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
}
}
}
-2
View File
@@ -21,8 +21,6 @@ class TemporaryCommandRegistrar {
"C_Cpp.PeekDeclaration",
"C_Cpp.ToggleErrorSquiggles",
"C_Cpp.ToggleIncludeFallback",
"C_Cpp.ToggleDimInactiveRegions",
"C_Cpp.ToggleSnippets",
"C_Cpp.ShowReleaseNotes",
"C_Cpp.ResetDatabase",
"C_Cpp.PauseParsing",
+8 -90
View File
@@ -20,41 +20,17 @@ export function setExtensionContext(context: vscode.ExtensionContext): void {
extensionContext = context;
}
// Use this package.json to read values
export const packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
// Use getRawPackageJson to read and write back to package.json
// This prevents obtaining any of VSCode's expanded variables.
let rawPackageJson: any = null;
export function getRawPackageJson(): any {
if (rawPackageJson === null) {
const fileContents: Buffer = fs.readFileSync(getPackageJsonPath());
rawPackageJson = JSON.parse(fileContents.toString());
}
return rawPackageJson;
}
// This function is used to stringify the rawPackageJson.
// Do not use with util.packageJson or else the expanded
// package.json will be written back.
export function stringifyPackageJson(packageJson: string): string {
return JSON.stringify(packageJson, null, 2);
}
export let packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
export function getExtensionFilePath(extensionfile: string): string {
return path.resolve(extensionContext.extensionPath, extensionfile);
}
export function getPackageJsonPath(): string {
return getExtensionFilePath("package.json");
}
export function getVcpkgPathDescriptorFile(): string {
if (process.platform === 'win32') {
return path.join(process.env.LOCALAPPDATA, "vcpkg/vcpkg.path.txt");
} else {
return path.join(process.env.HOME, ".vcpkg/vcpkg.path.txt");
}
export function getPackageJsonString(): string {
packageJson.main = "./out/src/main"; // Needs to be reset, because the relative path is removed by VS Code.
return JSON.stringify(packageJson, null, 2);
}
// Extension is ready if install.lock exists and debugAdapters folder exist.
@@ -143,13 +119,10 @@ export function showReleaseNotes(): void {
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.file(getExtensionFilePath("ReleaseNotes.html")), vscode.ViewColumn.One, "C/C++ Extension Release Notes");
}
export function resolveVariables(input: string, additionalEnvironment: {[key: string]: string | string[]}): string {
if (!input) {
export function resolveVariables(input: string): string {
if (input === null) {
return "";
}
if (!additionalEnvironment) {
additionalEnvironment = {};
}
// Replace environment and configuration variables.
let regexp: RegExp = /\$\{((env|config)(.|:))?(.*?)\}/g;
@@ -161,18 +134,7 @@ export function resolveVariables(input: string, additionalEnvironment: {[key: st
}
let newValue: string = undefined;
switch (varType) {
case "env": {
let v: string | string[] = additionalEnvironment[name];
if (typeof v === "string") {
newValue = v;
} else if (input === match && v instanceof Array) {
newValue = v.join(";");
}
if (!newValue) {
newValue = process.env[name];
}
break;
}
case "env": { newValue = process.env[name]; break; }
case "config": {
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let keys: string[] = name.split('.');
@@ -220,7 +182,7 @@ export function getDebugAdaptersPath(file: string): string {
return path.resolve(getExtensionFilePath("debugAdapters"), file);
}
export function getHttpsProxyAgent(): HttpsProxyAgent {
export function GetHttpsProxyAgent(): HttpsProxyAgent {
let proxy: string = vscode.workspace.getConfiguration().get<string>('http.proxy');
if (!proxy) {
proxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;
@@ -288,28 +250,6 @@ export function checkFileExists(filePath: string): Promise<boolean> {
});
}
/** Test whether a directory exists */
export function checkDirectoryExists(dirPath: string): Promise<boolean> {
return new Promise((resolve, reject) => {
fs.stat(dirPath, (err, stats) => {
if (stats && stats.isDirectory()) {
resolve(true);
} else {
resolve(false);
}
});
});
}
/** Read the files in a directory */
export function readDir(dirPath: string): Promise<string[]> {
return new Promise((resolve) => {
fs.readdir(dirPath, (err, list) => {
resolve(list);
});
});
}
/** Test whether the lock file exists.*/
export function checkInstallLockFile(): Promise<boolean> {
return checkFileExists(getInstallLockPath());
@@ -468,26 +408,4 @@ export function checkDistro(platformInfo: PlatformInformation): void {
// or SunOS (the other platforms supported by node)
getOutputChannelLogger().appendLine(`Warning: Debugging has not been tested for this platform. ${getReadmeMessage()}`);
}
}
export async function unlinkPromise(fileName: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
fs.unlink(fileName, err => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
export async function renamePromise(oldName: string, newName: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
fs.rename(oldName, newName, err => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
+13 -22
View File
@@ -114,22 +114,18 @@ async function downloadAndInstallPackages(info: PlatformInformation): Promise<vo
let outputChannelLogger: Logger = getOutputChannelLogger();
outputChannelLogger.appendLine("Updating C/C++ dependencies...");
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger);
let statusItem: vscode.StatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger, statusItem);
return vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "C/C++ Extension",
cancellable: false
}, async (progress, token) => {
outputChannelLogger.appendLine('');
setInstallationStage('downloadPackages');
await packageManager.DownloadPackages();
outputChannelLogger.appendLine('');
setInstallationStage('downloadPackages');
await packageManager.DownloadPackages(progress);
outputChannelLogger.appendLine('');
setInstallationStage('installPackages');
await packageManager.InstallPackages();
outputChannelLogger.appendLine('');
setInstallationStage('installPackages');
await packageManager.InstallPackages(progress);
});
statusItem.dispose();
}
function makeBinariesExecutable(): Promise<void> {
@@ -286,14 +282,12 @@ async function finalizeExtensionActivation(): Promise<void> {
// Redownload cpptools.json after activation so it's not blocked.
// It'll be used after the extension reloads.
cpptoolsJsonUtils.downloadCpptoolsJsonPkg();
return cpptoolsJsonUtils.downloadCpptoolsJsonPkg();
}
function rewriteManifest(): Promise<void> {
// Replace activationEvents with the events that the extension should be activated for subsequent sessions.
let packageJson: any = util.getRawPackageJson();
packageJson.activationEvents = [
util.packageJson.activationEvents = [
"onLanguage:cpp",
"onLanguage:c",
"onCommand:extension.pickNativeProcess",
@@ -306,17 +300,14 @@ function rewriteManifest(): Promise<void> {
"onCommand:C_Cpp.PeekDeclaration",
"onCommand:C_Cpp.ToggleErrorSquiggles",
"onCommand:C_Cpp.ToggleIncludeFallback",
"onCommand:C_Cpp.ToggleDimInactiveRegions",
"onCommand:C_Cpp.ToggleSnippets",
"onCommand:C_Cpp.ShowReleaseNotes",
"onCommand:C_Cpp.ResetDatabase",
"onCommand:C_Cpp.PauseParsing",
"onCommand:C_Cpp.ResumeParsing",
"onCommand:C_Cpp.ShowParsingCommands",
"onCommand:C_Cpp.TakeSurvey",
"onDebug",
"workspaceContains:/.vscode/c_cpp_properties.json"
"onDebug"
];
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
}
+109 -123
View File
@@ -67,33 +67,24 @@ export class PackageManager {
public constructor(
private platformInfo: PlatformInformation,
private outputChannel?: Logger) {
private outputChannel?: Logger,
private statusItem?: vscode.StatusBarItem) {
// Ensure our temp files get cleaned up in case of error
tmp.setGracefulCleanup();
}
public DownloadPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
public DownloadPackages(): Promise<void> {
return this.GetPackages()
.then((packages) => {
let count: number = 1;
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
const p: Promise<void> = this.DownloadPackage(pkg, `${count}/${packages.length}`, progress);
count += 1;
return p;
});
return this.BuildPromiseChain(packages, (pkg) => this.DownloadPackage(pkg));
});
}
public InstallPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
public InstallPackages(): Promise<void> {
return this.GetPackages()
.then((packages) => {
let count: number = 1;
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
const p: Promise<void> = this.InstallPackage(pkg, `${count}/${packages.length}`, progress);
count += 1;
return p;
.then((packages) => {
return this.BuildPromiseChain(packages, (pkg) => this.InstallPackage(pkg));
});
});
}
/** Builds a chain of promises by calling the promiseBuilder function once per item in the list.
@@ -146,84 +137,80 @@ export class PackageManager {
});
}
private async DownloadPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
private DownloadPackage(pkg: IPackage): Promise<void> {
this.AppendChannel(`Downloading package '${pkg.description}' `);
progress.report({message: `Downloading ${progressCount}: ${pkg.description}`});
this.SetStatusText("$(cloud-download) Downloading packages...");
this.SetStatusTooltip(`Downloading package '${pkg.description}'...`);
const tmpResult: tmp.SyncResult = await this.CreateTempFile(pkg);
await this.DownloadPackageWithRetries(pkg, tmpResult, progress);
}
private async CreateTempFile(pkg: IPackage): Promise<tmp.SyncResult> {
return new Promise<tmp.SyncResult>((resolve, reject) => {
tmp.file({ prefix: "package-" }, (err, path, fd, cleanupCallback) => {
if (err) {
return reject(new PackageManagerError('Error from temp.file', 'DownloadPackage', pkg, err));
}
return resolve(<tmp.SyncResult>{ name: path, fd: fd, removeCallback: cleanupCallback });
resolve(<tmp.SyncResult>{ name: path, fd: fd, removeCallback: cleanupCallback });
});
});
}
})
.then((tmpResult) => {
pkg.tmpFile = tmpResult;
private async DownloadPackageWithRetries(pkg: IPackage, tmpResult: tmp.SyncResult, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
pkg.tmpFile = tmpResult;
let success: boolean = false;
let lastError: any = null;
let retryCount: number = 0;
const MAX_RETRIES: number = 5;
// Retry the download at most MAX_RETRIES times with 2-32 seconds delay.
do {
try {
await this.DownloadFile(pkg.url, pkg, retryCount, progress);
success = true;
} catch (error) {
retryCount += 1;
lastError = error;
if (retryCount >= MAX_RETRIES) {
this.AppendChannel(` Failed to download ` + pkg.url);
throw error;
} else {
// This will skip the success = true.
let lastError: any = null;
let retryCount: number = 0;
let handleDownloadFailure: (num: any, error: any) => void = (num, error) => {
retryCount = num;
lastError = error;
this.AppendChannel(` Failed. Retrying...`);
continue;
}
}
} while (!success && retryCount < MAX_RETRIES);
this.AppendLineChannel(" Done!");
if (retryCount !== 0) {
// Log telemetry to see if retrying helps.
let telemetryProperties: { [key: string]: string } = {};
telemetryProperties["success"] = `OnRetry${retryCount}`;
if (lastError instanceof PackageManagerError) {
let packageError: PackageManagerError = lastError;
telemetryProperties['error.methodName'] = packageError.methodName;
telemetryProperties['error.message'] = packageError.message;
if (packageError.pkg) {
telemetryProperties['error.packageName'] = packageError.pkg.description;
telemetryProperties['error.packageUrl'] = packageError.pkg.url;
}
if (packageError.errorCode) {
telemetryProperties['error.errorCode'] = packageError.errorCode;
}
}
Telemetry.logDebuggerEvent("acquisition", telemetryProperties);
}
};
// Retry the download at most 5 times with 2-32 seconds delay.
return this.DownloadFile(pkg.url, pkg, 0).catch((error) => {
handleDownloadFailure(1, error);
return this.DownloadFile(pkg.url, pkg, 1).catch((error) => {
handleDownloadFailure(2, error);
return this.DownloadFile(pkg.url, pkg, 2).catch((error) => {
handleDownloadFailure(3, error);
return this.DownloadFile(pkg.url, pkg, 3).catch((error) => {
handleDownloadFailure(4, error);
return this.DownloadFile(pkg.url, pkg, 4).catch((error) => {
handleDownloadFailure(5, error);
return this.DownloadFile(pkg.url, pkg, 5); // Last try, don't catch the error.
});
});
});
});
}).then(() => {
this.AppendLineChannel(" Done!");
if (retryCount !== 0) {
// Log telemetry to see if retrying helps.
let telemetryProperties: { [key: string]: string } = {};
telemetryProperties["success"] = `OnRetry${retryCount}`;
if (lastError instanceof PackageManagerError) {
let packageError: PackageManagerError = lastError;
telemetryProperties['error.methodName'] = packageError.methodName;
telemetryProperties['error.message'] = packageError.message;
if (packageError.pkg) {
telemetryProperties['error.packageName'] = packageError.pkg.description;
telemetryProperties['error.packageUrl'] = packageError.pkg.url;
}
if (packageError.errorCode) {
telemetryProperties['error.errorCode'] = packageError.errorCode;
}
}
Telemetry.logDebuggerEvent("acquisition", telemetryProperties);
}
});
});
}
// reloadCpptoolsJson in main.ts uses ~25% of this function.
private DownloadFile(urlString: any, pkg: IPackage, delay: number, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
private DownloadFile(urlString: any, pkg: IPackage, delay: number): Promise<void> {
let parsedUrl: url.Url = url.parse(urlString);
let proxyStrictSSL: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true);
let options: https.RequestOptions = {
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.getHttpsProxyAgent(),
agent: util.GetHttpsProxyAgent(),
rejectUnauthorized: proxyStrictSSL
};
@@ -249,7 +236,7 @@ export class PackageManager {
} else {
redirectUrl = response.headers.location[0];
}
return resolve(this.DownloadFile(redirectUrl, pkg, 0, progress));
return resolve(this.DownloadFile(redirectUrl, pkg, 0));
} else if (response.statusCode !== 200) {
// Download failed - print error message
let errorMessage: string = `failed (error code '${response.statusCode}')`;
@@ -263,6 +250,7 @@ export class PackageManager {
contentLength = response.headers['content-length'][0];
}
let packageSize: number = parseInt(contentLength, 10);
let downloadedBytes: number = 0;
let downloadPercentage: number = 0;
let dots: number = 0;
let tmpFile: fs.WriteStream = fs.createWriteStream(null, { fd: pkg.tmpFile.fd });
@@ -270,6 +258,15 @@ export class PackageManager {
this.AppendChannel(`(${Math.ceil(packageSize / 1024)} KB) `);
response.on('data', (data) => {
downloadedBytes += data.length;
// Update status bar item with percentage
let newPercentage: number = Math.ceil(100 * (downloadedBytes / packageSize));
if (newPercentage !== downloadPercentage) {
this.SetStatusTooltip(`Downloading package '${pkg.description}'... ${downloadPercentage}%`);
downloadPercentage = newPercentage;
}
// Update dots after package name in output console
let newDots: number = Math.ceil(downloadPercentage / 5);
if (newDots > dots) {
@@ -279,11 +276,11 @@ export class PackageManager {
});
response.on('end', () => {
return resolve();
resolve();
});
response.on('error', (error) => {
return reject(new PackageManagerWebResponseError(response.socket, 'HTTP/HTTPS Response error', 'DownloadFile', pkg, error.stack, error.name));
reject(new PackageManagerWebResponseError(response.socket, 'HTTP/HTTPS Response error', 'DownloadFile', pkg, error.stack, error.name));
});
// Begin piping data from the response to the package file
@@ -294,7 +291,7 @@ export class PackageManager {
let request: ClientRequest = https.request(options, handleHttpResponse);
request.on('error', (error) => {
return reject(new PackageManagerError('HTTP/HTTPS Request error' + (urlString.includes("fwlink") ? ": fwlink" : ""), 'DownloadFile', pkg, error.stack, error.message));
reject(new PackageManagerError('HTTP/HTTPS Request error' + (urlString.includes("fwlink") ? ": fwlink" : ""), 'DownloadFile', pkg, error.stack, error.message));
});
// Execute the request
@@ -303,10 +300,11 @@ export class PackageManager {
});
}
private InstallPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
private InstallPackage(pkg: IPackage): Promise<void> {
this.AppendLineChannel(`Installing package '${pkg.description}'`);
progress.report({message: `Installing ${progressCount}: ${pkg.description}`});
this.SetStatusText("$(desktop-download) Installing packages...");
this.SetStatusTooltip(`Installing package '${pkg.description}'`);
return new Promise<void>((resolve, reject) => {
if (!pkg.tmpFile || pkg.tmpFile.fd === 0) {
@@ -318,15 +316,6 @@ export class PackageManager {
return reject(new PackageManagerError('Zip file error', 'InstallPackage', pkg, err));
}
// setup zip file events
zipfile.on('end', () => {
return resolve();
});
zipfile.on('error', err => {
return reject(new PackageManagerError('Zip File Error', 'InstallPackage', pkg, err, err.code));
});
zipfile.readEntry();
zipfile.on('entry', (entry: yauzl.Entry) => {
@@ -345,52 +334,26 @@ export class PackageManager {
util.checkFileExists(absoluteEntryPath).then((exists: boolean) => {
if (!exists) {
// File - extract it
zipfile.openReadStream(entry, (err, readStream: fs.ReadStream) => {
zipfile.openReadStream(entry, (err, readStream) => {
if (err) {
return reject(new PackageManagerError('Error reading zip stream', 'InstallPackage', pkg, err));
}
readStream.on('error', (err) => {
return reject(new PackageManagerError('Error in readStream', 'InstallPackage', pkg, err));
});
mkdirp.mkdirp(path.dirname(absoluteEntryPath), { mode: 0o775 }, async (err) => {
mkdirp.mkdirp(path.dirname(absoluteEntryPath), { mode: 0o775 }, (err) => {
if (err) {
return reject(new PackageManagerError('Error creating directory', 'InstallPackage', pkg, err, err.code));
}
// Create as a .tmp file to avoid partially unzipped files
// counting as completed files.
let absoluteEntryTempFile: string = absoluteEntryPath + ".tmp";
if (fs.existsSync(absoluteEntryTempFile)) {
try {
await util.unlinkPromise(absoluteEntryTempFile);
} catch (err) {
return reject(new PackageManagerError(`Error unlinking file ${absoluteEntryTempFile}`, 'InstallPackage', pkg, err));
}
}
// Make sure executable files have correct permissions when extracted
let fileMode: number = (pkg.binaries && pkg.binaries.indexOf(absoluteEntryPath) !== -1) ? 0o755 : 0o664;
let writeStream: fs.WriteStream = fs.createWriteStream(absoluteEntryTempFile, { mode: fileMode });
writeStream.on('close', async () => {
try {
// Remove .tmp extension from the file.
await util.renamePromise(absoluteEntryTempFile, absoluteEntryPath);
} catch (err) {
return reject(new PackageManagerError(`Error renaming file ${absoluteEntryTempFile}`, 'InstallPackage', pkg, err));
}
let writeStream: fs.WriteStream = fs.createWriteStream(absoluteEntryPath, { mode: fileMode });
readStream.pipe(writeStream);
writeStream.on('close', () => {
// Wait till output is done writing before reading the next zip entry.
// Otherwise, it's possible to try to launch the .exe before it is done being created.
zipfile.readEntry();
});
writeStream.on('error', (err) => {
return reject(new PackageManagerError('Error in writeStream', 'InstallPackage', pkg, err));
});
readStream.pipe(writeStream);
});
});
} else {
@@ -403,11 +366,20 @@ export class PackageManager {
});
}
});
zipfile.on('end', () => {
resolve();
});
zipfile.on('error', err => {
reject(new PackageManagerError('Zip File Error', 'InstallPackage', pkg, err, err.code));
});
});
})
.then(() => {
// Clean up temp file
pkg.tmpFile.removeCallback();
});
}).then(() => {
// Clean up temp file
pkg.tmpFile.removeCallback();
});
}
private AppendChannel(text: string): void {
@@ -421,4 +393,18 @@ export class PackageManager {
this.outputChannel.appendLine(text);
}
}
private SetStatusText(text: string): void {
if (this.statusItem) {
this.statusItem.text = text;
this.statusItem.show();
}
}
private SetStatusTooltip(text: string): void {
if (this.statusItem) {
this.statusItem.tooltip = text;
this.statusItem.show();
}
}
}
@@ -20,12 +20,8 @@ suite(`Debug Integration Test: `, function() {
let debugSessionTerminated = new Promise(resolve => {
vscode.debug.onDidTerminateDebugSession((e) => resolve());
});
try {
assert.equal(vscode.debug.activeDebugSession.type, "cppdbg");
} catch (e) {
assert.fail("Debugger failed to launch. Did the extension activate correctly?")
}
assert.equal(vscode.debug.activeDebugSession.type, "cppdbg");
await debugSessionTerminated;
});
@@ -1,131 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as assert from 'assert';
import { getLanguageConfigFromPatterns } from '../../src/LanguageServer/languageConfig';
import * as config from '../../src/LanguageServer/configurations';
import { CppSettings } from '../../src/LanguageServer/settings';
suite("multiline comment setting tests", function() {
suiteSetup(async function() {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
}
});
let defaultRules: vscode.OnEnterRule[] = [
{
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: ' * ' }
},
{
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
action: { indentAction: vscode.IndentAction.None, appendText: ' * ' }
},
{
beforeText: /^\s*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
action: { indentAction: vscode.IndentAction.None, appendText: '* ' }
},
{
beforeText: /^\s*\*\/\s*$/,
action: { indentAction: vscode.IndentAction.None, removeText: 1 }
},
{
beforeText: /^\s*\*[^/]*\*\/\s*$/,
action: { indentAction: vscode.IndentAction.None, removeText: 1 }
}
];
let defaultSLRules: vscode.OnEnterRule[] = [
{
beforeText: /^\s*\/\/\/.+$/,
action: { indentAction: vscode.IndentAction.None, appendText: '///' }
},
{
beforeText: /^\s*\/\/\/$/,
action: { indentAction: vscode.IndentAction.None, removeText: 0 }
}
];
test("Check the default OnEnterRules for C", () => {
let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**" ]).onEnterRules;
assert.deepEqual(rules, defaultRules);
});
test("Check for removal of single line comment continuations for C", () => {
let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**", "///" ]).onEnterRules;
assert.deepEqual(rules, defaultRules);
});
test("Check the default OnEnterRules for C++", () => {
let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**" ]).onEnterRules;
assert.deepEqual(rules, defaultRules);
});
test("Make sure duplicate rules are removed", () => {
let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**", { begin: "/**", continue: " * " }, "/**" ]).onEnterRules;
assert.deepEqual(rules, defaultRules);
});
test("Check single line rules for C++", () => {
let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "///" ]).onEnterRules;
assert.deepEqual(rules, defaultSLRules);
});
});
/*
suite("configuration tests", function() {
suiteSetup(async function() {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
}
// Open a c++ file to start the language server.
await vscode.workspace.openTextDocument({ language: "cpp", content: "int main() { return 0; }"});
});
suiteTeardown(async function() {
// Delete c_cpp_properties.json
});
test("Check default configuration", () => {
let rootUri: vscode.Uri;
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
rootUri = vscode.workspace.workspaceFolders[0].uri;
}
assert.notEqual(rootUri, undefined, "Root Uri is not defined");
if (rootUri) {
let cppProperties: config.CppProperties = new config.CppProperties(rootUri);
let configurations: config.Configuration[] = cppProperties.Configurations;
let defaultConfig: config.Configuration = config.getDefaultConfig();
assert.deepEqual(configurations[0], defaultConfig);
console.log(JSON.stringify(configurations, null, 2));
// Need to set the CompilerDefaults before the CppProperties can be successfully modified.
cppProperties.CompilerDefaults = {
compilerPath: "/path/to/compiler",
cStandard: "c99",
cppStandard: "c++14",
frameworks: ["/path/to/framework"],
includes: ["/path/to/includes"]
};
configurations[0].cppStandard = "${default}";
let s: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp.default", rootUri);
let d: any = s.inspect("cppStandard");
s.update("cppStandard", "c++11", vscode.ConfigurationTarget.WorkspaceFolder);
d = s.inspect("cppStandard");
cppProperties.onDidChangeSettings();
}
});
});
*/
-123
View File
@@ -1,123 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as os from 'os';
function appendFieldsToObject(reference: any, obj: any): any {
// Make sure it is an object type
if (typeof obj === 'object') {
for (let referenceKey in reference) {
// If key exists in original object and is an object.
if (obj.hasOwnProperty(referenceKey)) {
obj[referenceKey] = appendFieldsToObject(reference[referenceKey], obj[referenceKey]);
} else {
// Does not exist in current object context
obj[referenceKey] = reference[referenceKey];
}
}
}
return obj;
}
// Combines two object's fields, giving the parentDefault a higher precedence.
function mergeDefaults(parentDefault: any, childDefault: any): any {
let newDefault: any = {};
for (let attrname in childDefault) {
newDefault[attrname] = childDefault[attrname];
}
for (let attrname in parentDefault) {
newDefault[attrname] = parentDefault[attrname];
}
return newDefault;
}
function updateDefaults(object: any, defaults: any): any {
if (defaults !== null) {
for (let key in object) {
if (object[key].hasOwnProperty('type') && object[key].type === 'object' && object[key].properties !== null) {
object[key].properties = updateDefaults(object[key].properties, mergeDefaults(defaults, object[key].default));
} else if (key in defaults) {
object[key].default = defaults[key];
}
}
}
return object;
}
function refReplace(definitions: any, ref: any): any {
// $ref is formatted as "#/definitions/ObjectName"
let referenceStringArray: string[] = ref['$ref'].split('/');
// Getting "ObjectName"
let referenceName: string = referenceStringArray[referenceStringArray.length - 1];
// Make sure reference has replaced its own $ref fields and hope there are no recursive references.
definitions[referenceName] = replaceReferences(definitions, definitions[referenceName]);
// Retrieve ObjectName from definitions. (TODO: Does not retrieve inner objects)
// Need to deep copy, there are no functions in these objects.
let reference: any = JSON.parse(JSON.stringify(definitions[referenceName]));
ref = appendFieldsToObject(reference, ref);
// Remove $ref field
delete ref['$ref'];
return ref;
}
function replaceReferences(definitions: any, objects: any): any {
for (let key in objects) {
if (objects[key].hasOwnProperty('$ref')) {
objects[key] = refReplace(definitions, objects[key]);
}
// Recursively replace references if this object has properties.
if (objects[key].hasOwnProperty('type') && objects[key].type === 'object' && objects[key].properties !== null) {
objects[key].properties = replaceReferences(definitions, objects[key].properties);
objects[key].properties = updateDefaults(objects[key].properties, objects[key].default);
}
// Recursively replace references if the array has objects in items.
if (objects[key].hasOwnProperty('type') && objects[key].type === "array" && objects[key].items !== null && objects[key].items.hasOwnProperty('$ref')) {
objects[key].items = refReplace(definitions, objects[key].items);
}
}
return objects;
}
export function generateOptionsSchema(): void {
let packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString());
let schemaJSON: any = JSON.parse(fs.readFileSync('tools/OptionsSchema.json').toString());
schemaJSON.definitions = replaceReferences(schemaJSON.definitions, schemaJSON.definitions);
// Hard Code adding in configurationAttributes launch and attach.
// cppdbg
packageJSON.contributes.debuggers[0].configurationAttributes.launch = schemaJSON.definitions.CppdbgLaunchOptions;
packageJSON.contributes.debuggers[0].configurationAttributes.attach = schemaJSON.definitions.CppdbgAttachOptions;
// cppvsdbg
packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.CppvsdbgLaunchOptions;
packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.CppvsdbgAttachOptions;
let content: string = JSON.stringify(packageJSON, null, 2);
if (os.platform() === 'win32') {
content = content.replace(/\n/gm, "\r\n");
}
// We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will
// convert that from the readable espace sequence, to just an invisible character. Convert it back to the visible espace sequence.
content = content.replace(/\u200b/gm, "\\u200b");
fs.writeFileSync('package.json', content);
}
-546
View File
@@ -1,546 +0,0 @@
{
"_comment": "See README.md for information about this file",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "VS Code launch/attach options",
"description": "A json schema for the VS Code attach and launch options",
"type": "object",
"definitions": {
"PipeTransport": {
"type": "object",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"default": {
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
"type": "string",
"description": "The fully qualified path to the working directory for the pipe program.",
"default": "/usr/bin"
},
"pipeProgram": {
"type": "string",
"description": "The fully qualified pipe command to execute.",
"default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'"
},
"pipeArgs": {
"type": "array",
"description": "Command line arguments passed to the pipe program to configure the connection.",
"items": {
"type": "string"
},
"default": []
},
"debuggerPath": {
"type": "string",
"description": "The full path to the debugger on the target machine, for example /usr/bin/gdb.",
"default": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"pipeEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Environment variables passed to the pipe program.",
"default": {}
}
}
},
"Logging": {
"type": "object",
"default": {},
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic engine logs should be logged to the Debug Console. Defaults to false.",
"default": false
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
},
"traceResponse": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
},
"SetupCommandsConfiguration": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The debugger command to execute.",
"default": ""
},
"description": {
"type": "string",
"description": "Optional description for the command.",
"default": ""
},
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
}
}
},
"KeyValuePair": {
"type": "object",
"properties": {
"name": "string",
"value": "string"
}
},
"CppdbgLaunchOptions": {
"type": "object",
"required": [
"program"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"cwd": {
"type": "string",
"description": "The working directory of the target",
"default": "."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"customLaunchSetupCommands": {
"type": "array",
"description": "If provided, this replaces the default commands used to launch a target with some other commands. For example, this can be \"-target-attach\" in order to attach to a target process. An empty command list replaces the launch commands with nothing, which can be useful if the debugger is being provided launch options as command line options. Example: \"customLaunchSetupCommands\": [ { \"text\": \"target-run\", \"description\": \"run target\", \"ignoreFailures\": false }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"launchCompleteCommand": {
"enum": [
"exec-run",
"exec-continue",
"None"
],
"description": "The command to execute after the debugger is fully setup in order to cause the target process to run. Allowed values are \"exec-run\", \"exec-continue\", \"None\". The default value is \"exec-run\".",
"default": "exec-run"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"debugServerPath": {
"type": "string",
"description": "Optional full path to debug server to launch. Defaults to null.",
"default": ""
},
"debugServerArgs": {
"type": "string",
"description": "Optional debug server args. Defaults to null.",
"default": ""
},
"serverStarted": {
"type": "string",
"description": "Optional server-started pattern to look for in the debug server output. Defaults to null.",
"default": ""
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"serverLaunchTimeout": {
"type": "integer",
"description": "Optional time, in milliseconds, for the debugger to wait for the debugServer to start up. Default is 10000.",
"default": "10000"
},
"coreDumpPath": {
"type": "string",
"description": "Optional full path to a core dump file for the specified program. Defaults to null.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched. Note this option is ignored in some cases for technical reasons.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
}
}
},
"CppdbgAttachOptions": {
"type": "object",
"required": [
"program",
"processId"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"processId": {
"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.",
"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.",
"default": 0
}
]
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
}
}
},
"CppvsdbgLaunchOptions": {
"type": "object",
"required": [
"program",
"cwd"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/program.exe"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"cwd": {
"type": "string",
"description": "The working directory of the target.",
"default": "${workspaceRoot}"
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"dumpPath": {
"type": "string",
"description": "Optional full path to a dump file for the specified program. Example: \"c:\\temp\\app.dmp\". Defaults to null.",
"default": ""
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic debug engine messages should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
},
"CppvsdbgAttachOptions": {
"type": "object",
"required": [
"processId"
],
"properties": {
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"processId": {
"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.",
"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.",
"default": 0
}
]
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
}
}
}
-14
View File
@@ -1,14 +0,0 @@
# OptionsSchema
OptionsSchema.json defines the type for Launch/Attach options.
# GenerateOptionsSchema
If there are any modifications to the OptionsSchema.json file. Please run `npm run generateOptionsSchema` at the repo root.
This will call GenerateOptionsSchema and update the package.json file.
### Important notes:
1. Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes (cppdbg) or object.contributes.debuggers[0].configurationAttributes (cppvsdbg) will be
replaced by this generator.
If there is any other type of options added in the future, you will need to modify the GenerateOptionsSchema function
to have it appear in package.json. It only adds launch and attach.
+1 -10
View File
@@ -1,11 +1,6 @@
{
"rules": {
"curly": true,
"ext-variable-name": [
true,
["class", "pascal"],
["function", "camel"]
],
"file-header": [true, ".*"],
"indent": [true, "spaces", 4],
"new-parens": true,
@@ -23,9 +18,5 @@
"typedef": [true, "variable-declaration", "call-signature"],
"whitespace": [true, "check-branch", "check-operator", "check-separator", "check-preblock", "check-type"]
},
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib",
"node_modules/tslint-no-unused-expression-chai/rules",
"node_modules/vrsource-tslint-rules/rules"
]
"rulesDirectory": ["node_modules/tslint-microsoft-contrib", "node_modules/tslint-no-unused-expression-chai/rules"]
}
-7
View File
@@ -1,10 +1,4 @@
<!--
If this is a performance issue report, please use the VS Code Issue reporter via command palette (f1 -> Help: Report Issue).
Set the field 'This is a' to be 'Performance Issue', the field 'File on' to be 'An Extension', and set 'Extension' to be 'C/C++'.
You may toggle off the data you wish to not send, but with more information we can help.
Fill out the title and steps to reproduce with as much info as you can.
Clicking on 'Preview on GitHub' will open up a webpage for you to submit your issue.
If this is a bug report, please give us as much information as possible so we can reproduce your issue.
Examples of information that can help us find and fix bugs:
* Operating System and version
@@ -15,7 +9,6 @@
* A small code sample, zipped up project, or open source repo we can use to verify the bug
* Relevant settings from your settings.json, c_cpp_properties.json, and/or launch.json files
* Any log messages present in the Output window (use "C_Cpp.loggingLevel": "Information" in settings.json)
* Debugger logs (use "logging": { "engineLogging": true } in your launch.json)
Please also take a look at our documentation, as we may already have answers for your questions:
* https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation
+5 -21
View File
@@ -1,31 +1,15 @@
# vscode-cpptools
This is the official repository for the [Microsoft C/C++ extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).
The `vscode-cpptools` repository is where we do development and there are many ways you can support the extension, for example:
* [Report issues or request features](https://github.com/Microsoft/vscode-cpptools/issues)
- If someone has filed a similar issue, please provide any additional information that can help us resolve it on the issue
- If someone has filed a similar feature request, please leave a thumbs up reaction on the issue
- [List of popular feature requests](https://github.com/Microsoft/vscode-cpptools/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3A%22Feature+Request%22)
* [Contribute to the extension](Extension)
## Getting Started
You can learn how to use the extension at [VS Code for C/C++](https://code.visualstudio.com/docs/languages/cpp).
If you clone this repository, you can also try out our [Code Samples](Code%20Samples).
If you have any questions, check out our [**Documentation**](Documentation) folder. If you do not find your answer there, feel free to ask it in our [issues page](https://github.com/Microsoft/vscode-cpptools/issues).
### Contribution
Contributions are always welcome. Please see our [contributing guide](CONTRIBUTING.md) for more details.
This is the official repository for filing issues against and getting support for the [Microsoft C/C++ extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).
### Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments.
### Documentation
The documentation has been moved to the [**Documentation**](Documentation) folder. If you would like to contribute, please create a Markdown file and submit a pull request.
### Data/Telemetry
This project collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://privacy.microsoft.com/en-us/privacystatement) to learn more.
+1 -1
View File
@@ -70,7 +70,7 @@ Set or change the following options to control VS Code's behavior during debuggi
The following options enable you to modify the state of the target application when it is launched:
* #### `args`
JSON array of command line arguments to pass to the program when it is launched. Example `["arg1", "arg2"]`. If you are escaping characters you will need to double escape them. For example `["{\\\"arg\\\": true}]` will send `{"arg1": true}` to your application.
JSON array of command line arguments to pass to the program when it is launched. Example `["arg1", "arg2]`.
* #### `cwd`
Sets the the working directory of the application launched by the debugger.