Compare commits

..
Author SHA1 Message Date
Sergio Ramirez 294a751210 Adding additional parse checking logic to determine if idle state has no pending calls and finished workspace parsing, file parsing, and intellisense updates. 2026-04-23 13:55:35 -07:00
f6cc1fbd03 Cherry-picks and changelog update for 1.31.5 release (#14393)
* Bump @xmldom/xmldom from 0.8.11 to 0.8.12 in /Extension (#14340)

Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.11 to 0.8.12.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.8.11...0.8.12)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Set context flag for when C++ language server is activated (#14382)

The primary purpose of this is for this flag to be consumed by the C++ devtools extensions. This way the C++ specific Copilot tools will only appear in tools list and register when the C++ language server is actually activated.

* Update lodash. (#14350)

* Bump picomatch from 2.3.1 to 2.3.2 in /ExtensionPack (#14318)

Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump picomatch from 2.3.1 to 2.3.2 in /.github/actions (#14319)

Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sean McManus <[email protected]>

* Bump picomatch from 2.3.1 to 2.3.2 in /Themes (#14323)

Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update picomatch. (#14324)

* Update brace-expansion v5. (#14325)

* Update brace-expansion and serialize-javascript. (#14328)

* Bump serialize-javascript from 7.0.4 to 7.0.5 in /.github/actions (#14332)

Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 7.0.4 to 7.0.5.
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v7.0.4...v7.0.5)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 7.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update brace-expansion for other folders (#14333)

* Update brace-expansion for other folders.

* Fix Reinstalling the Extension.md not being included. (#14390)

* Update for 1.31.5.

* Fix typo in changelog.

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Raygoza <[email protected]>
2026-04-17 13:54:52 -07:00
Sean McManus e0bd199546 Fix typo in changelog. 2026-04-17 13:50:32 -07:00
Sean McManus bc914dc69c Update for 1.31.5. 2026-04-17 13:42:38 -07:00
Sean McManus b2f5c605c4 Fix Reinstalling the Extension.md not being included. (#14390) 2026-04-17 13:33:21 -07:00
Sean McManus d41e14fd86 Update brace-expansion for other folders (#14333)
* Update brace-expansion for other folders.
2026-04-17 13:32:51 -07:00
dependabot[bot] 35c0fd37e2 Bump serialize-javascript from 7.0.4 to 7.0.5 in /.github/actions (#14332)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 7.0.4 to 7.0.5.
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v7.0.4...v7.0.5)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 7.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 13:32:27 -07:00
Sean McManus 99259bf194 Update brace-expansion and serialize-javascript. (#14328) 2026-04-17 13:32:04 -07:00
Sean McManus 10c1e1b606 Update brace-expansion v5. (#14325) 2026-04-17 13:31:37 -07:00
Sean McManus fcdb6efbab Update picomatch. (#14324) 2026-04-17 13:31:06 -07:00
dependabot[bot] bd5f6c0462 Bump picomatch from 2.3.1 to 2.3.2 in /Themes (#14323)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 13:30:35 -07:00
dependabot[bot]andSean McManus 9c45e4d2bc Bump picomatch from 2.3.1 to 2.3.2 in /.github/actions (#14319)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sean McManus <[email protected]>
2026-04-17 13:30:17 -07:00
dependabot[bot] 31f6b66e6b Bump picomatch from 2.3.1 to 2.3.2 in /ExtensionPack (#14318)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 13:29:57 -07:00
Sean McManus 4404bf76a7 Update lodash. (#14350) 2026-04-17 13:27:28 -07:00
David Raygoza 133896eb4c Set context flag for when C++ language server is activated (#14382)
The primary purpose of this is for this flag to be consumed by the C++ devtools extensions. This way the C++ specific Copilot tools will only appear in tools list and register when the C++ language server is actually activated.
2026-04-17 13:26:21 -07:00
dependabot[bot] 376562ee75 Bump @xmldom/xmldom from 0.8.11 to 0.8.12 in /Extension (#14340)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.11 to 0.8.12.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.8.11...0.8.12)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 13:25:03 -07:00
Sean McManusanddependabot[bot] 668b33c1e5 Cherry pick to resolve security warning (#14388)
* Bump axios from 1.13.6 to 1.15.0 in /.github/actions (#14365)

Bumps [axios](https://github.com/axios/axios) from 1.13.6 to 1.15.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.13.6...v1.15.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.15.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump follow-redirects from 1.15.11 to 1.16.0 in /.github/actions (#14376)

Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.11 to 1.16.0.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.11...v1.16.0)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-version: 1.16.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 15:40:35 -07:00
dependabot[bot] 6317e27e45 Bump follow-redirects from 1.15.11 to 1.16.0 in /.github/actions (#14376)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.11 to 1.16.0.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.11...v1.16.0)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-version: 1.16.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 15:33:53 -07:00
dependabot[bot] 223a3e2cbe Bump axios from 1.13.6 to 1.15.0 in /.github/actions (#14365)
Bumps [axios](https://github.com/axios/axios) from 1.13.6 to 1.15.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.13.6...v1.15.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.15.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 15:33:10 -07:00
Sean McManus 5b000d939b Merge pull request #14339 from microsoft/seanmcm/1_31_4_release
Update changelog for 1.31.4. (#14338)
2026-03-31 15:19:40 -07:00
Sean McManus b6b11027da Update changelog for 1.31.4. (#14338) 2026-03-31 15:18:17 -07:00
Sean McManus e22017f6df Merge pull request #14315 from microsoft/seanmcm/1_31_3_release2
Merge for 1.31.3 (again)
2026-03-23 12:06:23 -07:00
Sean McManus a2f6a72aed Merge branch 'main' into seanmcm/1_31_3_release2 2026-03-23 12:04:48 -07:00
Sean McManus 593ed07c56 Merge pull request #14300 from microsoft/seanmcm/1_31_1_release2
Merge for 1.31.3 (2nd time)
2026-03-19 11:16:39 -07:00
Sean McManus 40f7455acd Merge branch 'main' into seanmcm/1_31_1_release2 2026-03-19 11:03:43 -07:00
Sean McManus adf4681ef8 Merge pull request #14291 from microsoft/seanmcm/1_31_3_release
Merge for 1.31.3
2026-03-17 14:13:30 -07:00
Sean McManus a53dac8bef Merge branch 'main' into seanmcm/1_31_3_release 2026-03-17 13:40:46 -07:00
Sean McManus 04c60c288a Merge branch 'main' into seanmcm/1_31_3_release 2026-03-17 13:06:35 -07:00
Sean McManus fa71378712 Merge pull request #14252 from microsoft/seanmcm/updateRelease_1_31_1
Update release with 1.31.1 (to enable a release build for compliance checks)
2026-03-10 16:02:43 -07:00
Sean McManus 36a78e89e1 Merge branch 'main' into seanmcm/updateRelease_1_31_1 2026-03-10 14:13:04 -07:00
Sean McManus 364ba2789c Change the version to 1.30.5 to block publishing via skip-duplicate 2026-03-09 12:30:41 -07:00
Sean McManus 8d5fc737b1 Merge branch 'main' into seanmcm/updateRelease_1_31_1 2026-03-09 12:09:12 -07:00
Sean McManus 1172405856 Merge pull request #14238 from microsoft/seanmcm/cherryPicka5d00e31230bdad1d171d1fd1421ac97fa77b275
Switch vsix packing to use Nuget.config (#14209)
2026-03-04 16:55:47 -08:00
Sean McManus b013b10b64 Switch vsix packing to use Nuget.config (#14209)
* Add a NuGet.config file
2026-03-04 15:38:01 -08:00
Sean McManus c6ff700da2 Update changelog for 1.30.5 (#14171) (#14172)
* Update changelog for 1.30.5.
2026-02-06 15:13:39 -08:00
Sean McManus 936e7e3b15 Update changelog for 1.30.5 (#14171)
* Update changelog for 1.30.5.
2026-02-06 15:11:58 -08:00
Sean McManus e7e2e3983f Merge pull request #14166 from microsoft/main
Update changelog and version for 1.30.4. (#14165)
2026-02-03 11:28:43 -08:00
Sean McManus 80a6d16f83 Merge pull request #14153 from microsoft/seanmcm/1_30_3_release
Merge for 1.30.3 (release)
2026-01-29 17:55:46 -08:00
Sean McManus e5a976f229 Merge branch 'main' into seanmcm/1_30_3_release 2026-01-29 17:34:25 -08:00
Sean McManus 70fbfd71e1 Merge pull request #14095 from microsoft/seanmcm/1_29_3_release
Cherry-picks for 1.29.3
2025-12-08 16:12:24 -08:00
Sean McManus 5b3b56c694 Update changelog for 1.29.3. (#14093)
* Update changelog for 1.29.3.
2025-12-08 15:22:01 -08:00
Bob Brown 777ff002f1 Don't require NETFXSDKDir for msvc environment test (#14088) 2025-12-08 15:21:24 -08:00
Bob Brown 8de8679b3e Merge pull request #14075 from microsoft/revert-14074-fix/comment-continuation-pattern
Revert "Fix custom comment continuation for multiple follow-up lines"
2025-12-02 18:49:08 +00:00
Bob Brown e02269ba89 Revert "Fix custom comment continuation for multiple follow-up lines (#14074)"
This reverts commit 7852d4587c.
2025-12-02 10:03:40 -08:00
dinhtam2c 7852d4587c Fix custom comment continuation for multiple follow-up lines (#14074) 2025-12-02 09:57:50 -08:00
a1cb1d8bec Merge for 1.29.2 (#14072)
* put standard library file associations in package.json (#14002)

* Fix incorrect comma in settings string. (#14005)

* Update IntelliSense strings (translations are available yet). (#14020)

* Enable setting the VS dev environment without running from Dev Command Prompt (#13571)

* For VS 18.0 and above, use "Insiders" instead of "Preview" (#14022)

* Adding telemetry for devcmd environment usage (#14023)

* Update changelog and version for 1.29.0. (#14028)

* Update changelog and version for 1.29.0.

* Update TPN. (#14029)

* Update changelog (2nd time). (#14032)

* Update IntelliSense loc strings. (#14038)

* Update localization (#14039)

* Localization - Translated Strings

* Some fixes.

* Remove \t.

---------

Co-authored-by: csigs <[email protected]>

* Update the msvc version to 1950. (#14042)

* Retry build files task in cg.yml (#14043)

* Retry build files.

* Update changelog for 1.29.1. (#14058)

* Bump js-yaml from 4.1.0 to 4.1.1 in /Extension (#14060)

Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update js-yaml for github actions. (#14061)

* Fix typo "no_suitable_complier" in nativeStrings.json (#14064)

* Update changelog and verison for 1.29.2. (#14070)

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Bob Brown <[email protected]>
Co-authored-by: csigs <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dhruvil Shah <[email protected]>
2025-12-01 18:13:44 -08:00
Sean McManus e10273d4a5 Merge branch 'main' into seanmcm/1_29_2_release 2025-12-01 17:21:30 -08:00
Sean McManus 0ae864f1d7 Merge pull request #14003 from microsoft/main
Merge for 1.28.3 (release)
2025-10-15 11:59:21 -07:00
Sean McManus 58e66e8aac Merge pull request #13992 from microsoft/main
Merge for 1.28.2
2025-10-10 11:42:29 -07:00
Sean McManus cf11bb5666 Merge pull request #13944 from microsoft/seanmcm/1_27_7_release
Merge for 1.27.7
2025-09-17 15:54:37 -07:00
Sean McManus 777af10222 Fix bad merge. 2025-09-17 15:39:28 -07:00
Sean McManus ca3dcdbc8f Merge branch 'main' into seanmcm/1_27_7_release 2025-09-17 15:36:38 -07:00
Sean McManus ff2fb7eb65 Merge pull request #13919 from microsoft/seanmcm/1_26_5_release
Cherry-pick for 1.26.5
2025-09-10 09:01:57 -07:00
Sean McManus a1fa61e73f Update changelog and version for 1.26.5. 2025-09-10 08:43:37 -07:00
Dirk Bäumer 42f7302d6b Wait maximum 3 seconds for the Copilot chat extension to activate. (#13918) 2025-09-10 08:36:00 -07:00
Sean McManus af326bd298 Merge pull request #13900 from microsoft/seanmcm/1_26_4_release
1.26.4 release
2025-09-05 16:16:37 -07:00
Sean McManus b50bf604fd Remove / from the message since it seems to cause it to be dropped. (#13899) 2025-09-05 09:56:16 -07:00
Sean McManus f4f3d8ca8b Add more state info to cpptools crash logging. (#13888)
* Add more state info to cpptools crash logging.
2025-09-05 09:55:45 -07:00
Sean McManus 303b838a41 Update changelog and version for 1.26.4 2025-09-05 04:34:59 -07:00
Dirk Bäumer 36cea36784 Register the CPP context provider with Copilot Chat as well. (#13877)
* Register context provider API with copilot chat as well.
2025-09-05 04:34:28 -07:00
Sean McManus e4f859dd56 Merge pull request #13718 from microsoft/main
Merge for 1.26.3 release
2025-06-18 19:14:47 -07:00
Sean McManus 97c5f14bd5 Merge pull request #13563 from microsoft/main
Merge for 1.25.3
2025-04-28 15:03:26 -07:00
Sean McManus c4003c07e8 Merge pull request #13451 from microsoft/main
Merge for 1.24.5 (release)
2025-04-02 12:39:30 -07:00
Sean McManus c27806e763 Merge pull request #13430 from microsoft/main
Merge for 1.24.x (2nd time)
2025-03-26 14:20:24 -07:00
Sean McManus 7cfb2d3316 Merge pull request #13423 from microsoft/seanmcm/1_24_x_release
Merge for 1.24.x
2025-03-26 11:09:49 -07:00
Sean McManus 9a03b747c6 Fix incorrect diffs in the branch. 2025-03-25 17:21:16 -07:00
Sean McManus 989cee4414 Merge branch 'main' into seanmcm/1_24_x_release 2025-03-25 16:59:59 -07:00
Sean McManus c357224407 Merge pull request #13245 from microsoft/seanmcm/1_23_6_release
Cherry-picks for 1.23.6
2025-02-06 11:51:34 -08:00
Sean McManus a636c87f3e Update changelog for 1.23.6 (#13244)
* Update changelog and version.
2025-02-06 11:26:32 -08:00
Garrett Serack 471cdfecf8 don't abort instantly, keep searching (#13243) 2025-02-06 11:25:58 -08:00
Sean McManus 97128122b0 Fix Select IntelliSense Configuration regression. (#13224) 2025-02-06 11:21:39 -08:00
Sean McManus 006ebff619 Merge pull request #13211 from microsoft/seanmcm/1_23_5_release
Merge insiders to release (with cherry-picks from main) for 1.23.5
2025-01-28 13:20:36 -08:00
Sean McManus 1458694ed6 Fix incorrect merge. 2025-01-28 12:09:47 -08:00
Sean McManus 896024ba9c Update changelog and version for 1.23.5. (#13208)
* Update changelog and version for 1.23.5.
2025-01-28 12:07:40 -08:00
Sean McManus 779bb080c1 Fix an undefined access when an edit is done before cpptools starts (#13206)
* Fix an undefined access.
2025-01-28 12:07:29 -08:00
Sean McManus 97df273fc1 Fix Call Hierarchy Calls From. (#13201) 2025-01-28 12:07:18 -08:00
dependabot[bot] 7037b070ce Bump undici from 5.28.4 to 5.28.5 in /.github/actions (#13180)
Bumps [undici](https://github.com/nodejs/undici) from 5.28.4 to 5.28.5.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-28 12:06:58 -08:00
Sean McManus 205e63772c Merge branch 'insiders' into seanmcm/1_23_5_release 2025-01-28 12:06:48 -08:00
Sean McManus 37950ffb2d Merge pull request #12930 from microsoft/seanmcm/1_22_11_release
Cherry-pick and version and changelog update for 1.22.11
2024-11-05 15:05:32 -08:00
Sean McManus 23b0672837 Cherry-pick and update version and changelog for 1.22.11. 2024-11-05 14:44:40 -08:00
Colen Garoutte-Carson 7bafd64cfe Fix processing of bools and numbers in editorConfig files (#12923) 2024-11-05 14:35:27 -08:00
Sean McManus dead10ac8a Merge pull request #12870 from microsoft/seanmcm/1_22_10_release
Cherry-picks for 1.22.10
2024-10-21 14:00:18 -07:00
Colen Garoutte-Carson ce20613f24 Update changelog for 1.22.10 (#12852) 2024-10-21 12:51:56 -07:00
Ben McMorran 86c6c10f18 React to lmTools API breaking changes (#12866) 2024-10-21 12:50:06 -07:00
Sean McManus db6e0cb5cf Merge pull request #12839 from microsoft/seanmcm/1_22_9_update
Last minute updates for 1.22.9
2024-10-14 12:09:27 -07:00
Sean McManus f9e067f5d1 Last minute updates for 1.22.9. 2024-10-14 12:05:29 -07:00
Ben McMorran b137df0bcd React to breaking changes in lmTools API (#12838) 2024-10-14 12:04:56 -07:00
Sean McManus 827db55084 Merge pull request #12827 from microsoft/seanmcm/1_22_9_release
Merge for 1.22.9
2024-10-10 11:46:03 -07:00
Sean McManus 8a2324daaa Merge branch 'main' into seanmcm/1_22_9_release 2024-10-09 14:34:08 -07:00
Sean McManus bdd3541f28 Merge branch 'main' into seanmcm/1_22_8_release 2024-10-04 15:07:46 -07:00
Sean McManus 3cc2650dfa Merge pull request #12538 from microsoft/seanmcm/1_21_6_release
Update changelog and version for 1.21.6
2024-08-05 09:27:22 -07:00
Sean McManus fdf9b5bfe0 Update changelog and version for 1.21.6 2024-08-02 18:31:39 -07:00
Sean McManus fdd71bc963 Merge pull request #12531 from microsoft/seanmcm/1_21_5_release
Update for 1.21.5.
2024-07-30 22:09:55 -07:00
Sean McManus 1d266a9c0e Update for 1.21.5. 2024-07-30 20:09:13 -07:00
Sean McManus f818529a08 Merge pull request #12517 from microsoft/seanmcm/1_21_4_release
Merge for 1.21.4
2024-07-25 15:13:50 -07:00
Sean McManus 41a05a90c8 Update TPN for 1.21.4 2024-07-25 15:09:54 -07:00
Sean McManus e59c6ca759 Go back to supporting VS Code 1.67.0 instead of 1.82.0. 2024-07-25 14:53:37 -07:00
Sean McManus 287ee3961b Merge pull request #12500 from microsoft/seanmcm/1_21_3_release
Update changelog and version for 1.21.3. (#12499)
2024-07-23 19:33:36 -07:00
Sean McManus 8a8fd883ac Update changelog and version for 1.21.3. (#12499) 2024-07-23 19:32:29 -07:00
Sean McManus 4fe56500a9 Merge pull request #12474 from microsoft/seanmcm/1_21_2_release
Merge for 1.21.2
2024-07-17 18:13:02 -07:00
Sean McManus 03911153f9 Update date. 2024-07-17 15:42:14 -07:00
Sean McManus acea31e572 Minor update. 2024-07-12 15:58:18 -07:00
Sean McManus bf21e01764 Update 2024-07-12 12:25:35 -07:00
Sean McManus 30f1361d23 Merge branch 'main' into seanmcm/1_21_2_release 2024-07-12 12:01:21 -07:00
Sean McManus 03933b0a74 Merge pull request #12277 from microsoft/seanmcm/1_20_5_release
Merge for 1.20.5
2024-05-07 20:26:45 -07:00
[email protected] fc8eb8632f [Auto] Localization - Translated Strings (#12236) 2024-05-03 16:06:02 -07:00
Sean McManus f6722bc8ff Update version and changelog for 1.20.5 (#12264)
* Update version and changelog for 1.20.5
2024-05-03 15:30:48 -07:00
Sean McManus 894db52405 Fix macOS version check. (#12276) 2024-05-03 15:29:46 -07:00
Sean McManus abf384619d Merge branch 'insiders' into seanmcm/1_20_5_release 2024-05-03 15:29:34 -07:00
Colen Garoutte-Carson ad5d6de4ea Merge pull request #12123 from microsoft/coleng/cherry_pick_1.19.9.x2 2024-03-19 16:40:47 -07:00
Colen Garoutte-Carson 153e232f2d Update changelog for 1.19.9 again (#12122) 2024-03-19 16:16:21 -07:00
Colen Garoutte-Carson bcd4a7f025 Merge pull request #12118 from microsoft/coleng/cherry_pick_1.19.9 2024-03-18 15:00:41 -07:00
Colen Garoutte-Carson 3c3d463a81 Update changelog 1.19.9 (#12117) 2024-03-18 13:22:40 -07:00
Colen Garoutte-Carson 92691929ed Merge pull request #12100 from microsoft/coleng/merge_release_1.19.8.try2 2024-03-13 17:16:25 -07:00
Colen Garoutte-Carson 86a41c9021 Update changelog for 1.19.8 again (#12099) 2024-03-13 17:12:21 -07:00
Colen Garoutte-Carson a71c90c140 Merge pull request #12093 from microsoft/coleng/cherry_pick_1.19.8 2024-03-12 19:16:35 -07:00
Colen Garoutte-Carson 1d28851ef7 Update changelog for 1.19.8 (#12092) 2024-03-12 19:11:20 -07:00
Colen Garoutte-Carson 1aced54699 Merge pull request #12090 from microsoft/coleng/cherry_pick_3_11_2024 2024-03-11 14:17:04 -07:00
Bob Brown a8cf39c8b4 Prevent the status bar from updating too quickly (#12088) 2024-03-11 13:32:50 -07:00
Colen Garoutte-Carson e037b95926 Merge pull request #12087 from microsoft/coleng/cherry_pick_to_release_again 2024-03-08 15:09:53 -08:00
Colen Garoutte-Carson af7f6ce52e Update changelog again for 1.19.7 (#12086) 2024-03-08 15:01:37 -08:00
Colen Garoutte-Carson 9a18982440 Merge pull request #12083 from microsoft/coleng/cherry_pick_release_1.19.7 2024-03-08 11:09:55 -08:00
Colen Garoutte-Carson 35bf4c8b0f Update changelog for 1.19.7 (#12081) 2024-03-08 10:32:50 -08:00
Colen Garoutte-Carson 23446558cf Merge pull request #12065 from microsoft/main 2024-03-05 18:22:19 -08:00
35 changed files with 264 additions and 1570 deletions
+1 -3
View File
@@ -1,4 +1,2 @@
registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/
always-auth=true
# Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust
ignore-scripts=true
always-auth=true
+3 -3
View File
@@ -4125,9 +4125,9 @@
"license": "ISC"
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha1-d31z1yqS+OxNLkEOtHNSpWuOg0A=",
"version": "1.16.0",
"resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.16.0.tgz",
"integrity": "sha1-KEdKFZ07nRHvYgUKFO1g5N9tYbw=",
"funding": [
{
"type": "individual",
@@ -66,11 +66,6 @@ jobs:
# run: yarn test --scenario=MultirootDeadlockTest
# working-directory: Extension
# - name: Run E2E IntelliSense features tests
# if: ${{ inputs.platform == 'windows' }}
# run: yarn test --scenario=RunWithoutDebugging
# working-directory: Extension
# NOTE: For mac/linux run the tests with xvfb-action for UI support.
# Another way to start xvfb https://github.com/microsoft/vscode-test/blob/master/sample/azure-pipelines.yml
@@ -88,10 +83,3 @@ jobs:
# run: yarn test --scenario=MultirootDeadlockTest
# working-directory: Extension
# - name: Run E2E IntelliSense features tests (xvfb)
# if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
# uses: coactions/setup-xvfb@v1
# with:
# run: yarn test --scenario=RunWithoutDebugging
# working-directory: Extension
+4 -10
View File
@@ -107,14 +107,8 @@ extends:
fi
retryCountOnTaskFailure: 3
- script: yarn install --frozen-lockfile
displayName: Install dependencies with yarn
workingDirectory: $(Build.SourcesDirectory)\Extension
- script: if not exist node_modules\@vscode\vsce-sign\bin\vsce-sign.exe (echo Missing vsce-sign.exe && exit 1)
displayName: Verify vsce-sign binary exists
workingDirectory: $(Build.SourcesDirectory)\Extension
- script: npx vsce package --yarn -o $(Build.ArtifactStagingDirectory)\Extension\cpptools.vsix
- script: |
cd $(Build.SourcesDirectory)\Extension
npx @vscode/[email protected] package --yarn -o $(Build.ArtifactStagingDirectory)\Extension\cpptools.vsix
name: ProcessRunner_12
displayName: Run VSCE to package vsix
workingDirectory: $(Build.SourcesDirectory)\Extension
+4 -15
View File
@@ -59,24 +59,13 @@ jobs:
- script: mkdir $(Build.ArtifactStagingDirectory)\vsix
displayName: Create Staging Directory
- script: npm install --no-save --ignore-scripts=false --include=optional --force @vscode/[email protected]
displayName: Install vsce
workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }}
- script: npm rebuild @vscode/vsce-sign --ignore-scripts=false
displayName: Rebuild vsce-sign binary
workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }}
- script: if not exist node_modules\@vscode\vsce-sign\bin\vsce-sign.exe (echo Missing vsce-sign.exe && exit 1)
displayName: Verify vsce-sign binary exists
workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }}
- script: npx vsce package -o $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.vsix
- script: |
cd $(Build.SourcesDirectory)\${{ parameters.srcDir }}
npx @vscode/[email protected] package -o $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.vsix
displayName: Run VSCE to package vsix
workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }}
# sign the vsix
- script: npx vsce generate-manifest -i $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.vsix -o $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.manifest
- script: npx @vscode/[email protected] generate-manifest -i $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.vsix -o $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.manifest
displayName: generate manifest
workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }}
- script: copy $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.manifest $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s
+2 -10
View File
@@ -31,16 +31,8 @@ jobs:
$aadToken = az account get-access-token --query accessToken --resource $(AzureGuid) -o tsv
Write-Host "##vso[task.setvariable variable=AAD_TOKEN;issecret=true]$aadToken"
- script: npm install --no-save --ignore-scripts=false --include=optional --force @vscode/[email protected]
displayName: Install vsce
- script: npm rebuild @vscode/vsce-sign --ignore-scripts=false
displayName: Rebuild vsce-sign binary
- script: if not exist node_modules\@vscode\vsce-sign\bin\vsce-sign.exe (echo Missing vsce-sign.exe && exit 1)
displayName: Verify vsce-sign binary exists
- script: npx vsce publish --skip-duplicate -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix --manifestPath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest --signaturePath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s
- script: |
npx @vscode/[email protected] publish --skip-duplicate -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix --manifestPath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest --signaturePath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s
displayName: Publish to Marketplace
env:
VSCE_PAT: $(AAD_TOKEN)
+1 -3
View File
@@ -1,4 +1,2 @@
registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/
always-auth=true
# Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust
ignore-scripts=true
always-auth=true
-113
View File
@@ -1,113 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { cp, readdir, rm, stat } from 'node:fs/promises';
import { homedir } from 'node:os';
import { join } from 'node:path';
import { $args, $root, green, heading, note } from './common';
const extensionPrefix = 'ms-vscode.cpptools-';
const foldersToCopy = ['bin', 'debugAdapters', 'LLVM'] as const;
type InstalledExtension = {
path: string;
version: number[];
modified: number;
};
function compareVersions(left: number[], right: number[]): number {
const maxLength: number = Math.max(left.length, right.length);
for (let i = 0; i < maxLength; i++) {
const diff: number = (left[i] ?? 0) - (right[i] ?? 0);
if (diff !== 0) {
return diff;
}
}
return 0;
}
function tryParseVersion(folderName: string): number[] | undefined {
if (!folderName.startsWith(extensionPrefix)) {
return undefined;
}
const versionText: string | undefined = folderName.substring(extensionPrefix.length).match(/^\d+\.\d+\.\d+/)?.[0];
return versionText?.split('.').map(each => Number(each));
}
async function getInstalledExtensions(root: string): Promise<InstalledExtension[]> {
try {
const entries = await readdir(root, { withFileTypes: true });
const candidates: Promise<InstalledExtension | undefined>[] = entries.map(async (entry) => {
if (!entry.isDirectory()) {
return undefined;
}
const version: number[] | undefined = tryParseVersion(entry.name);
if (!version) {
return undefined;
}
const extensionPath: string = join(root, entry.name);
for (const folder of foldersToCopy) {
const info = await stat(join(extensionPath, folder)).catch(() => undefined);
if (!info?.isDirectory()) {
return undefined;
}
}
const info = await stat(extensionPath);
return {
path: extensionPath,
version,
modified: info.mtimeMs
};
});
const found = await Promise.all(candidates);
return found.filter((entry): entry is InstalledExtension => entry !== undefined);
} catch {
return [];
}
}
async function findLatestInstalledExtension(providedPath?: string): Promise<string> {
if (providedPath) {
return providedPath;
}
const searchRoots: string[] = [
join(homedir(), '.vscode', 'extensions'),
join(homedir(), '.vscode-insiders', 'extensions'),
join(homedir(), '.vscode-server', 'extensions'),
join(homedir(), '.vscode-server-insiders', 'extensions')
];
const installed: InstalledExtension[] = (await Promise.all(searchRoots.map(each => getInstalledExtensions(each)))).flat();
if (!installed.length) {
throw new Error(`Unable to find an installed C/C++ extension under ${searchRoots.join(' or ')}.`);
}
installed.sort((left, right) => compareVersions(right.version, left.version) || right.modified - left.modified);
return installed[0].path;
}
export async function main(sourcePath = $args[0]) {
console.log(heading('Copy installed extension binaries'));
const installedExtensionPath: string = await findLatestInstalledExtension(sourcePath);
note(`Using installed extension at ${installedExtensionPath}`);
for (const folder of foldersToCopy) {
const source: string = join(installedExtensionPath, folder);
const destination: string = join($root, folder);
console.log(`Copying ${green(folder)} from ${source}`);
await rm(destination, { recursive: true, force: true });
await cp(source, destination, { recursive: true, force: true });
}
note(`Copied installed binaries into ${$root}`);
}
-4
View File
@@ -97,10 +97,6 @@
"label": "MultirootDeadlockTest ",
"value": "${workspaceFolder}/test/scenarios/MultirootDeadlockTest/assets/test.code-workspace"
},
{
"label": "RunWithoutDebugging ",
"value": "${workspaceFolder}/test/scenarios/RunWithoutDebugging/assets/"
},
{
"label": "SimpleCppProject ",
"value": "${workspaceFolder}/test/scenarios/SimpleCppProject/assets/simpleCppProject.code-workspace"
-1
View File
@@ -35,7 +35,6 @@ eslint.config.js
gulpfile.js
localized_string_ids.h
readme.developer.md
Reinstalling the Extension.md
test.tsconfig.json
translations_auto_pr.js
tsconfig.json
+3 -16
View File
@@ -1,22 +1,9 @@
# C/C++ for Visual Studio Code Changelog
## Version 1.32.0: April 14, 2026
### New Feature
* Add support for run without debugging. [#1201](https://github.com/microsoft/vscode-cpptools/issues/1201)
### Enhancements
* Add a `C_Cpp.doxygen.generateOnCodeAction` setting to allow disabling of Doxygen generation code actions. [#14341](https://github.com/microsoft/vscode-cpptools/issues/14341)
* Improve wildcard matching with the debugger natvis. [MIEngine#1162](https://github.com/microsoft/MIEngine/issues/1162)
* Add support for `HideRawView` with the debugger natvis. [MIEngine#1458](https://github.com/microsoft/MIEngine/issues/1458)
## Version 1.31.5: April 20, 2026
### Bug Fixes
* Fix high CPU usage caused by repeated calls to `selectChatModels`. [#14168](https://github.com/microsoft/vscode-cpptools/issues/14168), [#14211](https://github.com/microsoft/vscode-cpptools/issues/14211), [#14241](https://github.com/microsoft/vscode-cpptools/issues/14241)
* Fix the MSVC developer environment not working if `UCRTVersion` isn't found, and update the walkthrough instructions for installing MSVC. [#14352](https://github.com/microsoft/vscode-cpptools/issues/14352)
* Fix Copilot hover taking too many premium requests. [#14372](https://github.com/microsoft/vscode-cpptools/issues/14372)
* Fix null pointers being expandable for variables in the debugger. [MIEngine#698](https://github.com/microsoft/MIEngine/issues/698)
* Fix recursive `{this}` evaluation with the debugger natvis. [MIEngine#1391](https://github.com/microsoft/MIEngine/issues/1391)
* Update clang-tidy and clang-format from 22.1.1 to 22.1.3 (bug fixes).
* Fix a bug with semantic colorization of operators.
* Fix `Reinstalling the Extension.md` not being found. [#14389](https://github.com/microsoft/vscode-cpptools/issues/14389)
* Fix the `C/C++ DevTools` extension language service tools not working after the `C/C++` extension updates via `Restart Extensions`. [#14392](https://github.com/microsoft/vscode-cpptools/issues/14392)
## Version 1.31.4: March 31, 2026
### Bug Fix
+6 -6
View File
@@ -1250,7 +1250,7 @@ SOFTWARE.
---------------------------------------------------------
@xmldom/xmldom 0.8.12 - MIT
@xmldom/xmldom 0.8.11 - MIT
https://github.com/xmldom/xmldom
Copyright 2019 - present Christopher J. Brody and other contributors
@@ -1510,7 +1510,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
---------------------------------------------------------
brace-expansion 1.1.13 - MIT
brace-expansion 1.1.12 - MIT
https://github.com/juliangruber/brace-expansion
Copyright (c) 2013 Julian Gruber <[email protected]>
@@ -1542,7 +1542,7 @@ SOFTWARE.
---------------------------------------------------------
brace-expansion 2.0.3 - MIT
brace-expansion 2.0.2 - MIT
https://github.com/juliangruber/brace-expansion
Copyright (c) 2013 Julian Gruber <[email protected]>
@@ -1642,7 +1642,7 @@ SOFTWARE.
chokidar 3.6.0 - MIT
https://github.com/paulmillr/chokidar
(c) Paul Miller
(c) Paul Miller <https://paulmillr.com>
Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker
The MIT License (MIT)
@@ -3018,7 +3018,7 @@ THE SOFTWARE.
---------------------------------------------------------
picomatch 2.3.2 - MIT
picomatch 2.3.1 - MIT
https://github.com/micromatch/picomatch
Copyright (c) 2017-present, Jon Schlinkert
@@ -3183,7 +3183,7 @@ readdirp 3.6.0 - MIT
https://github.com/paulmillr/readdirp
Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com)
Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller ( https://paulmillr.com )
Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller <https://paulmillr.com>
MIT License
+1 -8
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "1.32.0-main",
"version": "1.31.5-main",
"publisher": "ms-vscode",
"icon": "LanguageCCPP_color_128x.png",
"readme": "README.md",
@@ -1703,12 +1703,6 @@
"description": "%c_cpp.configuration.doxygen.generateOnType.description%",
"scope": "resource"
},
"C_Cpp.doxygen.generateOnCodeAction": {
"type": "boolean",
"default": true,
"description": "%c_cpp.configuration.doxygen.generateOnCodeAction.description%",
"scope": "resource"
},
"C_Cpp.doxygen.generatedStyle": {
"type": "string",
"enum": [
@@ -6805,7 +6799,6 @@
"generate-native-strings": "ts-node -T ./.scripts/generateNativeStrings.ts",
"generate-options-schema": "ts-node -T ./.scripts/generateOptionsSchema.ts",
"copy-walkthrough-media": "ts-node -T ./.scripts/copyWalkthruMedia.ts",
"copy-extension-binaries": "ts-node -T ./.scripts/copyExtensionBinaries.ts",
"translations-export": "yarn install && yarn prep && yarn generate-native-strings && gulp translations-export",
"translations-generate": "gulp translations-generate",
"translations-import": "gulp translations-import",
-1
View File
@@ -580,7 +580,6 @@
]
},
"c_cpp.configuration.doxygen.generateOnType.description": "Controls whether to automatically insert the Doxygen comment after typing the chosen comment style.",
"c_cpp.configuration.doxygen.generateOnCodeAction.description": "Controls whether the code action to generate a Doxygen comment is enabled.",
"c_cpp.configuration.doxygen.generatedStyle.description": "The string of characters used as the starting line of the Doxygen comment.",
"c_cpp.configuration.doxygen.sectionTags.description": "Select the Doxygen section tags that you would like to appear on hover in the tooltip area when the 'Simplify Structured Comments' setting is enabled. ",
"c_cpp.configuration.commentContinuationPatterns.items.anyof.string.markdownDescription": {
@@ -147,14 +147,12 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
Telemetry.logDebuggerEvent(DebuggerEvent.debugPanel, { "debugType": DebugType.debug, "configSource": folder ? ConfigSource.workspaceFolder : ConfigSource.singleFile, "configMode": ConfigMode.noLaunchConfig, "cancelled": "true", "succeeded": "true" });
return undefined; // aborts debugging silently
} else {
const noDebug = config.noDebug ?? false; // Preserve the noDebug value from the config if it exists.
// Currently, we expect only one debug config to be selected.
console.assert(configs.length === 1, "More than one debug config is selected.");
config = configs[0];
// Keep track of the entry point where the debug config has been selected, for telemetry purposes.
config.debuggerEvent = DebuggerEvent.debugPanel;
config.configSource = folder ? ConfigSource.workspaceFolder : ConfigSource.singleFile;
config.noDebug = noDebug;
}
}
+3 -3
View File
@@ -97,7 +97,7 @@ function createLaunchString(name: string, type: string, executable: string): str
"stopAtEntry": false,
"cwd": "$\{fileDirname\}",
"environment": [],
${type === "cppdbg" ? `"externalConsole": false` : `"console": "internalConsole"`}
${ type === "cppdbg" ? `"externalConsole": false` : `"console": "externalTerminal"` }
`;
}
@@ -164,7 +164,7 @@ export class MIConfigurations extends Configuration {
\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)}` : ""]);
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
"label": configPrefix + name,
@@ -182,7 +182,7 @@ export class MIConfigurations extends Configuration {
\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)}` : ""]);
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
"label": configPrefix + name,
@@ -7,13 +7,11 @@ import * as os from 'os';
import * as path from 'path';
import * as vscode from "vscode";
import * as nls from 'vscode-nls';
import { getOutputChannel } from '../logger';
import { RunWithoutDebuggingAdapter } from './runWithoutDebuggingAdapter';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
// Registers DebugAdapterDescriptorFactory for `cppdbg` and `cppvsdbg`.
// Registers DebugAdapterDescriptorFactory for `cppdbg` and `cppvsdbg`. If it is not ready, it will prompt a wait for the download dialog.
// NOTE: This file is not automatically tested.
abstract class AbstractDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
@@ -28,15 +26,8 @@ abstract class AbstractDebugAdapterDescriptorFactory implements vscode.DebugAdap
}
export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable?: vscode.DebugAdapterExecutable): Promise<vscode.DebugAdapterDescriptor> {
if (session.configuration.noDebug) {
if (noDebugSupported(session.configuration)) {
return new vscode.DebugAdapterInlineImplementation(new RunWithoutDebuggingAdapter());
}
// If the configuration is not supported, gracefully fall back to a regular debug session and log a message to the user.
logReasonForNoDebugNotSupported(session.configuration);
}
async createDebugAdapterDescriptor(_session: vscode.DebugSession, _executable?: vscode.DebugAdapterExecutable): Promise<vscode.DebugAdapterDescriptor> {
const adapter: string = "./debugAdapters/bin/OpenDebugAD7" + (os.platform() === 'win32' ? ".exe" : "");
const command: string = path.join(this.context.extensionPath, adapter);
@@ -46,15 +37,8 @@ export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDes
}
export class CppvsdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable?: vscode.DebugAdapterExecutable): Promise<vscode.DebugAdapterDescriptor | null> {
if (session.configuration.noDebug) {
if (noDebugSupported(session.configuration)) {
return new vscode.DebugAdapterInlineImplementation(new RunWithoutDebuggingAdapter());
}
// If the configuration is not supported, gracefully fall back to a regular debug session and log a message to the user.
logReasonForNoDebugNotSupported(session.configuration);
}
async createDebugAdapterDescriptor(_session: vscode.DebugSession, _executable?: vscode.DebugAdapterExecutable): Promise<vscode.DebugAdapterDescriptor | null> {
if (os.platform() !== 'win32') {
void vscode.window.showErrorMessage(localize("debugger.not.available", "Debugger type '{0}' is not available for non-Windows machines.", "cppvsdbg"));
return null;
@@ -66,28 +50,3 @@ export class CppvsdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterD
}
}
}
function noDebugSupported(configuration: vscode.DebugConfiguration): boolean {
// Don't attempt to start a noDebug session if the configuration has any of these properties, which require a debug adapter to function.
return configuration.request === 'launch' && !configuration.pipeTransport && !configuration.debugServerPath && !configuration.miDebuggerServerAddress && !configuration.coreDumpPath;
}
function logReasonForNoDebugNotSupported(configuration: vscode.DebugConfiguration): void {
const outputChannel = getOutputChannel();
if (configuration.request !== 'launch') {
outputChannel.appendLine(localize("debugger.noDebug.requestType.not.supported", "Run Without Debugging is only supported for launch configurations."));
}
if (configuration.pipeTransport) {
outputChannel.appendLine(localize("debugger.noDebug.pipeTransport.not.supported", "Run Without Debugging is not supported for configurations with 'pipeTransport' set."));
}
if (configuration.debugServerPath) {
outputChannel.appendLine(localize("debugger.noDebug.debugServerPath.not.supported", "Run Without Debugging is not supported for configurations with 'debugServerPath' set."));
}
if (configuration.miDebuggerServerAddress) {
outputChannel.appendLine(localize("debugger.noDebug.miDebuggerServerAddress.not.supported", "Run Without Debugging is not supported for configurations with 'miDebuggerServerAddress' set."));
}
if (configuration.coreDumpPath) {
outputChannel.appendLine(localize("debugger.noDebug.coreDumpPath.not.supported", "Run Without Debugging is not supported for configurations with 'coreDumpPath' set."));
}
outputChannel.show(true);
}
@@ -1,302 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as cp from 'child_process';
import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { buildShellCommandLine, sessionIsWsl } from '../common';
import { isWindows } from '../constants';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize = nls.loadMessageBundle();
/**
* A minimal inline Debug Adapter that runs the target program directly without a debug adapter
* when the user invokes "Run Without Debugging".
*/
export class RunWithoutDebuggingAdapter implements vscode.DebugAdapter {
private readonly sendMessageEmitter = new vscode.EventEmitter<vscode.DebugProtocolMessage>();
public readonly onDidSendMessage: vscode.Event<vscode.DebugProtocolMessage> = this.sendMessageEmitter.event;
private readonly terminalListeners: vscode.Disposable[] = [];
private seq: number = 1;
private childProcess?: cp.ChildProcess;
private terminal?: vscode.Terminal;
private terminalExecution?: vscode.TerminalShellExecution;
private hasTerminated: boolean = false;
public handleMessage(message: vscode.DebugProtocolMessage): void {
const msg = message as { type: string; command: string; seq: number; arguments?: any; };
if (msg.type === 'request') {
void this.handleRequest(msg);
}
}
private async handleRequest(request: { command: string; seq: number; arguments?: any; }): Promise<void> {
switch (request.command) {
case 'initialize':
this.sendResponse(request, {});
this.sendEvent('initialized');
break;
case 'launch':
await this.launch(request);
break;
case 'configurationDone':
this.sendResponse(request, {});
break;
case 'disconnect':
case 'terminate':
this.sendResponse(request, {});
break;
default:
this.sendResponse(request, {});
break;
}
}
private async launch(request: { command: string; seq: number; arguments?: any; }): Promise<void> {
const config = request.arguments as {
program?: string;
args?: string[];
cwd?: string;
environment?: { name: string; value: string; }[];
console?: string;
externalConsole?: boolean;
};
const program: string = config.program ?? '';
const args: string[] = config.args ?? [];
const cwd: string | undefined = config.cwd;
const environment: { name: string; value: string; }[] = config.environment ?? [];
const consoleMode: string = config.console ?? (config.externalConsole ? 'externalTerminal' : 'integratedTerminal');
// Merge the launch config's environment variables on top of the inherited process environment.
const env: NodeJS.ProcessEnv = { ...process.env };
for (const e of environment) {
env[e.name] = e.value;
}
this.sendResponse(request, {});
if (consoleMode === 'integratedTerminal' || consoleMode === 'internalConsole') {
await this.launchIntegratedTerminal(program, args, cwd, env);
} else if (consoleMode === 'externalTerminal') {
this.launchExternalTerminal(program, args, cwd, env);
}
}
/**
* Launch the program in a VS Code integrated terminal.
* The terminal will remain open after the program exits and be reused for the next session, if applicable.
*/
private async launchIntegratedTerminal(program: string, args: string[], cwd: string | undefined, env: NodeJS.ProcessEnv): Promise<void> {
const terminalName = path.normalize(program);
const existingTerminal = vscode.window.terminals.find(t => t.name === terminalName);
this.terminal = existingTerminal ?? vscode.window.createTerminal({
name: terminalName,
cwd,
env: env as Record<string, string>
});
this.terminal.show(true);
const shellIntegration: vscode.TerminalShellIntegration | undefined =
this.terminal.shellIntegration ?? await this.waitForShellIntegration(this.terminal, 3000);
// Not all terminals support shell integration. If it's not available, we'll just send the command as text though we won't be able to monitor its execution.
if (shellIntegration) {
this.monitorIntegratedTerminal(this.terminal);
let executable: string = program;
let executableArgs: string[] = args;
if (!program.match(/["']/) && program.match(/\s/)) {
// VS Code does not automatically quote the program path if it has spaces.
const shellPath: string | undefined = 'shellPath' in this.terminal.creationOptions
? this.terminal.creationOptions.shellPath?.toLowerCase()
: undefined;
const terminalShell: string | undefined = this.terminal.state.shell?.toLowerCase();
const defaultTerminalProfile: string | undefined = isWindows
? vscode.workspace.getConfiguration('terminal.integrated').get<string>('defaultProfile.windows')?.toLowerCase()
: undefined;
const isPowerShell: boolean | undefined =
shellPath?.endsWith('pwsh.exe') || shellPath?.endsWith('powershell.exe') || shellPath?.endsWith('pwsh') ||
terminalShell?.includes('powershell') || terminalShell?.includes('pwsh') ||
defaultTerminalProfile?.includes('powershell') || defaultTerminalProfile?.includes('pwsh');
if (isPowerShell || (isWindows && isPowerShell === undefined)) { // PowerShell is the default on Windows if we can't determine the shell.
executable = '&';
executableArgs = [program, ...args];
} else {
executable = `"${program}"`;
}
}
this.terminalExecution = shellIntegration.executeCommand(executable, executableArgs);
} else {
const cmdLine: string = buildShellCommandLine('', program, args, true);
this.terminal.sendText(cmdLine);
// The terminal manages its own lifecycle; notify VS Code the "debug" session is done.
this.sendEvent('terminated');
}
}
/**
* Launch the program in an external terminal. We do not keep track of this terminal or the spawned process.
*/
private launchExternalTerminal(program: string, args: string[], cwd: string | undefined, env: NodeJS.ProcessEnv): void {
const cmdLine: string = buildShellCommandLine('', program, args, true);
const platform: string = os.platform();
if (platform === 'win32') {
cp.spawn('cmd.exe', ['/c', 'start', 'cmd.exe', '/K', `"${cmdLine}"`], { cwd, env, windowsVerbatimArguments: true, detached: true, stdio: 'ignore' }).unref();
} else if (platform === 'darwin') {
cp.spawn('osascript', ['-e', `tell application "Terminal" to do script "${this.escapeQuotes(cmdLine)}"`], { cwd, env, detached: true, stdio: 'ignore' }).unref();
} else if (platform === 'linux' && sessionIsWsl()) {
cp.spawn('/mnt/c/Windows/System32/cmd.exe', ['/c', 'start', 'bash', '-c', `${cmdLine};read -p 'Press enter to continue...'`], { env, detached: true, stdio: 'ignore' }).unref();
} else { // platform === 'linux'
this.launchLinuxExternalTerminal(cmdLine, cwd, env);
}
this.sendEvent('terminated');
}
/**
* On Linux, find and launch an available terminal emulator to run the command.
*/
private launchLinuxExternalTerminal(cmdLine: string, cwd: string | undefined, env: NodeJS.ProcessEnv): void {
const bashCmd = `${cmdLine}; echo; read -p 'Press enter to continue...'`;
const bashArgs = ['bash', '-c', bashCmd];
// Terminal emulators in order of preference, with the correct flag style for each.
const candidates: { cmd: string; buildArgs(): string[] }[] = [
{ cmd: 'x-terminal-emulator', buildArgs: () => ['-e', ...bashArgs] },
{ cmd: 'gnome-terminal', buildArgs: () => ['-e', ...bashArgs] },
{ cmd: 'konsole', buildArgs: () => ['-e', ...bashArgs] },
{ cmd: 'xterm', buildArgs: () => ['-e', ...bashArgs] }
];
// Honor the $TERMINAL environment variable if set.
const terminalEnv = process.env['TERMINAL'];
if (terminalEnv) {
candidates.unshift({ cmd: terminalEnv, buildArgs: () => ['-e', ...bashArgs] });
}
for (const candidate of candidates) {
try {
const result = cp.spawnSync('which', [candidate.cmd], { stdio: 'pipe' });
if (result.status === 0) {
cp.spawn(candidate.cmd, candidate.buildArgs(), { cwd, env, detached: true, stdio: 'ignore' }).unref();
return;
}
} catch {
continue;
}
}
const message = localize('no.terminal.emulator', 'No terminal emulator found. Please set the $TERMINAL environment variable to your terminal emulator of choice, or install one of the following: x-terminal-emulator, gnome-terminal, konsole, xterm.');
vscode.window.showErrorMessage(message);
}
private escapeQuotes(arg: string): string {
return arg.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
private waitForShellIntegration(terminal: vscode.Terminal, timeoutMs: number): Promise<vscode.TerminalShellIntegration | undefined> {
return new Promise(resolve => {
let resolved: boolean = false;
const done = (shellIntegration: vscode.TerminalShellIntegration | undefined): void => {
if (resolved) {
return;
}
resolved = true;
clearTimeout(timeout);
shellIntegrationChanged.dispose();
terminalClosed.dispose();
resolve(shellIntegration);
};
const timeout = setTimeout(() => done(undefined), timeoutMs);
const shellIntegrationChanged = vscode.window.onDidChangeTerminalShellIntegration(event => {
if (event.terminal === terminal) {
done(event.shellIntegration);
}
});
const terminalClosed = vscode.window.onDidCloseTerminal(closedTerminal => {
if (closedTerminal === terminal) {
done(undefined);
}
});
});
}
private monitorIntegratedTerminal(terminal: vscode.Terminal): void {
this.disposeTerminalListeners();
this.terminalListeners.push(
vscode.window.onDidEndTerminalShellExecution(event => {
if (event.terminal !== terminal || event.execution !== this.terminalExecution || this.hasTerminated) {
return;
}
if (event.exitCode !== undefined) {
this.sendEvent('exited', { exitCode: event.exitCode });
}
this.sendEvent('terminated');
}),
vscode.window.onDidCloseTerminal(closedTerminal => {
if (closedTerminal !== terminal || this.hasTerminated) {
return;
}
this.sendEvent('terminated');
})
);
}
private disposeTerminalListeners(): void {
while (this.terminalListeners.length > 0) {
this.terminalListeners.pop()?.dispose();
}
}
private sendResponse(request: { command: string; seq: number; }, body: object): void {
this.sendMessageEmitter.fire({
type: 'response',
seq: this.seq++,
request_seq: request.seq,
success: true,
command: request.command,
body
} as vscode.DebugProtocolMessage);
}
private sendEvent(event: string, body?: object): void {
if (event === 'terminated') {
if (this.hasTerminated) {
return;
}
this.hasTerminated = true;
this.disposeTerminalListeners();
}
this.sendMessageEmitter.fire({
type: 'event',
seq: this.seq++,
event,
body
} as vscode.DebugProtocolMessage);
}
public dispose(): void {
this.terminateProcess();
this.disposeTerminalListeners();
this.sendMessageEmitter.dispose();
}
private terminateProcess(): void {
this.childProcess?.kill();
this.childProcess = undefined;
}
}
@@ -26,69 +26,10 @@ export class CopilotHoverProvider implements vscode.HoverProvider {
private cancelledDocument: vscode.TextDocument | undefined;
private cancelledPosition: vscode.Position | undefined;
private content: string | undefined;
private chatModel: vscode.LanguageModelChat | undefined;
private chatModelId: string | undefined; // Save the selected model ID to avoid trying the same unavailable model repeatedly.
// Flag to avoid querying the LanguageModelChat repeatedly if no model is found
private checkedChatModel: boolean = false;
constructor(client: DefaultClient) {
this.client = client;
}
public async getCachedChatModel(): Promise<vscode.LanguageModelChat | undefined> {
if (this.checkedChatModel) {
return this.chatModel;
}
const vscodelm = getVSCodeLanguageModel();
if (vscodelm) {
try {
let model: vscode.LanguageModelChat | undefined;
if (this.chatModelId === undefined) {
// First look for GPT-4o which should be available to all
// users and have a 0x multiplier on paid plans.
// GPT-4o is faster than the x0 GPT-5-mini (which seems too slow for hover, e.g. 10+ seconds).
this.chatModelId = 'gpt-4o';
[model] = await vscodelm.selectChatModels({ ...modelSelector, id: this.chatModelId });
if (!model) {
// If GPT-4o is not available, fallback to GPT-5.4-mini (x0.33 and fast).
this.chatModelId = 'gpt-5.4-mini';
[model] = await vscodelm.selectChatModels({ ...modelSelector, id: this.chatModelId });
}
if (!model) {
// If GPT-5.4-mini is not available, fallback to the first available model.
this.chatModelId = 'default';
[model] = await vscodelm.selectChatModels(modelSelector);
}
} else {
if (this.chatModelId === 'default') {
[model] = await vscodelm.selectChatModels(modelSelector);
} else {
[model] = await vscodelm.selectChatModels({ ...modelSelector, id: this.chatModelId });
}
}
if (!model) {
telemetry.logLanguageServerEvent('CopilotHoverNoModelSelected', { remoteName: vscode.env.remoteName || 'local' });
} else {
this.chatModel = model;
}
} catch (e: any) {
const exceptionType = e?.name || e?.constructor?.name || typeof e;
telemetry.logLanguageServerEvent('CopilotHoverSelectModelFailed', {
remoteName: vscode.env.remoteName || 'local',
exceptionType: String(exceptionType)
});
}
}
this.checkedChatModel = true;
return this.chatModel;
}
public async refreshCachedChatModel(): Promise<vscode.LanguageModelChat | undefined> {
this.chatModel = undefined;
this.checkedChatModel = false;
return this.getCachedChatModel();
}
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | undefined> {
await this.client.ready;
@@ -102,9 +43,12 @@ export class CopilotHoverProvider implements vscode.HoverProvider {
}
// Ensure the user has access to Copilot.
const model = await this.getCachedChatModel();
if (!model) {
return undefined;
const vscodelm = getVSCodeLanguageModel();
if (vscodelm) {
const [model] = await vscodelm.selectChatModels(modelSelector);
if (!model) {
return undefined;
}
}
const newHover = this.isNewHover(document, position);
@@ -88,129 +88,6 @@ const CallHierarchyCallsToRequest: RequestType<CallHierarchyParams, CallHierarch
const CallHierarchyCallsFromRequest: RequestType<CallHierarchyParams, CallHierarchyCallsItemResult, void> =
new RequestType<CallHierarchyParams, CallHierarchyCallsItemResult, void>('cpptools/callHierarchyCallsFrom');
function makeVscodeCallHierarchyItem(client: DefaultClient, item: CallHierarchyItem): vscode.CallHierarchyItem {
const containerDetail: string = (item.detail !== "") ? `${item.detail} - ` : "";
const itemUri: vscode.Uri = vscode.Uri.file(item.file);
// Get file detail
const isInWorkspace: boolean = client.RootUri !== undefined &&
itemUri.fsPath.startsWith(client.RootUri.fsPath);
const dirPath: string = isInWorkspace ?
path.relative(client.RootPath, path.dirname(item.file)) : path.dirname(item.file);
const fileDetail: string = dirPath.length === 0 ?
`${path.basename(item.file)}` : `${path.basename(item.file)} (${dirPath})`;
return new vscode.CallHierarchyItem(
item.kind,
item.name,
containerDetail + fileDetail,
itemUri,
makeVscodeRange(item.range),
makeVscodeRange(item.selectionRange));
}
function createIncomingCalls(client: DefaultClient, calls: CallHierarchyCallsItem[]): vscode.CallHierarchyIncomingCall[] {
const result: vscode.CallHierarchyIncomingCall[] = [];
for (const call of calls) {
const item: vscode.CallHierarchyItem = makeVscodeCallHierarchyItem(client, call.item);
const ranges: vscode.Range[] = [];
call.fromRanges.forEach(r => {
ranges.push(makeVscodeRange(r));
});
const incomingCall: vscode.CallHierarchyIncomingCall =
new vscode.CallHierarchyIncomingCall(item, ranges);
result.push(incomingCall);
}
return result;
}
function createOutgoingCalls(client: DefaultClient, calls: CallHierarchyCallsItem[]): vscode.CallHierarchyOutgoingCall[] {
const result: vscode.CallHierarchyOutgoingCall[] = [];
for (const call of calls) {
const item: vscode.CallHierarchyItem = makeVscodeCallHierarchyItem(client, call.item);
const ranges: vscode.Range[] = [];
call.fromRanges.forEach(r => {
ranges.push(makeVscodeRange(r));
});
const outgoingCall: vscode.CallHierarchyOutgoingCall =
new vscode.CallHierarchyOutgoingCall(item, ranges);
result.push(outgoingCall);
}
return result;
}
export async function sendPrepareCallHierarchyRequest(client: DefaultClient, uri: vscode.Uri, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.CallHierarchyItem[] | undefined> {
const params: CallHierarchyParams = {
textDocument: { uri: uri.toString() },
position: Position.create(position.line, position.character)
};
let response: CallHierarchyItemResult;
try {
response = await client.languageClient.sendRequest(CallHierarchyItemRequest, params, token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
if (token.isCancellationRequested) {
return undefined;
}
return response.item === undefined ? [] : [makeVscodeCallHierarchyItem(client, response.item)];
}
export async function sendCallHierarchyCallsToRequest(client: DefaultClient, item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[] | undefined> {
const params: CallHierarchyParams = {
textDocument: { uri: item.uri.toString() },
position: Position.create(item.selectionRange.start.line, item.selectionRange.start.character)
};
let response: CallHierarchyCallsItemResult;
try {
response = await client.languageClient.sendRequest(CallHierarchyCallsToRequest, params, token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
if (token.isCancellationRequested) {
return undefined;
}
return response.calls.length !== 0 ? createIncomingCalls(client, response.calls) : [];
}
export async function sendCallHierarchyCallsFromRequest(client: DefaultClient, item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[] | undefined> {
const params: CallHierarchyParams = {
textDocument: { uri: item.uri.toString() },
position: Position.create(item.selectionRange.start.line, item.selectionRange.start.character)
};
let response: CallHierarchyCallsItemResult;
try {
response = await client.languageClient.sendRequest(CallHierarchyCallsFromRequest, params, token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
if (token.isCancellationRequested) {
return undefined;
}
return response.calls.length !== 0 ? createOutgoingCalls(client, response.calls) : [];
}
export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
// Indicates whether a request is from an entry root node (e.g. top function in the call tree).
private isEntryRootNodeTelemetry: boolean = false;
@@ -241,10 +118,20 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
cancelSource.cancel();
});
let result: vscode.CallHierarchyItem[] | undefined;
const params: CallHierarchyParams = {
textDocument: { uri: document.uri.toString() },
position: Position.create(position.line, position.character)
};
let response: CallHierarchyItemResult;
try {
result = await sendPrepareCallHierarchyRequest(this.client, document.uri, position, cancelSource.token);
} finally {
response = await this.client.languageClient.sendRequest(CallHierarchyItemRequest, params, cancelSource.token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
finally {
cancellationTokenListener.dispose();
requestCanceledListener.dispose();
}
@@ -252,12 +139,12 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
if (cancelSource.token.isCancellationRequested) {
throw new vscode.CancellationError();
}
if (!result || result.length === 0) {
if (response.item === undefined) {
return undefined;
}
this.isEntryRootNodeTelemetry = true;
return result[0];
return this.makeVscodeCallHierarchyItem(response.item);
}
public async provideCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[] | undefined> {
@@ -285,28 +172,39 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
// Send the request to the language server.
let result: vscode.CallHierarchyIncomingCall[] | undefined;
let progressBarDuration: number | undefined;
const params: CallHierarchyParams = {
textDocument: { uri: item.uri.toString() },
position: Position.create(item.selectionRange.start.line, item.selectionRange.start.character)
};
let response: CallHierarchyCallsItemResult | undefined;
let cancelled: boolean = false;
try {
result = await sendCallHierarchyCallsToRequest(this.client, item, cancelSource.token);
} finally {
// Reset anything that can be cleared before processing the result.
progressBarDuration = workspaceReferences.getCallHierarchyProgressBarDuration();
workspaceReferences.resetProgressBar();
workspaceReferences.resetReferences();
cancellationTokenListener.dispose();
requestCanceledListener.dispose();
response = await this.client.languageClient.sendRequest(CallHierarchyCallsToRequest, params, cancelSource.token);
} catch (e: any) {
cancelled = e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled);
if (!cancelled) {
throw e;
}
}
// Reset anything that can be cleared before processing the result.
const progressBarDuration: number | undefined = workspaceReferences.getCallHierarchyProgressBarDuration();
workspaceReferences.resetProgressBar();
workspaceReferences.resetReferences();
cancellationTokenListener.dispose();
requestCanceledListener.dispose();
// Process the result.
if (cancelSource.token.isCancellationRequested || result === undefined || requestCanceled !== undefined) {
if (cancelSource.token.isCancellationRequested || cancelled || requestCanceled !== undefined) {
const requestStatus: CallHierarchyRequestStatus = requestCanceled === CancellationSender.User ?
CallHierarchyRequestStatus.CanceledByUser : CallHierarchyRequestStatus.Canceled;
this.logTelemetry(CallHierarchyCallsToEvent, requestStatus, progressBarDuration);
throw new vscode.CancellationError();
} else if (response && response.calls.length !== 0) {
result = this.createIncomingCalls(response.calls);
}
this.logTelemetry(CallHierarchyCallsToEvent, CallHierarchyRequestStatus.Succeeded, progressBarDuration);
return result.length !== 0 ? result : undefined;
return result;
}
public async provideCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[] | undefined> {
@@ -318,15 +216,87 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
await this.client.ready;
const result: vscode.CallHierarchyOutgoingCall[] | undefined =
await sendCallHierarchyCallsFromRequest(this.client, item, token);
if (token.isCancellationRequested || result === undefined) {
let result: vscode.CallHierarchyOutgoingCall[] | undefined;
const params: CallHierarchyParams = {
textDocument: { uri: item.uri.toString() },
position: Position.create(item.selectionRange.start.line, item.selectionRange.start.character)
};
let response: CallHierarchyCallsItemResult | undefined;
let cancelled: boolean = false;
try {
response = await this.client.languageClient.sendRequest(CallHierarchyCallsFromRequest, params, token);
} catch (e: any) {
cancelled = e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled);
if (!cancelled) {
throw e;
}
}
if (token.isCancellationRequested || cancelled) {
this.logTelemetry(CallHierarchyCallsFromEvent, CallHierarchyRequestStatus.Canceled);
throw new vscode.CancellationError();
} else if (response && response.calls.length !== 0) {
result = this.createOutgoingCalls(response.calls);
}
this.logTelemetry(CallHierarchyCallsFromEvent, CallHierarchyRequestStatus.Succeeded);
return result.length !== 0 ? result : undefined;
return result;
}
private makeVscodeCallHierarchyItem(item: CallHierarchyItem): vscode.CallHierarchyItem {
const containerDetail: string = (item.detail !== "") ? `${item.detail} - ` : "";
const itemUri: vscode.Uri = vscode.Uri.file(item.file);
// Get file detail
const isInWorkspace: boolean = this.client.RootUri !== undefined &&
itemUri.fsPath.startsWith(this.client.RootUri?.fsPath);
const dirPath: string = isInWorkspace ?
path.relative(this.client.RootPath, path.dirname(item.file)) : path.dirname(item.file);
const fileDetail: string = dirPath.length === 0 ?
`${path.basename(item.file)}` : `${path.basename(item.file)} (${dirPath})`;
return new vscode.CallHierarchyItem(
item.kind,
item.name,
containerDetail + fileDetail,
itemUri,
makeVscodeRange(item.range),
makeVscodeRange(item.selectionRange));
}
private createIncomingCalls(calls: CallHierarchyCallsItem[]): vscode.CallHierarchyIncomingCall[] {
const result: vscode.CallHierarchyIncomingCall[] = [];
for (const call of calls) {
const item: vscode.CallHierarchyItem = this.makeVscodeCallHierarchyItem(call.item);
const ranges: vscode.Range[] = [];
call.fromRanges.forEach(r => {
ranges.push(makeVscodeRange(r));
});
const incomingCall: vscode.CallHierarchyIncomingCall =
new vscode.CallHierarchyIncomingCall(item, ranges);
result.push(incomingCall);
}
return result;
}
private createOutgoingCalls(calls: CallHierarchyCallsItem[]): vscode.CallHierarchyOutgoingCall[] {
const result: vscode.CallHierarchyOutgoingCall[] = [];
for (const call of calls) {
const item: vscode.CallHierarchyItem = this.makeVscodeCallHierarchyItem(call.item);
const ranges: vscode.Range[] = [];
call.fromRanges.forEach(r => {
ranges.push(makeVscodeRange(r));
});
const outgoingCall: vscode.CallHierarchyOutgoingCall =
new vscode.CallHierarchyOutgoingCall(item, ranges);
result.push(outgoingCall);
}
return result;
}
private logTelemetry(eventName: string, requestStatus: CallHierarchyRequestStatus, progressBarDuration?: number): void {
@@ -11,50 +11,6 @@ import { CancellationSender, ReferenceInfo, ReferenceType, ReferencesParams, Ref
const FindAllReferencesRequest: RequestType<ReferencesParams, ReferencesResult, void> =
new RequestType<ReferencesParams, ReferencesResult, void>('cpptools/findAllReferences');
export interface FindAllReferencesResult {
referencesResult: ReferencesResult;
locations: vscode.Location[];
}
function convertConfirmedReferencesToLocations(referencesResult: ReferencesResult): vscode.Location[] {
const locationsResult: vscode.Location[] = [];
referencesResult.referenceInfos.forEach((referenceInfo: ReferenceInfo) => {
if (referenceInfo.type === ReferenceType.Confirmed) {
const uri: vscode.Uri = vscode.Uri.file(referenceInfo.file);
const range: vscode.Range = new vscode.Range(referenceInfo.position.line, referenceInfo.position.character,
referenceInfo.position.line, referenceInfo.position.character + referencesResult.text.length);
locationsResult.push(new vscode.Location(uri, range));
}
});
return locationsResult;
}
export async function sendFindAllReferencesRequest(client: DefaultClient, uri: vscode.Uri, position: vscode.Position, token: vscode.CancellationToken): Promise<FindAllReferencesResult | undefined> {
const params: ReferencesParams = {
newName: "",
position: Position.create(position.line, position.character),
textDocument: { uri: uri.toString() }
};
let response: ReferencesResult;
try {
response = await client.languageClient.sendRequest(FindAllReferencesRequest, params, token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
if (token.isCancellationRequested || response.isCanceled) {
return undefined;
}
return {
referencesResult: response,
locations: convertConfirmedReferencesToLocations(response)
};
}
export class FindAllReferencesProvider implements vscode.ReferenceProvider {
private client: DefaultClient;
@@ -73,10 +29,23 @@ export class FindAllReferencesProvider implements vscode.ReferenceProvider {
const requestCanceledListener: vscode.Disposable = workspaceReferences.onCancellationRequested(_sender => { cancelSource.cancel(); });
// Send the request to the language server.
let result: FindAllReferencesResult | undefined;
const locationsResult: vscode.Location[] = [];
const params: ReferencesParams = {
newName: "",
position: Position.create(position.line, position.character),
textDocument: { uri: document.uri.toString() }
};
let response: ReferencesResult | undefined;
let cancelled: boolean = false;
try {
result = await sendFindAllReferencesRequest(this.client, document.uri, position, cancelSource.token);
} finally {
response = await this.client.languageClient.sendRequest(FindAllReferencesRequest, params, cancelSource.token);
} catch (e: any) {
cancelled = e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled);
if (!cancelled) {
throw e;
}
}
finally {
// Reset anything that can be cleared before processing the result.
workspaceReferences.resetProgressBar();
cancellationTokenListener.dispose();
@@ -84,21 +53,30 @@ export class FindAllReferencesProvider implements vscode.ReferenceProvider {
}
// Process the result.
if (cancelSource.token.isCancellationRequested || !result) {
if (cancelSource.token.isCancellationRequested || cancelled || (response && response.isCanceled)) {
// Return undefined instead of vscode.CancellationError to avoid the following error message from VS Code:
// "Cannot destructure property 'range' of 'e.location' as it is undefined."
// TODO: per issue https://github.com/microsoft/vscode/issues/169698
// vscode.CancellationError is expected, so when VS Code fixes the error use vscode.CancellationError again.
workspaceReferences.resetReferences();
return undefined;
} else if (result.referencesResult.referenceInfos.length > 0) {
} else if (response && response.referenceInfos.length > 0) {
response.referenceInfos.forEach((referenceInfo: ReferenceInfo) => {
if (referenceInfo.type === ReferenceType.Confirmed) {
const uri: vscode.Uri = vscode.Uri.file(referenceInfo.file);
const range: vscode.Range = new vscode.Range(referenceInfo.position.line, referenceInfo.position.character,
referenceInfo.position.line, referenceInfo.position.character + response.text.length);
locationsResult.push(new vscode.Location(uri, range));
}
});
// Display other reference types in panel or channel view.
// Note: ReferencesManager.resetReferences is called in ReferencesManager.showResultsInPanelView
workspaceReferences.showResultsInPanelView(result.referencesResult);
workspaceReferences.showResultsInPanelView(response);
} else {
workspaceReferences.resetReferences();
}
return result.locations;
return locationsResult;
}
}
@@ -1,57 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
import { Definition, DefinitionLink, DefinitionRequest, Position, ResponseError, TextDocumentPositionParams } from 'vscode-languageclient';
import { DefaultClient } from '../client';
import { RequestCancelled, ServerCancelled } from '../protocolFilter';
function convertDefinitionsToLocations(definitionsResult: vscode.Definition | vscode.DefinitionLink[] | undefined): vscode.Location[] {
if (!definitionsResult) {
return [];
}
if (!Array.isArray(definitionsResult)) {
return [definitionsResult];
}
const result: vscode.Location[] = [];
for (const definition of definitionsResult) {
if (definition instanceof vscode.Location) {
result.push(definition);
} else {
result.push(new vscode.Location(definition.targetUri, definition.targetSelectionRange ?? definition.targetRange));
}
}
return result;
}
export async function sendGoToDefinitionRequest(client: DefaultClient, uri: vscode.Uri, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Location[] | undefined> {
const params: TextDocumentPositionParams = {
position: Position.create(position.line, position.character),
textDocument: { uri: uri.toString() }
};
let response: Definition | DefinitionLink[] | null;
try {
response = await client.languageClient.sendRequest(DefinitionRequest.type, params, token);
} catch (e: any) {
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
return undefined;
}
throw e;
}
if (token.isCancellationRequested) {
return undefined;
}
const result: vscode.Definition | vscode.DefinitionLink[] | undefined =
await client.languageClient.protocol2CodeConverter.asDefinitionResult(response, token);
if (token.isCancellationRequested) {
return undefined;
}
return convertDefinitionsToLocations(result);
}
+62 -1
View File
@@ -805,6 +805,7 @@ export interface Client {
setCurrentConfigName(configurationName: string): Thenable<void>;
getCurrentConfigName(): Thenable<string | undefined>;
getCurrentConfigCustomVariable(variableName: string): Thenable<string>;
waitForIdle(timeout?: number): Promise<boolean>;
getVcpkgInstalled(): Thenable<boolean>;
getVcpkgEnabled(): Thenable<boolean>;
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined>;
@@ -919,6 +920,7 @@ export class DefaultClient implements Client {
private configStateReceived: ConfigStateReceived = { compilers: false, compileCommands: false, configProviders: undefined, timeout: false };
private showConfigureIntelliSenseButton: boolean = false;
private pendingIdleCalls: { promise: ManualPromise<boolean>; timer?: NodeJS.Timeout }[] = [];
/** A queue of asynchronous tasks that need to be processed befofe ready is considered active. */
private static queue = new Array<[ManualPromise<unknown>, () => Promise<unknown>] | [ManualPromise<unknown>]>();
@@ -1008,6 +1010,56 @@ export class DefaultClient implements Client {
};
}
private isIdle(): boolean {
return !this.model.isInitializingWorkspace.Value
&& !this.model.isIndexingWorkspace.Value
&& !this.model.isParsingWorkspace.Value
&& !this.model.isParsingFiles.Value
&& !this.model.isUpdatingIntelliSense.Value;
}
private resolvePendingIdleCallsIfReady(): void {
if (!this.pendingIdleCalls.length || !this.isIdle()) {
return;
}
const pendingCalls: { promise: ManualPromise<boolean>; timer?: NodeJS.Timeout }[] = this.pendingIdleCalls;
this.pendingIdleCalls = [];
pendingCalls.forEach(pendingCall => {
if (pendingCall.timer) {
clearTimeout(pendingCall.timer);
}
pendingCall.promise.resolve(true);
});
}
public async waitForIdle(timeout?: number): Promise<boolean> {
if (this.isIdle()) {
return true;
}
if (timeout !== undefined && timeout <= 0) {
return false;
}
const pendingCall: { promise: ManualPromise<boolean>; timer?: NodeJS.Timeout } = {
promise: new ManualPromise<boolean>()
};
if (timeout !== undefined) {
pendingCall.timer = global.setTimeout(() => {
const index: number = this.pendingIdleCalls.indexOf(pendingCall);
if (index !== -1) {
this.pendingIdleCalls.splice(index, 1);
}
pendingCall.promise.resolve(false);
}, timeout);
}
this.pendingIdleCalls.push(pendingCall);
return pendingCall.promise;
}
private getName(workspaceFolder?: vscode.WorkspaceFolder): string {
return workspaceFolder ? workspaceFolder.name : "untitled";
}
@@ -1537,7 +1589,6 @@ export class DefaultClient implements Client {
vcFormatSpaceAroundTernaryOperator: settings.vcFormatSpaceAroundTernaryOperator,
vcFormatWrapPreserveBlocks: settings.vcFormatWrapPreserveBlocks,
doxygenGenerateOnType: settings.doxygenGenerateOnType,
doxygenGenerateOnCodeAction: settings.doxygenGenerateOnCodeAction,
doxygenGeneratedStyle: settings.doxygenGeneratedCommentStyle,
doxygenSectionTags: settings.doxygenSectionTags,
filesExclude: otherSettings.filesExclude,
@@ -2893,6 +2944,8 @@ export class DefaultClient implements Client {
} else if (message.includes("/")) {
this.lastInvokedLspMessage = message;
}
this.resolvePendingIdleCallsIfReady();
}
private updateTagParseStatus(tagParseStatus: TagParseStatus): void {
@@ -4208,6 +4261,13 @@ export class DefaultClient implements Client {
}
public dispose(): void {
this.pendingIdleCalls.forEach(pendingCall => {
if (pendingCall.timer) {
clearTimeout(pendingCall.timer);
}
pendingCall.promise.resolve(false);
});
this.pendingIdleCalls = [];
this.disposables.forEach((d) => d.dispose());
this.disposables = [];
if (this.documentFormattingProviderDisposable) {
@@ -4360,6 +4420,7 @@ class NullClient implements Client {
setCurrentConfigName(configurationName: string): Thenable<void> { return Promise.resolve(); }
getCurrentConfigName(): Thenable<string> { return Promise.resolve(""); }
getCurrentConfigCustomVariable(variableName: string): Thenable<string> { return Promise.resolve(""); }
waitForIdle(timeout?: number): Promise<boolean> { return Promise.resolve(true); }
getVcpkgInstalled(): Thenable<boolean> { return Promise.resolve(false); }
getVcpkgEnabled(): Thenable<boolean> { return Promise.resolve(false); }
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined> { return Promise.resolve(undefined); }
+12 -86
View File
@@ -17,15 +17,12 @@ import { TargetPopulation } from 'vscode-tas-client';
import * as which from 'which';
import { logAndReturn } from '../Utility/Async/returns';
import * as util from '../common';
import { isWindows } from '../constants';
import { isWindows, modelSelector } from '../constants';
import { instrument } from '../instrumentation';
import { getCrashCallStacksChannel } from '../logger';
import { PlatformInformation } from '../platform';
import * as telemetry from '../telemetry';
import { CopilotHoverProvider } from './Providers/CopilotHoverProvider';
import { sendCallHierarchyCallsFromRequest, sendCallHierarchyCallsToRequest, sendPrepareCallHierarchyRequest } from './Providers/callHierarchyProvider';
import { sendFindAllReferencesRequest } from './Providers/findAllReferencesProvider';
import { sendGoToDefinitionRequest } from './Providers/goToDefinitionProvider';
import { Client, DefaultClient, DoxygenCodeActionCommandArguments, openFileVersions } from './client';
import { ClientCollection } from './clientCollection';
import { CodeActionDiagnosticInfo, CodeAnalysisDiagnosticIdentifiersAndUri, codeAnalysisAllFixes, codeAnalysisCodeToFixes, codeAnalysisFileToCodeActions } from './codeAnalysis';
@@ -275,6 +272,7 @@ export async function activate(): Promise<void> {
}
await registerRelatedFilesProvider();
await vscode.commands.executeCommand('setContext', 'cpptools.languageServerActivated', true);
}
export function updateLanguageConfigurations(): void {
@@ -400,11 +398,6 @@ export async function registerCommands(enabled: boolean): Promise<void> {
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowActiveCodeAnalysisCommands', enabled ? onShowActiveCodeAnalysisCommands : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowIdleCodeAnalysisCommands', enabled ? onShowIdleCodeAnalysisCommands : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ShowReferencesProgress', enabled ? onShowReferencesProgress : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.FindAllReferences', enabled ? onFindAllReferences : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.GoToDefinition', enabled ? onGoToDefinition : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.PrepareCallHierarchy', enabled ? onPrepareCallHierarchy : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.CallHierarchyCallsTo', enabled ? onCallHierarchyCallsTo : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.CallHierarchyCallsFrom', enabled ? onCallHierarchyCallsFrom : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.TakeSurvey', enabled ? onTakeSurvey : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.LogDiagnostics', enabled ? onLogDiagnostics : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.RescanWorkspace', enabled ? onRescanWorkspace : onDisabledCommand));
@@ -429,6 +422,7 @@ export async function registerCommands(enabled: boolean): Promise<void> {
commandDisposables.push(vscode.commands.registerCommand('cpptools.activeConfigName', enabled ? onGetActiveConfigName : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('cpptools.activeConfigCustomVariable', enabled ? onGetActiveConfigCustomVariable : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('cpptools.setActiveConfigName', enabled ? onSetActiveConfigName : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.waitForIdle', enabled ? onWaitForIdle : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.RestartIntelliSenseForFile', enabled ? onRestartIntelliSenseForFile : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.GenerateDoxygenComment', enabled ? onGenerateDoxygenComment : onDisabledCommand));
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.CreateDeclarationOrDefinition', enabled ? onCreateDeclarationOrDefinition : onDisabledCommand));
@@ -816,77 +810,6 @@ function onShowReferencesProgress(): void {
void clients.ActiveClient.handleReferencesIcon().catch(logAndReturn.undefined);
}
async function onFindAllReferences(uri: vscode.Uri, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.Location[] | undefined> {
if (!uri || !position) {
throw new Error("C_Cpp.FindAllReferences requires both a uri and position.");
}
const client: Client = clients.getClientFor(uri);
if (!(client instanceof DefaultClient)) {
return undefined;
}
await client.ready;
const result = await sendFindAllReferencesRequest(client, uri, position, token ?? CancellationToken.None);
return result?.locations;
}
async function onGoToDefinition(uri: vscode.Uri, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.Location[] | undefined> {
if (!uri || !position) {
throw new Error("C_Cpp.GoToDefinition requires both a uri and position.");
}
const client: Client = clients.getClientFor(uri);
if (!(client instanceof DefaultClient)) {
return undefined;
}
await client.ready;
return sendGoToDefinitionRequest(client, uri, position, token ?? CancellationToken.None);
}
async function onPrepareCallHierarchy(uri: vscode.Uri, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyItem[] | undefined> {
if (!uri || !position) {
throw new Error("C_Cpp.PrepareCallHierarchy requires both a uri and position.");
}
const client: Client = clients.getClientFor(uri);
if (!(client instanceof DefaultClient)) {
return undefined;
}
await client.ready;
return sendPrepareCallHierarchyRequest(client, uri, position, token ?? CancellationToken.None);
}
async function onCallHierarchyCallsTo(item: vscode.CallHierarchyItem, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[] | undefined> {
if (!item) {
throw new Error("C_Cpp.CallHierarchyCallsTo requires an item.");
}
const client: Client = clients.getClientFor(item.uri);
if (!(client instanceof DefaultClient)) {
return undefined;
}
await client.ready;
return sendCallHierarchyCallsToRequest(client, item, token ?? CancellationToken.None);
}
async function onCallHierarchyCallsFrom(item: vscode.CallHierarchyItem, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[] | undefined> {
if (!item) {
throw new Error("C_Cpp.CallHierarchyCallsFrom requires an item.");
}
const client: Client = clients.getClientFor(item.uri);
if (!(client instanceof DefaultClient)) {
return undefined;
}
await client.ready;
return sendCallHierarchyCallsFromRequest(client, item, token ?? CancellationToken.None);
}
function onToggleRefGroupView(): void {
// Set context to switch icons
const client: Client = getActiveClient();
@@ -984,6 +907,13 @@ function onRescanWorkspace(): Promise<void> {
return clients.ActiveClient.rescanFolder();
}
async function onWaitForIdle(timeout?: number): Promise<boolean> {
const pending: Promise<boolean>[] = [];
clients.forEach(client => pending.push(client.waitForIdle(timeout)));
const results: boolean[] = await Promise.all(pending);
return results.every(result => result);
}
function onShowRefCommand(arg?: TreeNode): void {
if (!arg) {
return;
@@ -1550,12 +1480,8 @@ async function onCopilotHover(): Promise<void> {
let chatResponse: vscode.LanguageModelChatResponse | undefined;
try {
// Select the chat model (refresh from cache).
const model = await copilotHoverProvider.refreshCachedChatModel();
if (!model) {
await reportCopilotFailure(copilotHoverProvider, hoverDocument, hoverPosition, "Copilot model not available.");
return;
}
// Select the chat model.
const [model] = await vscodelm.selectChatModels(modelSelector);
chatResponse = await model.sendRequest(
messages,
-2
View File
@@ -126,7 +126,6 @@ export interface WorkspaceFolderSettingsParams {
vcFormatSpaceAroundTernaryOperator: string;
vcFormatWrapPreserveBlocks: string;
doxygenGenerateOnType: boolean;
doxygenGenerateOnCodeAction: boolean;
doxygenGeneratedStyle: string;
doxygenSectionTags: string[];
filesExclude: Excludes;
@@ -384,7 +383,6 @@ export class CppSettings extends Settings {
public get simplifyStructuredComments(): boolean { return this.getAsBoolean("simplifyStructuredComments"); }
public get doxygenGeneratedCommentStyle(): string { return this.getAsString("doxygen.generatedStyle"); }
public get doxygenGenerateOnType(): boolean { return this.getAsBoolean("doxygen.generateOnType"); }
public get doxygenGenerateOnCodeAction(): boolean { return this.getAsBoolean("doxygen.generateOnCodeAction"); }
public get commentContinuationPatterns(): (string | CommentPattern)[] {
const value: any = super.Section.get<any>("commentContinuationPatterns");
if (this.isArrayOfCommentContinuationPatterns(value)) {
+3 -41
View File
@@ -1549,6 +1549,7 @@ export function hasMsvcEnvironment(): boolean {
'INCLUDE',
'LIB',
'LIBPATH',
'UCRTVersion',
'UniversalCRTSdkDir',
'VCIDEInstallDir',
'VCINSTALLDIR',
@@ -1567,34 +1568,6 @@ export function hasMsvcEnvironment(): boolean {
);
}
export function getMissingMsvcEnvironmentVariables(): string[] {
const msvcEnvVars: string[] = [
'DevEnvDir',
'Framework40Version',
'FrameworkDir',
'FrameworkVersion',
'INCLUDE',
'LIB',
'LIBPATH',
'UCRTVersion',
'UniversalCRTSdkDir',
'VCIDEInstallDir',
'VCINSTALLDIR',
'VCToolsRedistDir',
'VisualStudioVersion',
'VSINSTALLDIR',
'WindowsLibPath',
'WindowsSdkBinPath',
'WindowsSdkDir',
'WindowsSDKLibVersion',
'WindowsSDKVersion'
];
return msvcEnvVars.filter(envVarName =>
(process.env[envVarName] === undefined || process.env[envVarName] === '') &&
extensionContext?.environmentVariableCollection?.get(envVarName) === undefined
);
}
function isIntegral(str: string): boolean {
const regex = /^-?\d+$/;
return regex.test(str);
@@ -1695,7 +1668,7 @@ export interface IQuotedString {
export type CommandString = string | IQuotedString;
export function buildShellCommandLine(originalCommand: CommandString, command: CommandString, args: CommandString[], singleCommandOnly: boolean = false): string {
export function buildShellCommandLine(originalCommand: CommandString, command: CommandString, args: CommandString[]): string {
let shellQuoteOptions: IShellQuotingOptions;
const isWindows: boolean = os.platform() === 'win32';
@@ -1809,7 +1782,7 @@ export function buildShellCommandLine(originalCommand: CommandString, command: C
let commandLine = result.join(' ');
// There are special rules quoted command line in cmd.exe
if (isWindows && !singleCommandOnly) {
if (isWindows) {
commandLine = `chcp 65001>nul && ${commandLine}`;
if (commandQuoted && argQuoted) {
commandLine = '"' + commandLine + '"';
@@ -1877,14 +1850,3 @@ export function getVSCodeLanguageModel(): any | undefined {
}
return vscodelm;
}
export function sessionIsWsl(): boolean {
if (process.env.WSL_DISTRO_NAME) {
return true;
}
try {
return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
} catch {
return false;
}
}
@@ -1,21 +0,0 @@
#include <fstream>
int main(int argc, char *argv[]) {
if (argc < 2) {
return 1;
}
std::ofstream resultFile(argv[1]);
if (!resultFile) {
return 2;
}
for (int i = 2; i < argc; ++i) {
resultFile << argv[i];
if (i + 1 < argc) {
resultFile << '\n';
}
}
return 0;
}
@@ -1,11 +0,0 @@
#include <fstream>
int main() {
std::ofstream resultFile("runWithoutDebuggingResult.txt");
if (!resultFile) {
return 1;
}
resultFile << 37;
return 0;
}
@@ -1,72 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="../../../../vscode.d.ts" />
import * as assert from 'assert';
import * as cp from 'child_process';
import * as vscode from 'vscode';
import * as util from '../../../../src/common';
import { isLinux, isMacOS, isWindows } from '../../../../src/constants';
import { getEffectiveEnvironment } from '../../../../src/LanguageServer/devcmd';
interface ProcessResult {
code: number | null;
stdout: string;
stderr: string;
}
function runProcess(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<ProcessResult> {
return new Promise((resolve, reject) => {
const child = cp.spawn(command, args, { cwd, env });
let stdout = '';
let stderr = '';
child.stdout.on('data', (data: Buffer) => {
stdout += data.toString();
});
child.stderr.on('data', (data: Buffer) => {
stderr += data.toString();
});
child.on('error', reject);
child.on('close', (code) => resolve({ code, stdout, stderr }));
});
}
async function setWindowsBuildEnvironment(): Promise<void> {
const promise = vscode.commands.executeCommand('C_Cpp.SetVsDeveloperEnvironment', 'test');
const timer = setInterval(() => {
void vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
}, 1000);
await promise;
clearInterval(timer);
const missingVars = util.getMissingMsvcEnvironmentVariables();
assert.strictEqual(missingVars.length, 0, `MSVC environment missing: ${missingVars.join(', ')}`);
}
export async function compileProgram(workspacePath: string, sourcePath: string, outputPath: string): Promise<void> {
if (isWindows) {
await setWindowsBuildEnvironment();
const env = getEffectiveEnvironment();
const result = await runProcess('cl.exe', ['/nologo', '/EHsc', '/Zi', '/std:c++17', `/Fe:${outputPath}`, sourcePath], workspacePath, env);
assert.strictEqual(result.code, 0, `MSVC compilation failed. stdout: ${result.stdout}\nstderr: ${result.stderr}`);
return;
}
if (isMacOS) {
const result = await runProcess('clang++', ['-std=c++17', '-g', sourcePath, '-o', outputPath], workspacePath);
assert.strictEqual(result.code, 0, `clang++ compilation failed. stdout: ${result.stdout}\nstderr: ${result.stderr}`);
return;
}
if (isLinux) {
const result = await runProcess('g++', ['-std=c++17', '-g', sourcePath, '-o', outputPath], workspacePath);
assert.strictEqual(result.code, 0, `g++ compilation failed. stdout: ${result.stdout}\nstderr: ${result.stderr}`);
return;
}
assert.fail(`Unsupported test platform: ${process.platform}`);
}
@@ -1,267 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="../../../../vscode.d.ts" />
import * as assert from 'assert';
import { suite } from 'mocha';
import * as path from 'path';
import * as vscode from 'vscode';
import * as util from '../../../../src/common';
import { isMacOS, isWindows } from '../../../../src/constants';
import { compileProgram } from './compileProgram';
interface TrackerState {
setBreakpointsRequestReceived: boolean;
stoppedEventReceived: boolean;
exitedEventReceived: boolean;
exitedBeforeStop: boolean;
}
interface TrackerController {
state: TrackerState;
lastEvent: Promise<'stopped' | 'exited'>;
dispose(): void;
}
async function createBreakpointAtResultWriteStatement(sourceUri: vscode.Uri): Promise<vscode.SourceBreakpoint> {
const document = await vscode.workspace.openTextDocument(sourceUri);
const resultWriteLine = document.getText().split(/\r?\n/).findIndex((line) => line.includes('resultFile << 37;'));
assert.notStrictEqual(resultWriteLine, -1, 'Unable to find expected result-write statement for breakpoint placement.');
const breakpoint = new vscode.SourceBreakpoint(new vscode.Location(sourceUri, new vscode.Position(resultWriteLine, 0)), true);
vscode.debug.addBreakpoints([breakpoint]);
return breakpoint;
}
function createSessionTerminatedPromise(sessionName: string): Promise<void> {
return new Promise<void>((resolve) => {
const terminateSubscription = vscode.debug.onDidTerminateDebugSession((session) => {
if (session.name === sessionName) {
terminateSubscription.dispose();
resolve();
}
});
});
}
function createTracker(debugType: string, sessionName: string, timeoutMs: number, timeoutMessage: string): TrackerController {
const state: TrackerState = {
setBreakpointsRequestReceived: false,
stoppedEventReceived: false,
exitedEventReceived: false,
exitedBeforeStop: false
};
let trackerRegistration: vscode.Disposable | undefined;
let timeoutHandle: NodeJS.Timeout | undefined;
const lastEvent = new Promise<'stopped' | 'exited'>((resolve, reject) => {
timeoutHandle = setTimeout(() => {
trackerRegistration?.dispose();
trackerRegistration = undefined;
reject(new Error(timeoutMessage));
}, timeoutMs);
trackerRegistration = vscode.debug.registerDebugAdapterTrackerFactory(debugType, {
createDebugAdapterTracker: (session: vscode.DebugSession): vscode.DebugAdapterTracker | undefined => {
if (session.name !== sessionName) {
return undefined;
}
return {
onWillReceiveMessage: (message: any): void => {
if (message?.type === 'request' && message?.command === 'setBreakpoints') {
state.setBreakpointsRequestReceived = true;
}
},
onDidSendMessage: (message: any): void => {
if (message?.type !== 'event') {
return;
}
if (message.event === 'stopped') {
state.stoppedEventReceived = true;
if (timeoutHandle) {
clearTimeout(timeoutHandle);
timeoutHandle = undefined;
}
resolve('stopped');
}
if ((message.event === 'terminated' || message.event === 'exited') && !state.exitedEventReceived) {
state.exitedEventReceived = true;
if (!state.stoppedEventReceived) {
state.exitedBeforeStop = true;
}
if (timeoutHandle) {
clearTimeout(timeoutHandle);
timeoutHandle = undefined;
}
resolve('exited');
}
}
};
}
});
});
return {
state,
lastEvent,
dispose(): void {
if (timeoutHandle) {
clearTimeout(timeoutHandle);
timeoutHandle = undefined;
}
trackerRegistration?.dispose();
trackerRegistration = undefined;
}
};
}
async function waitForResultFileValue(filePath: string, timeoutMs: number): Promise<number> {
const deadline = Date.now() + timeoutMs;
let lastContents = '';
while (Date.now() < deadline) {
try {
lastContents = await util.readFileText(filePath, 'utf8');
const trimmedContents = lastContents.trim();
if (trimmedContents.length > 0) {
const value = Number.parseInt(trimmedContents, 10);
if (!Number.isNaN(value)) {
return value;
}
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
throw error;
}
}
await new Promise<void>(resolve => setTimeout(resolve, 100));
}
assert.fail(`Timed out waiting for numeric result in ${filePath}. Last contents: ${lastContents}`);
}
suite('Run Without Debugging Test', function (): void {
const expectedResultValue = 37;
const workspaceFolder = vscode.workspace.workspaceFolders?.[0] ?? assert.fail('No workspace folder available');
const workspacePath = workspaceFolder.uri.fsPath;
const sourceFile = path.join(workspacePath, 'debugTest.cpp');
const sourceUri = vscode.Uri.file(sourceFile);
const resultFilePath = path.join(workspacePath, 'runWithoutDebuggingResult.txt');
const executableName = isWindows ? 'debugTestProgram.exe' : 'debugTestProgram';
const executablePath = path.join(workspacePath, executableName);
const sessionName = 'Run Without Debugging Result File';
const debugType = isWindows ? 'cppvsdbg' : 'cppdbg';
const miMode = isMacOS ? 'lldb' : 'gdb';
suiteSetup(async function (): Promise<void> {
const extension: vscode.Extension<any> = vscode.extensions.getExtension('ms-vscode.cpptools') || assert.fail('Extension not found');
if (!extension.isActive) {
await extension.activate();
}
await compileProgram(workspacePath, sourceFile, executablePath);
});
suiteTeardown(async function (): Promise<void> {
if (isWindows) {
await vscode.commands.executeCommand('C_Cpp.ClearVsDeveloperEnvironment');
}
});
setup(async function (): Promise<void> {
await util.deleteFile(resultFilePath);
});
test('Run Without Debugging should not break on breakpoints and write the expected result file', async () => {
const breakpoint = await createBreakpointAtResultWriteStatement(sourceUri);
const tracker = createTracker(debugType, sessionName, 30000, 'Timed out waiting for debugger event.');
const debugSessionTerminated = createSessionTerminatedPromise(sessionName);
try {
const started = await vscode.debug.startDebugging(
workspaceFolder,
{
name: sessionName,
type: debugType,
request: 'launch',
program: executablePath,
args: [],
cwd: workspacePath,
externalConsole: debugType === 'cppdbg' ? false : undefined,
console: debugType === 'cppvsdbg' ? 'internalConsole' : undefined
},
{ noDebug: true });
assert.strictEqual(started, true, 'The noDebug launch did not start successfully.');
const lastEvent = await tracker.lastEvent;
await debugSessionTerminated;
const actualResultValue = await waitForResultFileValue(resultFilePath, 10000);
assert.strictEqual(lastEvent, 'exited', 'No-debug launch should exit rather than stop on a breakpoint.');
assert.strictEqual(tracker.state.setBreakpointsRequestReceived, false, 'a "no debug" session should not send setBreakpoints requests.');
assert.strictEqual(tracker.state.stoppedEventReceived, false, 'a "no debug" session should not emit stopped events.');
assert.strictEqual(actualResultValue, expectedResultValue, 'Unexpected result value from run without debugging launch.');
} finally {
tracker.dispose();
vscode.debug.removeBreakpoints([breakpoint]);
await util.deleteFile(resultFilePath);
}
});
test('Debug launch should bind and stop at the breakpoint', async () => {
const breakpoint = await createBreakpointAtResultWriteStatement(sourceUri);
const tracker = createTracker(debugType, sessionName, 30000, 'Timed out waiting for debugger event in normal debug mode.');
const debugSessionTerminated = createSessionTerminatedPromise(sessionName);
let launchedSession: vscode.DebugSession | undefined;
const startedSubscription = vscode.debug.onDidStartDebugSession((session) => {
if (session.name === sessionName) {
launchedSession = session;
}
});
try {
const started = await vscode.debug.startDebugging(
workspaceFolder,
{
name: sessionName,
type: debugType,
request: 'launch',
program: executablePath,
args: [],
cwd: workspacePath,
MIMode: debugType === 'cppdbg' ? miMode : undefined,
externalConsole: debugType === 'cppdbg' ? false : undefined,
console: debugType === 'cppvsdbg' ? 'internalConsole' : undefined
},
{ noDebug: false });
assert.strictEqual(started, true, 'The debug launch did not start successfully.');
const lastEvent = await tracker.lastEvent;
assert.strictEqual(lastEvent, 'stopped', 'Debug launch should stop at the breakpoint before exit.');
assert.strictEqual(tracker.state.setBreakpointsRequestReceived, true, 'Debug mode should send setBreakpoints requests.');
assert.strictEqual(tracker.state.stoppedEventReceived, true, 'Debug mode should emit a stopped event at the breakpoint.');
assert.strictEqual(tracker.state.exitedBeforeStop, false, 'Program exited before stopping at breakpoint in debug mode.');
assert.strictEqual(vscode.debug.activeDebugSession?.name, sessionName, 'Debug session should still be active at breakpoint.');
const stoppedSession = launchedSession ?? vscode.debug.activeDebugSession;
assert.ok(stoppedSession, 'Unable to identify the running debug session for termination.');
await vscode.debug.stopDebugging(stoppedSession);
await debugSessionTerminated;
} finally {
startedSubscription.dispose();
tracker.dispose();
vscode.debug.removeBreakpoints([breakpoint]);
await util.deleteFile(resultFilePath);
}
});
});
@@ -1,190 +0,0 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="../../../../vscode.d.ts" />
import * as assert from 'assert';
import { suite } from 'mocha';
import * as path from 'path';
import * as vscode from 'vscode';
import * as util from '../../../../src/common';
import { isWindows } from '../../../../src/constants';
import { compileProgram } from './compileProgram';
type ConsoleMode = 'integratedTerminal' | 'externalTerminal';
type WindowsTerminalProfile = 'Command Prompt' | 'PowerShell';
/**
* Waits for the output of a program to be written to a file and returns the lines of output.
* @param filePath The path to the file containing the program output.
* @param timeoutMs The maximum time to wait for the output, in milliseconds.
* @returns A promise that resolves to an array of output lines.
* @throws An error if the output is not available within the specified timeout.
*/
async function waitForOutput(filePath: string, timeoutMs: number): Promise<string[]> {
const deadline = Date.now() + timeoutMs;
let lastContents = '';
while (Date.now() < deadline) {
try {
lastContents = await util.readFileText(filePath, 'utf8');
const trimmedContents = lastContents.trimEnd();
if (trimmedContents.length > 0) {
return trimmedContents.split(/\r?\n/);
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
throw error;
}
}
await new Promise<void>(resolve => setTimeout(resolve, 100));
}
assert.fail(`Timed out waiting for argument output in ${filePath}. Last contents: ${lastContents}`);
}
/**
* Disposes of any terminals whose names match the given program paths. These are the terminals that were created to run the specified programs.
* @param programs An array of program paths whose corresponding terminals should be disposed.
*/
function disposeTerminals(programs: string[]): void {
const terminalNames = new Set(programs.map(program => path.normalize(program)));
for (const terminal of vscode.window.terminals) {
if (terminalNames.has(terminal.name)) {
terminal.dispose();
}
}
}
/**
* Sets or clears the setting for the default Windows terminal profile.
* @param profile The terminal profile to set as the default, or undefined to clear the setting.
*/
async function setWindowsDefaultTerminalProfile(profile?: WindowsTerminalProfile): Promise<void> {
if (!isWindows) {
return;
}
const config = vscode.workspace.getConfiguration('terminal.integrated');
await config.update('defaultProfile.windows', profile, vscode.ConfigurationTarget.Workspace);
}
async function runNoDebugLaunch(workspaceFolder: vscode.WorkspaceFolder, sessionName: string, program: string, consoleMode: ConsoleMode, resultFilePath: string, args: string[]): Promise<string[]> {
const debugType = isWindows ? 'cppvsdbg' : 'cppdbg';
const launchConfig: vscode.DebugConfiguration = {
name: sessionName,
type: debugType,
request: 'launch',
program: program,
args: [resultFilePath, ...args],
cwd: workspaceFolder.uri.fsPath
};
if (debugType === 'cppvsdbg') {
launchConfig.console = consoleMode;
} else {
launchConfig.externalConsole = consoleMode === 'externalTerminal';
}
const started = await vscode.debug.startDebugging(workspaceFolder, launchConfig, { noDebug: true });
assert.strictEqual(started, true, `The ${consoleMode} noDebug launch did not start successfully.`);
return waitForOutput(resultFilePath, 15000);
}
suite('Run Without Debugging Terminal and Arguments Test', function (this: Mocha.Suite): void {
this.timeout(120000);
const workspaceFolder = vscode.workspace.workspaceFolders?.[0] ?? assert.fail('No workspace folder available');
const workspacePath = workspaceFolder.uri.fsPath;
const sourceFile = path.join(workspacePath, 'argsTest.cpp');
const resultFilePath = path.join(workspacePath, 'test_output.txt');
const executablePath = path.join(workspacePath, isWindows ? 'argsTestProgram.exe' : 'argsTestProgram');
const spacedExecutablePath = path.join(workspacePath, isWindows ? 'args Test Program.exe' : 'args Test Program');
const executablePaths = [executablePath, spacedExecutablePath];
const expectedArgs = [
'alpha',
'two words',
path.join(workspacePath, 'input folder', 'three words.txt')
];
suiteSetup(async function (): Promise<void> {
const extension: vscode.Extension<any> = vscode.extensions.getExtension('ms-vscode.cpptools') || assert.fail('Extension not found');
if (!extension.isActive) {
await extension.activate();
}
await compileProgram(workspacePath, sourceFile, executablePath);
await compileProgram(workspacePath, sourceFile, spacedExecutablePath);
});
teardown(async function (): Promise<void> {
await util.deleteFile(resultFilePath);
disposeTerminals(executablePaths);
});
setup(async function (): Promise<void> {
if (await util.checkFileExists(resultFilePath)) {
await util.deleteFile(resultFilePath);
}
});
suiteTeardown(async function (): Promise<void> {
await util.deleteFile(resultFilePath);
disposeTerminals(executablePaths);
if (isWindows) {
await vscode.commands.executeCommand('C_Cpp.ClearVsDeveloperEnvironment');
await util.deleteFile(path.join(workspacePath, '.vscode', 'settings.json'));
}
});
const consoleCases: { label: string; consoleMode: ConsoleMode; windowsProfiles?: (WindowsTerminalProfile | undefined)[] }[] = [
{
label: 'integrated terminal',
consoleMode: 'integratedTerminal',
windowsProfiles: [undefined, 'Command Prompt', 'PowerShell']
},
{
label: 'external terminal',
consoleMode: 'externalTerminal'
}
];
const programCases = [
{
label: 'a program name without spaces',
programPath: executablePath
},
{
label: 'a program name with spaces',
programPath: spacedExecutablePath
}
];
for (const consoleCase of consoleCases) {
for (const programCase of programCases) {
const profiles: (WindowsTerminalProfile | undefined)[] = isWindows && consoleCase.consoleMode === 'integratedTerminal' ? consoleCase.windowsProfiles ?? [undefined] : [undefined];
for (const profile of profiles) {
const profileSuffix = profile ? ` with ${profile} as the default terminal` : consoleCase.consoleMode === 'integratedTerminal' ? ' with default terminal' : '';
test(`No-debug launch via ${consoleCase.label} handles ${programCase.label}${profileSuffix}`, async () => {
await setWindowsDefaultTerminalProfile(profile);
disposeTerminals(executablePaths);
const sessionName = `Run Without Debugging Args (${consoleCase.consoleMode}, ${path.basename(programCase.programPath)}${profile ? `, ${profile}` : ''})`;
const actualArgs = await runNoDebugLaunch(
workspaceFolder,
sessionName,
programCase.programPath,
consoleCase.consoleMode,
resultFilePath,
expectedArgs);
assert.deepStrictEqual(actualArgs, expectedArgs, `Unexpected arguments received for ${consoleCase.label} using ${programCase.label}${profileSuffix}.`);
});
}
}
}
});
@@ -1,8 +1,9 @@
<h1 data-loc-id="walkthrough.windows.install.compiler">Install a C++ compiler on Windows</h1>
<p data-loc-id="walkthrough.windows.text1">If you&#39;re doing C++ development for Windows, we recommend installing the Microsoft Visual C++ (MSVC) compiler.</p>
<ol>
<li><p data-loc-id="walkthrough.windows.text2">To install MSVC, open the VS Code terminal (CTRL + `) and paste in the following command:</p>
<p><code>winget install Microsoft.<wbr>VisualStudio.<wbr>2022.<wbr>BuildTools --force --override "--wait --passive --add Microsoft.<wbr>VisualStudio.<wbr>Workload.<wbr>VCTools --add Microsoft.<wbr>VisualStudio.<wbr>Component.<wbr>VC.<wbr>Tools.<wbr>x86.<wbr>x64 --add Microsoft.<wbr>VisualStudio.<wbr>Component.<wbr>Windows10SDK.<wbr>19041"</code></p>
<li><p data-loc-id="walkthrough.windows.text2">To install MSVC, open the VS Code terminal (CTRL + `) and paste in the following command:
<pre><code style="white-space: pre-wrap;">winget install Microsoft.VisualStudio.2022.BuildTools --force --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.20348"</code></pre>
</li>
<blockquote>
<p><strong data-loc-id="walkthrough.windows.note1">Note</strong>: <span data-loc-id="walkthrough.windows.note1.text">You can use the C++ toolset from Visual Studio Build Tools along with Visual Studio Code to compile, build, and verify any C++ codebase as long as you also have a valid Visual Studio license (either Community, Pro, or Enterprise) that you are actively using to develop that C++ codebase.</span></p>
</blockquote>
@@ -1,8 +1,9 @@
<h1 data-loc-id="walkthrough.windows.install.compiler">Install a C++ compiler on Windows</h1>
<p data-loc-id="walkthrough.windows.text1">If you&#39;re doing C++ development for Windows, we recommend installing the Microsoft Visual C++ (MSVC) compiler.</p>
<ol>
<li><p data-loc-id="walkthrough.windows.text2">To install MSVC, open the VS Code terminal (CTRL + `) and paste in the following command:</p>
<p><code>winget install Microsoft.<wbr>VisualStudio.<wbr>2022.<wbr>BuildTools --force --override "--wait --passive --add Microsoft.<wbr>VisualStudio.<wbr>Workload.<wbr>VCTools --add Microsoft.<wbr>VisualStudio.<wbr>Component.<wbr>VC.<wbr>Tools.<wbr>x86.<wbr>x64 --add Microsoft.<wbr>VisualStudio.<wbr>Component.<wbr>Windows11SDK.<wbr>26100"</code></p>
<li><p data-loc-id="walkthrough.windows.text2">To install MSVC, open the VS Code terminal (CTRL + `) and paste in the following command:
<pre><code style="white-space: pre-wrap;">winget install Microsoft.VisualStudio.2022.BuildTools --force --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.26100"</code></pre>
</li>
<blockquote>
<p><strong data-loc-id="walkthrough.windows.note1">Note</strong>: <span data-loc-id="walkthrough.windows.note1.text">You can use the C++ toolset from Visual Studio Build Tools along with Visual Studio Code to compile, build, and verify any C++ codebase as long as you also have a valid Visual Studio license (either Community, Pro, or Enterprise) that you are actively using to develop that C++ codebase.</span></p>
</blockquote>
+1 -3
View File
@@ -1,4 +1,2 @@
registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/
always-auth=true
# Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust
ignore-scripts=true
always-auth=true
+1 -3
View File
@@ -1,4 +1,2 @@
registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/
always-auth=true
# Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust
ignore-scripts=true
always-auth=true