Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdbac5714b | ||
|
|
4d01799159 | ||
|
|
d41ba04e26 | ||
|
|
592661994a | ||
|
|
98055e0aa8 | ||
|
|
7a7c1f421b | ||
|
|
82c66b05d3 | ||
|
|
08baa1d0d2 | ||
|
|
dde8653da5 | ||
|
|
154f56e4c7 | ||
|
|
95717b4eb4 | ||
|
|
2587d00a47 | ||
|
|
77c1a14635 | ||
|
|
07a4927c41 | ||
|
|
5351c00667 |
@@ -63,7 +63,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
|
||||
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
|
||||
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from 'path';
|
||||
import { parseString } from 'xml2js';
|
||||
import { mkdir, write } from './common';
|
||||
import { glob, mkdir, write } from './common';
|
||||
|
||||
export async function main() {
|
||||
|
||||
@@ -45,11 +45,16 @@ export async function main() {
|
||||
|
||||
const locFolderNames = fs.readdirSync(localizeRepoPath).filter(f => fs.lstatSync(path.join(localizeRepoPath, f)).isDirectory());
|
||||
for (const locFolderName of locFolderNames) {
|
||||
const lclPath = path.join(localizeRepoPath, locFolderName, "vc/vc/cpfeui.dll.lcl");
|
||||
const languageInfo = languages.find(l => l.folderName === locFolderName);
|
||||
if (!languageInfo) {
|
||||
return;
|
||||
}
|
||||
const localePath = path.join(localizeRepoPath, locFolderName);
|
||||
const lclPaths = await glob("vc/vc/cpfeui.dll.lcl", { cwd: localePath, nocase: true, nodir: true });
|
||||
if (lclPaths.length !== 1) {
|
||||
throw new Error(`Expected one cpfeui.dll.lcl under '${localePath}', found ${lclPaths.length}.`);
|
||||
}
|
||||
const lclPath = path.join(localePath, lclPaths[0]);
|
||||
const languageId = languageInfo.id;
|
||||
const outputLanguageFolder = path.join(cpptoolsRepoPath, "Extension/bin/messages", languageId);
|
||||
const outputPath = path.join(outputLanguageFolder, "messages.json");
|
||||
|
||||
+33
-71
@@ -1,93 +1,55 @@
|
||||
# C/C++ for Visual Studio Code Changelog
|
||||
|
||||
## Version 1.33.7: August 11, 2026
|
||||
### Bug Fixes
|
||||
* Fix another crash when reading files saved in certain multibyte encodings such as GB18030 or EUC-JP.
|
||||
* Fix newly created files not being associated with the correct configuration in the browse database.
|
||||
* Fix the language server becoming unresponsive during browse database initialization.
|
||||
* Fix stale diagnostics and missing code actions after editing visible headers.
|
||||
* Fix `/ZW:nostdlib` not being processed correctly by IntelliSense.
|
||||
* Update dependencies.
|
||||
|
||||
## Version 1.33.6: August 4, 2026
|
||||
### Bug Fixes
|
||||
* Fix a spurious recursive includes (`**`) debug console log warning for paths merged from `c_cpp_properties.json` when `C_Cpp.mergeConfigurations` is enabled. [#14125](https://github.com/microsoft/vscode-cpptools/issues/14125)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14620](https://github.com/microsoft/vscode-cpptools/pull/14620)
|
||||
* Fix custom configurations being discarded when `C_Cpp.mergeConfigurations` is enabled and a provider supplies the file `uri` as a `vscode.Uri`. [#14621](https://github.com/microsoft/vscode-cpptools/issues/14621)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14624](https://github.com/microsoft/vscode-cpptools/pull/14624)
|
||||
* Fix a tag parser crash when a UTF-8 string literal is concatenated with a narrow string literal containing an invalid multibyte sequence.
|
||||
* Fix potential browse database corruption when the same workspace is opened by multiple processes on Linux and macOS.
|
||||
* Fix a crash when reading files saved in certain multibyte encodings such as GB18030 or EUC-JP.
|
||||
* Fix an incorrect file path in an error message on Windows.
|
||||
* Other potential crash fixes.
|
||||
* Update dependencies.
|
||||
|
||||
## Version 1.33.5: July 28, 2026
|
||||
### Bug Fixes
|
||||
* Fix the remote process picker `ps` command not working with some shells. [#14442](https://github.com/microsoft/vscode-cpptools/issues/14442)
|
||||
* Thanks for the contribution. [@HuzaifaAbdulRehman](https://github.com/HuzaifaAbdulRehman) [PR #14592](https://github.com/microsoft/vscode-cpptools/pull/14592)
|
||||
* Fix a spurious IntelliSense error with class template argument deduction (CTAD). [#14453](https://github.com/microsoft/vscode-cpptools/issues/14453), [#14459](https://github.com/microsoft/vscode-cpptools/issues/14459), [#14504](https://github.com/microsoft/vscode-cpptools/issues/14504)
|
||||
* Fix 'Run C/C++ File' not running the program in PowerShell when terminal shell integration is unavailable. [#14583](https://github.com/microsoft/vscode-cpptools/issues/14583)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14585](https://github.com/microsoft/vscode-cpptools/pull/14585)
|
||||
* Fix the build tools walkthrough for Visual Studio 2026. [PR #14589](https://github.com/microsoft/vscode-cpptools/pull/14589)
|
||||
* Fix empty database folders being created in every folder of a multi-root workspace.
|
||||
* Fix 'Rescan Workspace' triggering a full database reset instead of only a rescan.
|
||||
* Fix several potential deadlocks and data races in the language server.
|
||||
* Reduce memory usage to help avoid out-of-memory crashes.
|
||||
* Fix an incorrect `#include` casing error on Linux.
|
||||
* Fix an IntelliSense crash.
|
||||
* Various localization updates.
|
||||
* Update dependencies.
|
||||
|
||||
## Version 1.33.4: July 8, 2026
|
||||
### Bug Fixes
|
||||
* Fix the wording for the `#include` errors detected message. [#8227](https://github.com/microsoft/vscode-cpptools/issues/8227)
|
||||
* Fix another "directory_cache" crash.
|
||||
* Update some localization.
|
||||
|
||||
## Version 1.33.3: July 6, 2026
|
||||
### Enhancement
|
||||
* Allow platform overrides in `cppbuild` tasks. [#11601](https://github.com/microsoft/vscode-cpptools/issues/11601)
|
||||
|
||||
### Bug Fixes
|
||||
* Fix `[[no_unique_address]]` empty-base layout `sizeof` being computed too large. [#14524](https://github.com/microsoft/vscode-cpptools/issues/14524)
|
||||
* Fix C/C++ debug data-tips on members of a dereferenced expression. [PR #14540](https://github.com/microsoft/vscode-cpptools/pull/14540)
|
||||
* Thanks for the contribution. [@tieo](https://github.com/tieo)
|
||||
* Fix `clang-format`/`clang-tidy` version check failing on Windows. [PR #14552](https://github.com/microsoft/vscode-cpptools/pull/14552)
|
||||
* Fix Windows backslash paths being mangled when adding an SSH target. [PR #14554](https://github.com/microsoft/vscode-cpptools/pull/14554)
|
||||
* Fix "directory_cache" crashes.
|
||||
* Fix spurious IntelliSense error on `std::variant` brace-initialization.
|
||||
|
||||
## Version 1.33.2: June 26, 2026
|
||||
### Bug Fixes
|
||||
* Fix a regression with 'Find All References' with functions that exist in both C and C++ files. [#14546](https://github.com/microsoft/vscode-cpptools/issues/14546)
|
||||
|
||||
## Version 1.33.1: June 23, 2026
|
||||
### Bug Fixes
|
||||
* Fix 'Find All References' dropping valid references when a template parameter type has a typedef alias in only one translation unit. [#14344](https://github.com/microsoft/vscode-cpptools/issues/14344)
|
||||
* Fix a crash regression on file open.
|
||||
* Fix IntelliSense incorrectly resolving `#include` files through a symbolic link after the target directory was deleted from disk.
|
||||
* Fix "tag parsing finished" status randomly getting reported too soon after a 'Reset IntelliSense Database' command.
|
||||
|
||||
## Version 1.33.0: June 22, 2026
|
||||
## Version 1.33.8: August 17, 2026
|
||||
### New Feature
|
||||
* Unification of tag parsing with the VS implementation. In particular, it's now done using multiple parallel `cpptools-srv2` processes. [PR #14426](https://github.com/microsoft/vscode-cpptools/pull/14426)
|
||||
|
||||
### Enhancements
|
||||
* Allow platform overrides in `cppbuild` tasks. [#11601](https://github.com/microsoft/vscode-cpptools/issues/11601)
|
||||
* Add the `debuginfod` launch option to the `cppdbg` debugger schema. [#14458](https://github.com/microsoft/vscode-cpptools/issues/14458), [#14460](https://github.com/microsoft/vscode-cpptools/issues/14460), [PR #14471](https://github.com/microsoft/vscode-cpptools/pull/14471), [PR #14506](https://github.com/microsoft/vscode-cpptools/pull/14506), [MIEngine#1562](https://github.com/microsoft/MIEngine/issues/1562)
|
||||
* Add the `ignoreRunWithoutDebuggingWarnings` property to allow 'Run without debugging' warnings to be suppressed. [#14515](https://github.com/microsoft/vscode-cpptools/issues/14515)
|
||||
* Various localization updates.
|
||||
|
||||
### Bug Fixes
|
||||
* Fix the wording for the `#include` errors detected message. [#8227](https://github.com/microsoft/vscode-cpptools/issues/8227)
|
||||
* Fix an incorrect `invalid type conversion` IntelliSense error. [#11294](https://github.com/microsoft/vscode-cpptools/issues/11294)
|
||||
* Fix include completion (with recursive includes) still suggesting headers from a deleted folder. [#12636](https://github.com/microsoft/vscode-cpptools/issues/12636)
|
||||
* Fix a spurious recursive includes (`**`) debug console log warning for paths merged from `c_cpp_properties.json` when `C_Cpp.mergeConfigurations` is enabled. [#14125](https://github.com/microsoft/vscode-cpptools/issues/14125)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14620](https://github.com/microsoft/vscode-cpptools/pull/14620)
|
||||
* Fix 'Find All References' dropping valid references when a template parameter type has a typedef alias in only one translation unit. [#14344](https://github.com/microsoft/vscode-cpptools/issues/14344)
|
||||
* Fix the remote process picker `ps` command not working with some shells. [#14442](https://github.com/microsoft/vscode-cpptools/issues/14442)
|
||||
* Thanks for the contribution. [@HuzaifaAbdulRehman](https://github.com/HuzaifaAbdulRehman) [PR #14592](https://github.com/microsoft/vscode-cpptools/pull/14592)
|
||||
* Fix a spurious IntelliSense error with class template argument deduction (CTAD). [#14453](https://github.com/microsoft/vscode-cpptools/issues/14453), [#14459](https://github.com/microsoft/vscode-cpptools/issues/14459), [#14504](https://github.com/microsoft/vscode-cpptools/issues/14504)
|
||||
* Add `important` to `C_Cpp.doxygen.sectionTags`. [PR #14473](https://github.com/microsoft/vscode-cpptools/pull/14473)
|
||||
* Update the minimum supported VS Code version to 1.77. [PR #14502](https://github.com/microsoft/vscode-cpptools/pull/14502)
|
||||
* Fix issues with the debugger `launch.json` schema. [PR #14523](https://github.com/microsoft/vscode-cpptools/pull/14523)
|
||||
* Fix `[[no_unique_address]]` empty-base layout `sizeof` being computed too large. [#14524](https://github.com/microsoft/vscode-cpptools/issues/14524)
|
||||
* Fix `${env:VAR}` and `${env.VAR}` not expanding to an empty string when the environment variable is unset, to match VS Code's behavior. [PR #14535](https://github.com/microsoft/vscode-cpptools/pull/14535)
|
||||
* Thanks for the contribution. [@notable-equivalent](https://github.com/notable-equivalent)
|
||||
* Fix C/C++ debug data-tips on members of a dereferenced expression. [PR #14540](https://github.com/microsoft/vscode-cpptools/pull/14540)
|
||||
* Thanks for the contribution. [@tieo](https://github.com/tieo)
|
||||
* Fix Windows backslash paths being mangled when adding an SSH target. [PR #14554](https://github.com/microsoft/vscode-cpptools/pull/14554)
|
||||
* Fix 'Run C/C++ File' not running the program in PowerShell when terminal shell integration is unavailable. [#14583](https://github.com/microsoft/vscode-cpptools/issues/14583)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14585](https://github.com/microsoft/vscode-cpptools/pull/14585)
|
||||
* Fix the build tools walkthrough for Visual Studio 2026. [PR #14589](https://github.com/microsoft/vscode-cpptools/pull/14589)
|
||||
* Fix custom configurations being discarded when `C_Cpp.mergeConfigurations` is enabled and a provider supplies the file `uri` as a `vscode.Uri`. [#14621](https://github.com/microsoft/vscode-cpptools/issues/14621)
|
||||
* Thanks for the contribution. [@owevertonguedes (Weverton Guedes)](https://github.com/owevertonguedes) [PR #14624](https://github.com/microsoft/vscode-cpptools/pull/14624)
|
||||
* Fix a tag parser crash when a UTF-8 string literal is concatenated with a narrow string literal containing an invalid multibyte sequence.
|
||||
* Fix IntelliSense incorrectly resolving `#include` files through a symbolic link after the target directory was deleted from disk.
|
||||
* Fix potential browse database corruption when the same workspace is opened by multiple processes on Linux and macOS.
|
||||
* Fix crashes when reading files saved in certain multibyte encodings such as GB18030 or EUC-JP.
|
||||
* Fix empty database folders being created in every folder of a multi-root workspace.
|
||||
* Fix the `C_Cpp.refactoring.includeHeader` setting not honoring `always`.
|
||||
* Fix spurious IntelliSense error on `std::variant` brace-initialization.
|
||||
* Fix several potential deadlocks and data races in the language server.
|
||||
* Fix an incorrect file path in an error message on Windows.
|
||||
* Reduce memory usage to help avoid out-of-memory crashes.
|
||||
* Fix stale diagnostics after editing visible headers.
|
||||
* Fix several crashes in the recursive include cache.
|
||||
* Fix an incorrect `#include` casing error on Linux.
|
||||
* Various other fixes found internally.
|
||||
* Various localization updates.
|
||||
* Fix an IntelliSense crash.
|
||||
* Update dependencies.
|
||||
|
||||
## Version 1.32.2: April 28, 2026
|
||||
### New Feature
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"Přiřazení k anachronizmu this není kompatibilní s režimem C++11.",
|
||||
"Došlo k neznámé chybě. Soubor PCH IntelliSense se nevygeneroval.",
|
||||
"Nejméně jednu ze vzdálených cest nejde namapovat na stávající místní cesty. Funkce IntelliSense možná nebude fungovat zcela podle očekávání.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"„static“ je zde nestandardní",
|
||||
"%nd byl dříve deklarován bez explicitního základu výčtu",
|
||||
"Chybějící typename je tady nestandardní.",
|
||||
"Zkrácená syntaxe šablony funkce není standardní pro vodítka dedukce",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"Zkrácená syntaxe šablony funkce není standardní pro vodítka dedukce"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"Die Zuweisung zum this-Anachronismus ist mit dem C++11-Modus nicht kompatibel.",
|
||||
"Unbekannter Fehler. Es wurde keine IntelliSense PCH-Datei generiert.",
|
||||
"Mindestens ein Remotepfad kann vorhandenen lokalen Pfaden nicht zugeordnet werden. Die IntelliSense-Funktionen werden ggf. beeinträchtigt.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"„static“ entspricht hier nicht dem Standard",
|
||||
"%nd wurde zuvor ohne explizite Enumerationsbasis deklariert",
|
||||
"Fehlender „typename“ entspricht hier nicht dem Standard.",
|
||||
"Die abgekürzte Funktionsvorlagensyntax entspricht nicht dem Standard für Deduktionsleitfäden.",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"Die abgekürzte Funktionsvorlagensyntax entspricht nicht dem Standard für Deduktionsleitfäden."
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"la asignación al anacronismo \"this\" no es compatible con el modo C++11",
|
||||
"error desconocido. No se generó un archivo IntelliSense PCH.",
|
||||
"No se pueden asignar una o varias rutas remotas a las rutas locales actuales. La experiencia con IntelliSense puede degradarse.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"\"static\" no es estándar aquí",
|
||||
"%nd se declaró previamente sin una base explícita de enumeración",
|
||||
"falta 'typename' no estándar aquí",
|
||||
"La sintaxis abreviada de las plantillas de funciones no es estándar para las guías de deducción",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"La sintaxis abreviada de las plantillas de funciones no es estándar para las guías de deducción"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"l'assignation à l'anachronisme 'this' n'est pas compatible avec le mode C++11",
|
||||
"une erreur inconnue s'est produite. Aucun fichier PCH IntelliSense n'a été généré.",
|
||||
"Impossible de mapper un ou plusieurs chemins distants à des chemins locaux existants. L'expérience IntelliSense risque d'être dégradée.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"« static » n’est pas standard ici",
|
||||
"%nd a été déclaré précédemment sans base d’énumération explicite",
|
||||
"le mot-clé « typename » manquant n’est pas standard ici",
|
||||
"la syntaxe abrégée du modèle de fonction n’est pas standard pour les guides de déduction",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"la syntaxe abrégée du modèle de fonction n’est pas standard pour les guides de déduction"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"l'assegnazione all'anacronismo 'this' non è compatibile con la modalità C++11",
|
||||
"si è verificato un errore sconosciuto. Non è stato generato alcun file PCH IntelliSense.",
|
||||
"Non è possibile eseguire il mapping di uno o più percorsi remoti a percorsi locali esistenti. L'operazione potrebbe influire negativamente sull'esperienza IntelliSense.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"'static' non è standard qui",
|
||||
"%nd era stato dichiarato in precedenza senza una base di enumerazione esplicita",
|
||||
"manca 'typename' che qui non è standard",
|
||||
"la sintassi abbreviata del modello di funzione non è standard per le guide alla deduzione",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"la sintassi abbreviata del modello di funzione non è standard per le guide alla deduzione"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"'this' への代入 (旧形式) は C++11 モードと互換性がありません",
|
||||
"不明なエラーが発生しました。IntelliSense PCH ファイルは生成されませんでした。",
|
||||
"1 つ以上のリモート パスを既存のローカル パスにマップできません。IntelliSense の機能が低下する可能性があります。",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"'static' はここでは非標準です",
|
||||
"%nd は、明示的な列挙型ベースなしで以前に宣言されました",
|
||||
"見つからない 'typename' はここでは非標準です",
|
||||
"省略形の関数テンプレート構文は、推論ガイドでは非標準です",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"省略形の関数テンプレート構文は、推論ガイドでは非標準です"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"'this'에 대한 할당(오래된 구문)은 C++11 모드와 호환되지 않습니다.",
|
||||
"알 수 없는 오류가 발생했습니다. IntelliSense PCH 파일이 생성되지 않았습니다.",
|
||||
"하나 이상의 원격 경로를 기존 로컬 경로에 매핑할 수 없습니다. IntelliSense 성능이 저하될 수 있습니다.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"여기서 'static'은 표준이 아닙니다.",
|
||||
"%nd은(는) 이전에 명시적 열거형 기반 없이 선언되었습니다.",
|
||||
"여기서 누락된 'typename'이 표준이 아닙니다.",
|
||||
"약식 함수 템플릿 구문은 추론 가이드에 대한 표준이 아닙니다.",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"약식 함수 템플릿 구문은 추론 가이드에 대한 표준이 아닙니다."
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"przypisanie do przestarzałej konstrukcji „this” nie jest zgodne z trybem C++11",
|
||||
"wystąpił nieznany błąd. Nie wygenerowano pliku PCH funkcji IntelliSense.",
|
||||
"Nie można zamapować co najmniej jednej ścieżki zdalnej na istniejące ścieżki lokalne. Może to mieć negatywny wpływ na działanie funkcji IntelliSense.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"„static” jest tutaj niestandardowy",
|
||||
"funkcja %nd została poprzednio zadeklarowana bez jawnej bazy wyliczenia",
|
||||
"brak elementu „typename” jest tutaj niestandardowe",
|
||||
"skrócona składnia szablonu funkcji jest niestandardowa dla przewodników dedukcji",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"skrócona składnia szablonu funkcji jest niestandardowa dla przewodników dedukcji"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"a atribuição ao anacronismo 'this' não é compatível com o modo C++11",
|
||||
"erro desconhecido. Não foi gerado um arquivo PCH do IntelliSense.",
|
||||
"Um ou mais caminhos remotos não podem ser mapeados para os caminhos locais existentes. A experiência do IntelliSense pode ser degradada.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"\"static\" não é padrão aqui",
|
||||
"%nd foi declarado anteriormente sem uma base de enumeração explícita",
|
||||
"\"typename\" ausente não é padrão aqui",
|
||||
"a sintaxe abreviada de template de função é não padrão para guias de dedução",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"a sintaxe abreviada de template de função é não padrão para guias de dedução"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"назначение устаревшему элементу this несовместимо с режимом C++11",
|
||||
"произошла неизвестная ошибка. PCH-файл IntelliSense не был создан.",
|
||||
"Один или несколько удаленных путей не могут быть сопоставлены с существующими локальными путями. Использование IntelliSense может быть ограничено.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"\"static\" является здесь нестандартным",
|
||||
"%nd ранее был объявлен без явной базы перечисления",
|
||||
"отсутствие typename здесь является нестандартным",
|
||||
"сокращенный синтаксис шаблона функции не является стандартным для правил дедукции",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"сокращенный синтаксис шаблона функции не является стандартным для правил дедукции"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"'this' anakronizmine yönelik atama C++11 modu ile uyumlu değil",
|
||||
"bilinmeyen bir hata oluştu. IntelliSense PCH dosyası oluşturulmadı.",
|
||||
"Bir veya daha fazla uzak yol, mevcut yerel yollarla eşlenemiyor. IntelliSense deneyimi bozulabilir.",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"'static' burada standart dışıdır",
|
||||
"%nd daha önce açık bir sabit liste tabanı olmadan tanımlanmıştı",
|
||||
"eksik 'typename' burada standart dışı",
|
||||
"kısaltılmış işlev şablonu sözdizimi çıkarsama kılavuzları için standart değil",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"kısaltılmış işlev şablonu sözdizimi çıkarsama kılavuzları için standart değil"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"对 \"this\" 计时错误的赋值与 C++11 模式不兼容",
|
||||
"出现了未知错误。未生成 IntelliSense PCH 文件。",
|
||||
"一个或多个远程路径无法映射到现有本地路径。IntelliSense 体验可能会降级。",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"此处使用 \"static\" 不符合标准",
|
||||
"之前声明 %nd 时未指定显式枚举基类型",
|
||||
"此处缺少 'typename' 属于非标准用法",
|
||||
"缩写函数模板语法对于推导指南是不标准的",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"缩写函数模板语法对于推导指南是不标准的"
|
||||
]
|
||||
|
||||
@@ -2999,7 +2999,7 @@
|
||||
"'this' 用法已過時,且這種指派與 C++11 模式不相容",
|
||||
"發生未知的錯誤。未產生 IntelliSense PCH 檔案。",
|
||||
"有一或多個遠端路徑無法對應到現有的本機路徑。IntelliSense 的效能可能會變差。",
|
||||
null,
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3747,6 +3747,5 @@
|
||||
"此處使用的 'static' 非標準",
|
||||
"%nd 先前宣告時未明確指定的列舉基底",
|
||||
"此處缺少 'typename' 非標準用法",
|
||||
"簡化函式範本語法在推導指南中並非標準用法",
|
||||
"too many nested user-defined conversions (possible cycle of converting routines)"
|
||||
"簡化函式範本語法在推導指南中並非標準用法"
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "cpptools",
|
||||
"displayName": "C/C++",
|
||||
"description": "C/C++ IntelliSense, debugging, and code browsing.",
|
||||
"version": "1.33.7-main",
|
||||
"version": "1.33.8-main",
|
||||
"publisher": "ms-vscode",
|
||||
"icon": "LanguageCCPP_color_128x.png",
|
||||
"readme": "README.md",
|
||||
|
||||
@@ -16,7 +16,6 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
||||
export class CopilotHoverProvider implements vscode.HoverProvider {
|
||||
private client: DefaultClient;
|
||||
private currentDocument: vscode.TextDocument | undefined;
|
||||
private currentPosition: vscode.Position | undefined;
|
||||
private currentCancellationToken: vscode.CancellationToken | undefined;
|
||||
@@ -30,8 +29,8 @@ export class CopilotHoverProvider implements vscode.HoverProvider {
|
||||
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;
|
||||
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async getCachedChatModel(): Promise<vscode.LanguageModelChat | undefined> {
|
||||
@@ -171,7 +170,6 @@ export class CopilotHoverProvider implements vscode.HoverProvider {
|
||||
position: Position.create(position.line, position.character)
|
||||
};
|
||||
|
||||
await this.client.ready;
|
||||
if (this.currentCancellationToken?.isCancellationRequested) {
|
||||
throw new vscode.CancellationError();
|
||||
}
|
||||
|
||||
@@ -10,11 +10,10 @@ import { RequestCancelled, ServerCancelled } from '../protocolFilter';
|
||||
import { CppSettings } from '../settings';
|
||||
|
||||
export class HoverProvider implements vscode.HoverProvider {
|
||||
private client: DefaultClient;
|
||||
private lastContent: vscode.MarkdownString[] | undefined;
|
||||
private readonly hasContent = new ManualSignal<boolean>(true);
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | undefined> {
|
||||
@@ -36,7 +35,6 @@ export class HoverProvider implements vscode.HoverProvider {
|
||||
textDocument: { uri: document.uri.toString() },
|
||||
position: Position.create(position.line, position.character)
|
||||
};
|
||||
await this.client.ready;
|
||||
let hoverResult: vscode.Hover;
|
||||
try {
|
||||
hoverResult = await this.client.languageClient.sendRequest(HoverRequest, params, token);
|
||||
|
||||
@@ -214,15 +214,11 @@ export async function sendCallHierarchyCallsFromRequest(client: DefaultClient, i
|
||||
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;
|
||||
private client: DefaultClient;
|
||||
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async prepareCallHierarchy(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.CallHierarchyItem | undefined> {
|
||||
await this.client.ready;
|
||||
|
||||
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
|
||||
workspaceReferences.clearViews();
|
||||
|
||||
@@ -261,7 +257,6 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
|
||||
}
|
||||
|
||||
public async provideCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[] | undefined> {
|
||||
await this.client.ready;
|
||||
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
|
||||
|
||||
const CallHierarchyCallsToEvent: string = "CallHierarchyCallsTo";
|
||||
@@ -316,8 +311,6 @@ export class CallHierarchyProvider implements vscode.CallHierarchyProvider {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await this.client.ready;
|
||||
|
||||
const result: vscode.CallHierarchyOutgoingCall[] | undefined =
|
||||
await sendCallHierarchyCallsFromRequest(this.client, item, token);
|
||||
if (token.isCancellationRequested || result === undefined) {
|
||||
|
||||
@@ -40,9 +40,7 @@ export const GetCodeActionsRequest: RequestType<GetCodeActionsRequestParams, Get
|
||||
new RequestType<GetCodeActionsRequestParams, GetCodeActionsResult, void>('cpptools/getCodeActions');
|
||||
|
||||
export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
private client: DefaultClient;
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
private static inlineMacroKind: vscode.CodeActionKind = vscode.CodeActionKind.RefactorInline.append("macro");
|
||||
@@ -51,7 +49,6 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
|
||||
public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range | vscode.Selection,
|
||||
context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise<(vscode.Command | vscode.CodeAction)[]> {
|
||||
await this.client.ready;
|
||||
let r: Range;
|
||||
if (range instanceof vscode.Selection) {
|
||||
if (range.active.isBefore(range.anchor)) {
|
||||
|
||||
@@ -11,9 +11,7 @@ import { CppSettings, OtherSettings } from '../settings';
|
||||
import { makeVscodeTextEdits } from '../utils';
|
||||
|
||||
export class DocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider {
|
||||
private client: DefaultClient;
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
|
||||
@@ -21,7 +19,6 @@ export class DocumentFormattingEditProvider implements vscode.DocumentFormatting
|
||||
if (settings.formattingEngine === "disabled") {
|
||||
return [];
|
||||
}
|
||||
await this.client.ready;
|
||||
const filePath: string = document.uri.fsPath;
|
||||
if (options.onChanges) {
|
||||
let insertSpacesSet: boolean = false;
|
||||
|
||||
@@ -11,9 +11,7 @@ import { CppSettings } from '../settings';
|
||||
import { makeVscodeTextEdits } from '../utils';
|
||||
|
||||
export class DocumentRangeFormattingEditProvider implements vscode.DocumentRangeFormattingEditProvider {
|
||||
private client: DefaultClient;
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range,
|
||||
@@ -22,7 +20,6 @@ export class DocumentRangeFormattingEditProvider implements vscode.DocumentRange
|
||||
if (settings.formattingEngine === "disabled") {
|
||||
return [];
|
||||
}
|
||||
await this.client.ready;
|
||||
const filePath: string = document.uri.fsPath;
|
||||
const useVcFormat: boolean = settings.useVcFormat(document);
|
||||
const configCallBack = async (editorConfigSettings: any | undefined) => {
|
||||
|
||||
@@ -58,14 +58,12 @@ export class DocumentSymbolProvider implements vscode.DocumentSymbolProvider {
|
||||
public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SymbolInformation[] | vscode.DocumentSymbol[]> {
|
||||
const client: Client = clients.getClientFor(document.uri);
|
||||
if (client instanceof DefaultClient) {
|
||||
const defaultClient: DefaultClient = <DefaultClient>client;
|
||||
await client.ready;
|
||||
const params: GetDocumentSymbolRequestParams = {
|
||||
uri: document.uri.toString()
|
||||
};
|
||||
let response: GetDocumentSymbolResult;
|
||||
try {
|
||||
response = await defaultClient.languageClient.sendRequest(GetDocumentSymbolRequest, params, token);
|
||||
response = await client.languageClient.sendRequest(GetDocumentSymbolRequest, params, token);
|
||||
} catch (e: any) {
|
||||
if (e instanceof ResponseError && (e.code === RequestCancelled || e.code === ServerCancelled)) {
|
||||
throw new vscode.CancellationError();
|
||||
|
||||
@@ -56,14 +56,10 @@ export async function sendFindAllReferencesRequest(client: DefaultClient, uri: v
|
||||
}
|
||||
|
||||
export class FindAllReferencesProvider implements vscode.ReferenceProvider {
|
||||
private client: DefaultClient;
|
||||
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideReferences(document: vscode.TextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Promise<vscode.Location[] | undefined> {
|
||||
await this.client.ready;
|
||||
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
|
||||
|
||||
// Listen to a cancellation for this request. When this request is cancelled,
|
||||
|
||||
@@ -14,7 +14,6 @@ interface FoldingRangeRequestInfo {
|
||||
}
|
||||
|
||||
export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
|
||||
private client: DefaultClient;
|
||||
public onDidChangeFoldingRangesEvent = new vscode.EventEmitter<void>();
|
||||
public onDidChangeFoldingRanges?: vscode.Event<void>;
|
||||
|
||||
@@ -22,12 +21,11 @@ export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
|
||||
// for the same file without waiting for the prior request to complete or cancelling them.
|
||||
private pendingRequests: Map<string, FoldingRangeRequestInfo> = new Map<string, FoldingRangeRequestInfo>();
|
||||
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
this.onDidChangeFoldingRanges = this.onDidChangeFoldingRangesEvent.event;
|
||||
}
|
||||
|
||||
async provideFoldingRanges(document: vscode.TextDocument, context: vscode.FoldingContext, token: vscode.CancellationToken): Promise<vscode.FoldingRange[] | undefined> {
|
||||
await this.client.ready;
|
||||
const settings: CppSettings = new CppSettings();
|
||||
if (!settings.codeFolding) {
|
||||
return [];
|
||||
|
||||
@@ -11,9 +11,7 @@ import { CppSettings } from '../settings';
|
||||
import { makeVscodeTextEdits } from '../utils';
|
||||
|
||||
export class OnTypeFormattingEditProvider implements vscode.OnTypeFormattingEditProvider {
|
||||
private client: DefaultClient;
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideOnTypeFormattingEdits(document: vscode.TextDocument, position: vscode.Position, ch: string, options: vscode.FormattingOptions, token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
|
||||
@@ -21,7 +19,6 @@ export class OnTypeFormattingEditProvider implements vscode.OnTypeFormattingEdit
|
||||
if (settings.formattingEngine === "disabled") {
|
||||
return [];
|
||||
}
|
||||
await this.client.ready;
|
||||
const filePath: string = document.uri.fsPath;
|
||||
const useVcFormat: boolean = settings.useVcFormat(document);
|
||||
const configCallBack = async (editorConfigSettings: any | undefined) => {
|
||||
|
||||
@@ -18,14 +18,10 @@ const RenameRequest: RequestType<ReferencesParams, ReferencesResult, void> =
|
||||
new RequestType<ReferencesParams, ReferencesResult, void>('cpptools/rename');
|
||||
|
||||
export class RenameProvider implements vscode.RenameProvider {
|
||||
private client: DefaultClient;
|
||||
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string, _token: vscode.CancellationToken): Promise<vscode.WorkspaceEdit | undefined> {
|
||||
await this.client.ready;
|
||||
workspaceReferences.cancelCurrentReferenceRequest(CancellationSender.NewRequest);
|
||||
|
||||
const settings: CppSettings = new CppSettings();
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { ManualPromise } from '../../Utility/Async/manualPromise';
|
||||
|
||||
interface FileData
|
||||
{
|
||||
interface FileData {
|
||||
version: number;
|
||||
promise: ManualPromise<vscode.SemanticTokens>;
|
||||
tokenBuilder: vscode.SemanticTokensBuilder;
|
||||
|
||||
@@ -10,9 +10,7 @@ import { RequestCancelled, ServerCancelled } from '../protocolFilter';
|
||||
import { makeVscodeLocation } from '../utils';
|
||||
|
||||
export class WorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
|
||||
private client: DefaultClient;
|
||||
constructor(client: DefaultClient) {
|
||||
this.client = client;
|
||||
constructor(private client: DefaultClient) {
|
||||
}
|
||||
|
||||
public async provideWorkspaceSymbols(query: string, token: vscode.CancellationToken): Promise<vscode.SymbolInformation[]> {
|
||||
|
||||
@@ -23,19 +23,16 @@ import { WorkspaceSymbolProvider } from './Providers/workspaceSymbolProvider';
|
||||
// End provider imports
|
||||
|
||||
import { CodeSnippet, Trait } from '@github/copilot-language-server';
|
||||
import { ok } from 'assert';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import { SourceFileConfiguration, SourceFileConfigurationItem, Version, WorkspaceBrowseConfiguration } from 'vscode-cpptools';
|
||||
import { IntelliSenseStatus, Status } from 'vscode-cpptools/out/testApi';
|
||||
import { CloseAction, DidOpenTextDocumentParams, ErrorAction, LanguageClientOptions, NotificationType, Position, Range, RequestType, ResponseError, TextDocumentIdentifier, TextDocumentPositionParams } from 'vscode-languageclient';
|
||||
import { LanguageClient, ServerOptions } from 'vscode-languageclient/node';
|
||||
import { CloseAction, DidOpenTextDocumentParams, ErrorAction, NotificationType, Position, Range, RequestType, ResponseError, TextDocumentIdentifier, TextDocumentPositionParams } from 'vscode-languageclient';
|
||||
import * as rpc from 'vscode-languageclient/node';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { DebugConfigurationProvider } from '../Debugger/configurationProvider';
|
||||
import { ManualPromise } from '../Utility/Async/manualPromise';
|
||||
import { ManualSignal } from '../Utility/Async/manualSignal';
|
||||
import { logAndReturn } from '../Utility/Async/returns';
|
||||
import { is } from '../Utility/System/guards';
|
||||
import * as util from '../common';
|
||||
import { isWindows } from '../constants';
|
||||
import { instrument, isInstrumentationEnabled } from '../instrumentation';
|
||||
@@ -60,6 +57,7 @@ import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderE
|
||||
import { DataBinding } from './dataBinding';
|
||||
import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig';
|
||||
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, isWritingCrashCallStack, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
|
||||
import { LanguageClient } from './languageClient';
|
||||
import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization';
|
||||
import { PersistentFolderState, PersistentState, PersistentWorkspaceState } from './persistentState';
|
||||
import { RequestCancelled, ServerCancelled, createProtocolFilter } from './protocolFilter';
|
||||
@@ -88,7 +86,7 @@ export function hasTrustedCompilerPaths(): boolean {
|
||||
}
|
||||
|
||||
// Data shared by all clients.
|
||||
let languageClient: LanguageClient;
|
||||
const languageClient: LanguageClient = new LanguageClient();
|
||||
let firstClientStarted: Promise<{ wasShutdown: boolean }>;
|
||||
let languageClientHasCrashed: boolean = false;
|
||||
let languageClientCrashedNeedsRestart: boolean = false;
|
||||
@@ -221,11 +219,18 @@ interface FileChangedParams extends WorkspaceFolderParams {
|
||||
uri: string;
|
||||
}
|
||||
|
||||
interface InputRegion {
|
||||
interface InputLineRange {
|
||||
startLine: number;
|
||||
endLine: number;
|
||||
}
|
||||
|
||||
interface InputRegion {
|
||||
startLine: number;
|
||||
startColumn: number;
|
||||
endLine: number;
|
||||
endColumn: number;
|
||||
}
|
||||
|
||||
interface DecorationRangesPair {
|
||||
decoration: vscode.TextEditorDecorationType;
|
||||
ranges: vscode.Range[];
|
||||
@@ -374,7 +379,7 @@ export enum FoldingRangeKind {
|
||||
|
||||
export interface CppFoldingRange {
|
||||
kind: FoldingRangeKind;
|
||||
range: InputRegion;
|
||||
range: InputLineRange;
|
||||
}
|
||||
|
||||
export interface GetFoldingRangesResult {
|
||||
@@ -781,7 +786,6 @@ class ClientModel {
|
||||
|
||||
export interface Client {
|
||||
readonly ready: Promise<void>;
|
||||
enqueue<T>(task: () => Promise<T>): Promise<T>;
|
||||
InitializingWorkspaceChanged: vscode.Event<boolean>;
|
||||
IndexingWorkspaceChanged: vscode.Event<boolean>;
|
||||
ParsingWorkspaceChanged: vscode.Event<boolean>;
|
||||
@@ -893,7 +897,6 @@ export function createNullClient(): Client {
|
||||
}
|
||||
|
||||
export class DefaultClient implements Client {
|
||||
private innerLanguageClient?: LanguageClient; // The "client" that launches and communicates with our language "server" process.
|
||||
private disposables: vscode.Disposable[] = [];
|
||||
private documentFormattingProviderDisposable: vscode.Disposable | undefined;
|
||||
private formattingRangeProviderDisposable: vscode.Disposable | undefined;
|
||||
@@ -909,7 +912,6 @@ export class DefaultClient implements Client {
|
||||
private rootRealPath: string;
|
||||
private workspaceStoragePath: string;
|
||||
private trackedDocuments = new Map<string, vscode.TextDocument>();
|
||||
private isSupported: boolean = true;
|
||||
private inactiveRegionsDecorations = new Map<string, DecorationRangesPair>();
|
||||
private settingsTracker: SettingsTracker;
|
||||
private loggingLevel: number = 1;
|
||||
@@ -934,20 +936,6 @@ export class DefaultClient implements Client {
|
||||
private showConfigureIntelliSenseButton: boolean = false;
|
||||
private pendingTagParsingCalls: PendingTagParsingCall[] = [];
|
||||
|
||||
/** 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>]>();
|
||||
|
||||
/** returns a promise that waits initialization and/or a change to configuration to complete (i.e. language client is ready-to-use) */
|
||||
private static readonly isStarted = new ManualSignal<void>(true);
|
||||
|
||||
/**
|
||||
* Indicates if the blocking task dispatcher is currently running
|
||||
*
|
||||
* This will be in the Set state when the dispatcher is not running (i.e. if you await this it will be resolved immediately)
|
||||
* If the dispatcher is running, this will be in the Reset state (i.e. if you await this it will be resolved when the dispatcher is done)
|
||||
*/
|
||||
private static readonly dispatching = new ManualSignal<void>();
|
||||
|
||||
// The "model" that is displayed via the UI (status bar).
|
||||
private model: ClientModel = new ClientModel();
|
||||
|
||||
@@ -964,7 +952,7 @@ export class DefaultClient implements Client {
|
||||
public get ReferencesCommandModeChanged(): vscode.Event<refs.ReferencesCommandMode> { return this.model.referencesCommandMode.ValueChanged; }
|
||||
public get TagParserStatusChanged(): vscode.Event<string> { return this.model.parsingWorkspaceStatus.ValueChanged; }
|
||||
public get ActiveConfigChanged(): vscode.Event<string> { return this.model.activeConfigName.ValueChanged; }
|
||||
public isInitialized(): boolean { return this.innerLanguageClient !== undefined; }
|
||||
public isInitialized(): boolean { return this.languageClient.isInitialized; }
|
||||
public getShowConfigureIntelliSenseButton(): boolean { return this.showConfigureIntelliSenseButton; }
|
||||
public setShowConfigureIntelliSenseButton(show: boolean): void { this.showConfigureIntelliSenseButton = show; }
|
||||
|
||||
@@ -999,10 +987,7 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public get languageClient(): LanguageClient {
|
||||
if (!this.innerLanguageClient) {
|
||||
throw new Error("Attempting to use languageClient before initialized");
|
||||
}
|
||||
return this.innerLanguageClient;
|
||||
return languageClient;
|
||||
}
|
||||
|
||||
public get configuration(): configs.CppProperties {
|
||||
@@ -1376,19 +1361,18 @@ export class DefaultClient implements Client {
|
||||
if (firstClientStarted === undefined || languageClientCrashedNeedsRestart) {
|
||||
if (languageClientCrashedNeedsRestart) {
|
||||
languageClientCrashedNeedsRestart = false;
|
||||
// if we're recovering, the isStarted needs to be reset.
|
||||
// if we're recovering, the isStarted needs to be reset
|
||||
// because we're starting the first client again.
|
||||
DefaultClient.isStarted.reset();
|
||||
this.languageClient.isStarted = false;
|
||||
this.languageClient.setLanguageClient(undefined);
|
||||
}
|
||||
firstClientStarted = this.createLanguageClient();
|
||||
util.setProgress(util.getProgressExecutableStarted());
|
||||
isFirstClient = true;
|
||||
}
|
||||
void this.init(rootUri, isFirstClient).catch(logAndReturn.undefined);
|
||||
|
||||
} catch (errJS) {
|
||||
const err: NodeJS.ErrnoException = errJS as NodeJS.ErrnoException;
|
||||
this.isSupported = false; // Running on an OS we don't support yet.
|
||||
if (!failureMessageShown) {
|
||||
failureMessageShown = true;
|
||||
let additionalInfo: string;
|
||||
@@ -1408,8 +1392,7 @@ export class DefaultClient implements Client {
|
||||
ui = getUI();
|
||||
ui.bind(this);
|
||||
if ((await firstClientStarted).wasShutdown) {
|
||||
this.isSupported = false;
|
||||
DefaultClient.isStarted.resolve();
|
||||
this.languageClient.isStarted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1421,7 +1404,10 @@ export class DefaultClient implements Client {
|
||||
this.innerConfiguration.CompileCommandsChanged((e) => this.onCompileCommandsChanged(e));
|
||||
this.disposables.push(this.innerConfiguration);
|
||||
|
||||
this.innerLanguageClient = languageClient;
|
||||
// Ideally this would be set earlier, but the task provider expects it to also mean that `this.innerConfiguration` is set.
|
||||
this.languageClient.isStarted = true;
|
||||
compilerDefaults = await this.requestCompiler();
|
||||
|
||||
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", this.settingsTracker.getUserModifiedSettings());
|
||||
failureMessageShown = false;
|
||||
|
||||
@@ -1488,7 +1474,6 @@ export class DefaultClient implements Client {
|
||||
});
|
||||
// The configurations will not be sent to the language server until the default include paths and frameworks have been set.
|
||||
// The event handlers must be set before this happens.
|
||||
compilerDefaults = await this.requestCompiler();
|
||||
DefaultClient.updateClientConfigurations();
|
||||
clients.forEach(client => {
|
||||
if (client instanceof DefaultClient) {
|
||||
@@ -1498,14 +1483,11 @@ export class DefaultClient implements Client {
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
this.isSupported = false; // Running on an OS we don't support yet.
|
||||
if (!failureMessageShown) {
|
||||
failureMessageShown = true;
|
||||
void vscode.window.showErrorMessage(localize("unable.to.start", "Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: {0}", String(err)));
|
||||
}
|
||||
}
|
||||
|
||||
DefaultClient.isStarted.resolve();
|
||||
}
|
||||
|
||||
private getWorkspaceFolderSettings(workspaceFolderUri: vscode.Uri | undefined, workspaceFolder: vscode.WorkspaceFolder | undefined, settings: CppSettings, otherSettings: OtherSettings): WorkspaceFolderSettingsParams {
|
||||
@@ -1693,7 +1675,7 @@ export class DefaultClient implements Client {
|
||||
// from a sanitizer build to files in that directory (see getSanitizerServerEnv). This is
|
||||
// undefined -- i.e. the environment is inherited unchanged -- for normal builds.
|
||||
const sanitizerServerEnv: NodeJS.ProcessEnv | undefined = getSanitizerServerEnv();
|
||||
const serverOptions: ServerOptions = {
|
||||
const serverOptions: rpc.ServerOptions = {
|
||||
run: { command: serverModule, options: { detached: false, cwd: util.getExtensionFilePath("bin"), env: sanitizerServerEnv } },
|
||||
debug: { command: serverModule, args: [serverName], options: { detached: true, cwd: util.getExtensionFilePath("bin"), env: sanitizerServerEnv } }
|
||||
};
|
||||
@@ -1756,7 +1738,7 @@ export class DefaultClient implements Client {
|
||||
loggingLevel: this.loggingLevel
|
||||
};
|
||||
|
||||
const clientOptions: LanguageClientOptions = {
|
||||
const clientOptions: rpc.LanguageClientOptions = {
|
||||
documentSelector: [
|
||||
{ scheme: 'file', language: 'c' },
|
||||
{ scheme: 'file', language: 'cpp' },
|
||||
@@ -1836,34 +1818,40 @@ export class DefaultClient implements Client {
|
||||
// Refresh initializing state in UI.
|
||||
this.model.isInitializingWorkspace.Value = true;
|
||||
|
||||
// Create the language client
|
||||
languageClient = new LanguageClient(`cpptools`, serverOptions, clientOptions);
|
||||
languageClient.onNotification(DebugProtocolNotification, logDebugProtocol);
|
||||
languageClient.onNotification(DebugLogNotification, logLocalized);
|
||||
languageClient.onNotification(LogTelemetryNotification, (e) => void this.logTelemetry(e));
|
||||
languageClient.onNotification(ShowMessageWindowNotification, showMessageWindow);
|
||||
languageClient.registerProposedFeatures();
|
||||
await languageClient.start();
|
||||
// Create the language client that spawns cpptools and configures RPC over stdin/stdout.
|
||||
// This is the ONLY place outside of the LanguageClient wrapper where the VS Code LanguageClient class should be used directly.
|
||||
// All other code should use the LanguageClient wrapper class.
|
||||
const client = new rpc.LanguageClient(`cpptools`, serverOptions, clientOptions);
|
||||
client.onNotification(DebugProtocolNotification, logDebugProtocol);
|
||||
client.onNotification(DebugLogNotification, logLocalized);
|
||||
client.onNotification(LogTelemetryNotification, (e) => void this.logTelemetry(e));
|
||||
client.onNotification(ShowMessageWindowNotification, showMessageWindow);
|
||||
client.registerProposedFeatures();
|
||||
await client.start();
|
||||
|
||||
if (usesCrashHandler()) {
|
||||
watchForCrashes(await languageClient.sendRequest(PreInitializationRequest, null));
|
||||
watchForCrashes(await client.sendRequest(PreInitializationRequest, null));
|
||||
} else if (os.platform() === "win32") {
|
||||
const settings: CppSettings = new CppSettings();
|
||||
if ((settings.windowsErrorReportingMode === "default" && !languageClientHasCrashed) ||
|
||||
settings.windowsErrorReportingMode === "enabled") {
|
||||
await languageClient.sendRequest(PreInitializationRequest, null);
|
||||
await client.sendRequest(PreInitializationRequest, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Move initialization to a separate message, so we can see log output from it.
|
||||
// A request is used in order to wait for completion and ensure that no subsequent
|
||||
// higher priority message may be processed before the Initialization request.
|
||||
const initializeResult = await languageClient.sendRequest(InitializationRequest, cppInitializationParams);
|
||||
const initializeResult = await client.sendRequest(InitializationRequest, cppInitializationParams);
|
||||
|
||||
// If the server requested shutdown, then reload with the failsafe (null) client.
|
||||
if (initializeResult.shouldShutdown) {
|
||||
await languageClient.stop();
|
||||
await client.stop();
|
||||
await clients.recreateClients(true);
|
||||
} else {
|
||||
// Don't set the inner language client on the wrapper until after initialization is complete.
|
||||
// This ensures the order of the initialization messages.
|
||||
languageClient.setLanguageClient(client);
|
||||
}
|
||||
|
||||
return { wasShutdown: initializeResult.shouldShutdown };
|
||||
@@ -1871,7 +1859,6 @@ export class DefaultClient implements Client {
|
||||
|
||||
public async sendDidChangeSettings(): Promise<void> {
|
||||
// Send settings json to native side.
|
||||
await this.ready;
|
||||
await this.languageClient.sendNotification(DidChangeSettingsNotification, this.getAllSettings());
|
||||
}
|
||||
|
||||
@@ -2211,7 +2198,6 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public async logDiagnostics(): Promise<void> {
|
||||
await this.ready;
|
||||
const response: GetDiagnosticsResult = await this.languageClient.sendRequest(GetDiagnosticsRequest, null);
|
||||
const diagnosticsChannel: vscode.OutputChannel = getDiagnosticsChannel();
|
||||
diagnosticsChannel.clear();
|
||||
@@ -2279,16 +2265,12 @@ export class DefaultClient implements Client {
|
||||
diagnosticsChannel.show(false);
|
||||
}
|
||||
|
||||
public async rescanFolder(): Promise<void> {
|
||||
await this.ready;
|
||||
public rescanFolder(): Promise<void> {
|
||||
return this.languageClient.sendNotification(RescanFolderNotification);
|
||||
}
|
||||
|
||||
public async provideCustomConfigurations(docUris: vscode.Uri[], batchId: number): Promise<void> {
|
||||
let isProviderRegistered: boolean = false;
|
||||
const onFinished: () => void = () => {
|
||||
void this.languageClient.sendNotification(FinishedRequestCustomConfig, { batchId, isProviderRegistered });
|
||||
};
|
||||
try {
|
||||
const providerId: string | undefined = this.configurationProvider;
|
||||
if (!providerId) {
|
||||
@@ -2302,7 +2284,7 @@ export class DefaultClient implements Client {
|
||||
const resultCode = await this.provideCustomConfigurationAsync(docUris, provider);
|
||||
telemetry.logLanguageServerEvent('provideCustomConfigurations', { providerId, resultCode });
|
||||
} finally {
|
||||
onFinished();
|
||||
void this.languageClient.sendNotification(FinishedRequestCustomConfig, { batchId, isProviderRegistered });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2522,9 +2504,8 @@ export class DefaultClient implements Client {
|
||||
* the UI results and always re-requests (no caching).
|
||||
*/
|
||||
|
||||
public async getIncludes(uri: vscode.Uri, maxDepth: number): Promise<GetIncludesResult> {
|
||||
public getIncludes(uri: vscode.Uri, maxDepth: number): Promise<GetIncludesResult> {
|
||||
const params: GetIncludesParams = { fileUri: uri.toString(), maxDepth };
|
||||
await this.ready;
|
||||
return this.languageClient.sendRequest(IncludesRequest, params);
|
||||
}
|
||||
|
||||
@@ -2545,82 +2526,11 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
/**
|
||||
* a Promise that can be awaited to know when it's ok to proceed.
|
||||
*
|
||||
* This is a lighter-weight complement to `enqueue()`
|
||||
*
|
||||
* Use `await <client>.ready` when you need to ensure that the client is initialized, and to run in order
|
||||
* Use `enqueue()` when you want to ensure that subsequent calls are blocked until a critical bit of code is run.
|
||||
*
|
||||
* This is lightweight, because if the queue is empty, then the only thing to wait for is the client itself to be initialized
|
||||
* A Promise that can be awaited to know when the language client (cpptools) is up and running.
|
||||
* It also implies that `this.innerConfiguration` is set.
|
||||
*/
|
||||
get ready(): Promise<void> {
|
||||
if (!DefaultClient.dispatching.isCompleted || DefaultClient.queue.length) {
|
||||
// if the dispatcher has stuff going on, then we need to stick in a promise into the queue so we can
|
||||
// be notified when it's our turn
|
||||
const p = new ManualPromise<void>();
|
||||
DefaultClient.queue.push([p as ManualPromise<unknown>]);
|
||||
return p;
|
||||
}
|
||||
|
||||
// otherwise, we're only waiting for the client to be in an initialized state, in which case just wait for that.
|
||||
return DefaultClient.isStarted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue a task to ensure that the order is maintained. The tasks are executed sequentially after the client is ready.
|
||||
*
|
||||
* this is a bit more expensive than `.ready` - this ensures the task is absolutely finished executing before allowing
|
||||
* the dispatcher to move forward.
|
||||
*
|
||||
* Use `enqueue()` when you want to ensure that subsequent calls are blocked until a critical bit of code is run.
|
||||
* Use `await <client>.ready` when you need to ensure that the client is initialized, and still run in order.
|
||||
*/
|
||||
enqueue<T>(task: () => Promise<T>) {
|
||||
ok(this.isSupported, localize("unsupported.client", "Unsupported client"));
|
||||
|
||||
// create a placeholder promise that is resolved when the task is complete.
|
||||
const result = new ManualPromise<unknown>();
|
||||
|
||||
// add the task to the queue
|
||||
DefaultClient.queue.push([result, task]);
|
||||
|
||||
// if we're not already dispatching, start
|
||||
if (DefaultClient.dispatching.isSet) {
|
||||
// start dispatching
|
||||
void DefaultClient.dispatch();
|
||||
}
|
||||
|
||||
// return the placeholder promise to the caller.
|
||||
return result as Promise<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The dispatch loop asynchronously processes items in the async queue in order, and ensures that tasks are dispatched in the
|
||||
* order they were inserted.
|
||||
*/
|
||||
private static async dispatch() {
|
||||
// reset the promise for the dispatcher
|
||||
DefaultClient.dispatching.reset();
|
||||
|
||||
do {
|
||||
// ensure that this is OK to start working
|
||||
await this.isStarted;
|
||||
|
||||
// pick items up off the queue and run then one at a time until the queue is empty
|
||||
const [promise, task] = DefaultClient.queue.shift() ?? [];
|
||||
if (is.promise(promise)) {
|
||||
try {
|
||||
promise.resolve(task ? await task() : undefined);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
promise.reject(e);
|
||||
}
|
||||
}
|
||||
} while (DefaultClient.queue.length);
|
||||
|
||||
// unblock anything that is waiting for the dispatcher to empty
|
||||
this.dispatching.resolve();
|
||||
return this.languageClient.ready;
|
||||
}
|
||||
|
||||
private static async withLspCancellationHandling<T>(task: () => Promise<T>, token: vscode.CancellationToken): Promise<T> {
|
||||
@@ -2672,7 +2582,7 @@ export class DefaultClient implements Client {
|
||||
* listen for notifications from the language server.
|
||||
*/
|
||||
private registerNotifications(): void {
|
||||
console.assert(this.languageClient !== undefined, "This method must not be called until this.languageClient is set in \"onReady\"");
|
||||
console.assert(this.languageClient.isInitialized, "This method must not be called until the language client is initialized.");
|
||||
|
||||
this.languageClient.onNotification(ReloadWindowNotification, () => void util.promptForReloadWindowDueToSettingsChange());
|
||||
this.languageClient.onNotification(UpdateTrustedCompilersNotification, (e) => void this.addTrustedCompiler(e.compilerPath));
|
||||
@@ -2781,7 +2691,7 @@ export class DefaultClient implements Client {
|
||||
* listen for file created/deleted events under the ${workspaceFolder} folder
|
||||
*/
|
||||
private registerFileWatcher(): void {
|
||||
console.assert(this.languageClient !== undefined, "This method must not be called until this.languageClient is set in \"onReady\"");
|
||||
console.assert(this.languageClient.isInitialized, "This method must not be called until the language client is initialized.");
|
||||
|
||||
if (this.rootFolder) {
|
||||
// WARNING: The default limit on Linux is 8k, so for big directories, this can cause file watching to fail.
|
||||
@@ -3054,7 +2964,8 @@ export class DefaultClient implements Client {
|
||||
this.inactiveRegionsDecorations.set(uriString, currentSet);
|
||||
}
|
||||
|
||||
Array.prototype.push.apply(currentSet.ranges, inactiveRegions.map(element => new vscode.Range(element.startLine, 0, element.endLine, 0)));
|
||||
Array.prototype.push.apply(currentSet.ranges, inactiveRegions.map(element =>
|
||||
new vscode.Range(element.startLine, element.startColumn, element.endLine, element.endColumn)));
|
||||
|
||||
// Apply the decorations to all *visible* text editors
|
||||
const editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === uriString);
|
||||
@@ -3142,7 +3053,6 @@ export class DefaultClient implements Client {
|
||||
switchHeaderSourceFileName: fileName,
|
||||
workspaceFolderUri: rootUri.toString()
|
||||
};
|
||||
return this.enqueue(async () => {
|
||||
// Don't use withLspCancellationHandling() or withCancellation() here. If the switch target is already known,
|
||||
// the caller should still be able to use it even if the progress notification was just cancelled.
|
||||
try {
|
||||
@@ -3153,7 +3063,6 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async requestCompiler(newCompilerPath?: string): Promise<configs.CompilerDefaults> {
|
||||
@@ -3233,7 +3142,6 @@ export class DefaultClient implements Client {
|
||||
* send notifications to the language server to restart IntelliSense for the selected file.
|
||||
*/
|
||||
public async restartIntelliSenseForFile(document: vscode.TextDocument): Promise<void> {
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(RestartIntelliSenseForFileNotification, this.languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document)).catch(logAndReturn.undefined);
|
||||
}
|
||||
|
||||
@@ -3250,7 +3158,6 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public async resetDatabase(): Promise<void> {
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(ResetDatabaseNotification);
|
||||
}
|
||||
|
||||
@@ -3262,29 +3169,24 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public async pauseParsing(): Promise<void> {
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(PauseParsingNotification);
|
||||
}
|
||||
|
||||
public async resumeParsing(): Promise<void> {
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(ResumeParsingNotification);
|
||||
}
|
||||
|
||||
public async PauseCodeAnalysis(): Promise<void> {
|
||||
await this.ready;
|
||||
this.model.isCodeAnalysisPaused.Value = true;
|
||||
return this.languageClient.sendNotification(PauseCodeAnalysisNotification);
|
||||
}
|
||||
|
||||
public async ResumeCodeAnalysis(): Promise<void> {
|
||||
await this.ready;
|
||||
this.model.isCodeAnalysisPaused.Value = false;
|
||||
return this.languageClient.sendNotification(ResumeCodeAnalysisNotification);
|
||||
}
|
||||
|
||||
public async CancelCodeAnalysis(): Promise<void> {
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(CancelCodeAnalysisNotification);
|
||||
}
|
||||
|
||||
@@ -3419,7 +3321,6 @@ export class DefaultClient implements Client {
|
||||
currentConfiguration: index,
|
||||
workspaceFolderUri: this.RootUri?.toString()
|
||||
};
|
||||
await this.ready;
|
||||
await this.languageClient.sendNotification(ChangeSelectedSettingNotification, params);
|
||||
|
||||
let configName: string = "";
|
||||
@@ -3435,7 +3336,6 @@ export class DefaultClient implements Client {
|
||||
uri: vscode.Uri.file(path).toString(),
|
||||
workspaceFolderUri: this.RootUri?.toString()
|
||||
};
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(ChangeCompileCommandsNotification, params);
|
||||
}
|
||||
|
||||
@@ -3621,7 +3521,6 @@ export class DefaultClient implements Client {
|
||||
const params: WorkspaceFolderParams = {
|
||||
workspaceFolderUri: this.RootUri?.toString()
|
||||
};
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(ClearCustomConfigurationsNotification, params);
|
||||
}
|
||||
|
||||
@@ -3630,7 +3529,6 @@ export class DefaultClient implements Client {
|
||||
const params: WorkspaceFolderParams = {
|
||||
workspaceFolderUri: this.RootUri?.toString()
|
||||
};
|
||||
await this.ready;
|
||||
return this.languageClient.sendNotification(ClearCustomBrowseConfigurationNotification, params);
|
||||
}
|
||||
|
||||
@@ -3717,7 +3615,6 @@ export class DefaultClient implements Client {
|
||||
position: editor.selection.active,
|
||||
next: next
|
||||
};
|
||||
await this.ready;
|
||||
const response: Position | undefined = await this.languageClient.sendRequest(GoToDirectiveInGroupRequest, params);
|
||||
if (response) {
|
||||
const p: vscode.Position = new vscode.Position(response.line, response.character);
|
||||
@@ -3750,7 +3647,6 @@ export class DefaultClient implements Client {
|
||||
isCodeAction: codeActionArguments !== undefined,
|
||||
isCursorAboveSignatureLine: codeActionArguments?.isCursorAboveSignatureLine
|
||||
};
|
||||
await this.ready;
|
||||
const currentFileVersion: number | undefined = openFileVersions.get(params.uri);
|
||||
if (currentFileVersion === undefined) {
|
||||
return;
|
||||
@@ -3796,23 +3692,19 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
}
|
||||
|
||||
public async handleRunCodeAnalysisOnActiveFile(): Promise<void> {
|
||||
await this.ready;
|
||||
public handleRunCodeAnalysisOnActiveFile(): Promise<void> {
|
||||
return this.languageClient.sendNotification(CodeAnalysisNotification, { scope: CodeAnalysisScope.ActiveFile });
|
||||
}
|
||||
|
||||
public async handleRunCodeAnalysisOnOpenFiles(): Promise<void> {
|
||||
await this.ready;
|
||||
public handleRunCodeAnalysisOnOpenFiles(): Promise<void> {
|
||||
return this.languageClient.sendNotification(CodeAnalysisNotification, { scope: CodeAnalysisScope.OpenFiles });
|
||||
}
|
||||
|
||||
public async handleRunCodeAnalysisOnAllFiles(): Promise<void> {
|
||||
await this.ready;
|
||||
public handleRunCodeAnalysisOnAllFiles(): Promise<void> {
|
||||
return this.languageClient.sendNotification(CodeAnalysisNotification, { scope: CodeAnalysisScope.AllFiles });
|
||||
}
|
||||
|
||||
public async handleRemoveAllCodeAnalysisProblems(): Promise<void> {
|
||||
await this.ready;
|
||||
if (removeAllCodeAnalysisProblems()) {
|
||||
return this.languageClient.sendNotification(CodeAnalysisNotification, { scope: CodeAnalysisScope.ClearSquiggles });
|
||||
}
|
||||
@@ -3843,8 +3735,6 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public async handleRemoveCodeAnalysisProblems(refreshSquigglesOnSave: boolean, identifiersAndUris: CodeAnalysisDiagnosticIdentifiersAndUri[]): Promise<void> {
|
||||
await this.ready;
|
||||
|
||||
// A deep copy is needed because the call to identifiers.splice below can
|
||||
// remove elements in identifiersAndUris[...].identifiers.
|
||||
const identifiersAndUrisCopy: CodeAnalysisDiagnosticIdentifiersAndUri[] = [];
|
||||
@@ -4324,9 +4214,8 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public onInterval(): void {
|
||||
// These events can be discarded until the language client is ready.
|
||||
// Don't queue them up with this.notifyWhenLanguageClientReady calls.
|
||||
if (this.innerLanguageClient !== undefined && this.configuration !== undefined) {
|
||||
// These events can be discarded until the language client is ready. Don't queue them up.
|
||||
if (this.languageClient.isInitialized && this.configuration !== undefined) {
|
||||
void this.languageClient.sendNotification(IntervalTimerNotification).catch(logAndReturn.undefined);
|
||||
this.configuration.checkCppProperties();
|
||||
this.configuration.checkCompileCommands();
|
||||
@@ -4372,8 +4261,6 @@ export class DefaultClient implements Client {
|
||||
}
|
||||
|
||||
public async handleReferencesIcon(): Promise<void> {
|
||||
await this.ready;
|
||||
|
||||
workspaceReferences.UpdateProgressUICounter(this.model.referencesCommandMode.Value);
|
||||
|
||||
// If the search is find all references, preview partial results.
|
||||
@@ -4507,9 +4394,6 @@ class NullClient implements Client {
|
||||
|
||||
readonly ready: Promise<void> = Promise.resolve();
|
||||
|
||||
async enqueue<T>(task: () => Promise<T>) {
|
||||
return task();
|
||||
}
|
||||
public get InitializingWorkspaceChanged(): vscode.Event<boolean> { return this.booleanEvent.event; }
|
||||
public get IndexingWorkspaceChanged(): vscode.Event<boolean> { return this.booleanEvent.event; }
|
||||
public get ParsingWorkspaceChanged(): vscode.Event<boolean> { return this.booleanEvent.event; }
|
||||
|
||||
@@ -121,7 +121,6 @@ export class ClientCollection {
|
||||
const client: cpptools.Client = pair[1];
|
||||
|
||||
const newClient: cpptools.Client = this.createClient(client.RootFolder, true);
|
||||
await newClient.ready;
|
||||
for (const document of client.TrackedDocuments.values()) {
|
||||
this.transferOwnership(document, client);
|
||||
await newClient.sendDidOpen(document);
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
import * as vscode from 'vscode';
|
||||
import { LanguageClient, NotificationType, Range } from 'vscode-languageclient/node';
|
||||
import { NotificationType, Range } from 'vscode-languageclient';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Location, WorkspaceEdit } from './commonTypes';
|
||||
import { CppSourceStr } from './extension';
|
||||
import { LanguageClient } from './languageClient';
|
||||
import { LocalizeStringParams, getLocalizedString } from './localization';
|
||||
import { CppSettings } from './settings';
|
||||
import { makeVscodeLocation, makeVscodeRange, makeVscodeTextEdits, rangeEquals } from './utils';
|
||||
|
||||
@@ -14,6 +14,7 @@ import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as which from 'which';
|
||||
import { logAndReturn, returns } from '../Utility/Async/returns';
|
||||
import { escapePathForSquiggles } from '../Utility/Text/escape';
|
||||
import * as util from '../common';
|
||||
import { isWindows } from '../constants';
|
||||
import { getOutputChannelLogger } from '../logger';
|
||||
@@ -135,7 +136,7 @@ export interface CompilerDefaults {
|
||||
trustedCompilerFound: boolean;
|
||||
}
|
||||
|
||||
export class CppProperties {
|
||||
export class CppProperties implements vscode.Disposable {
|
||||
private client: DefaultClient;
|
||||
private rootUri: vscode.Uri | undefined;
|
||||
private propertiesFile: vscode.Uri | undefined | null = undefined; // undefined and null values are handled differently
|
||||
@@ -2119,10 +2120,8 @@ export class CppProperties {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Escape the path string for literal use in a regular expression
|
||||
// Need to escape any quotes to match the original text
|
||||
let escapedPath: string = curPath.replace(/"/g, '\\"');
|
||||
escapedPath = escapedPath.replace(/[-\"\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
// Escape the parsed path for a literal regex match against its JSON spelling.
|
||||
const escapedPath: string = escapePathForSquiggles(curPath);
|
||||
|
||||
// Create a pattern to search for the path with either a quote or semicolon immediately before and after,
|
||||
// and extend that pattern to the next quote before and next quote after it.
|
||||
|
||||
@@ -185,11 +185,11 @@ export async function activate(): Promise<void> {
|
||||
disposables.push(vscode.workspace.onDidOpenTextDocument(onDidOpenTextDocument));
|
||||
|
||||
disposables.push(vscode.workspace.onDidChangeConfiguration(onDidChangeSettings));
|
||||
disposables.push(vscode.window.onDidChangeTextEditorVisibleRanges((e) => clients.ActiveClient.enqueue(async () => onDidChangeTextEditorVisibleRanges(e))));
|
||||
disposables.push(vscode.window.onDidChangeActiveTextEditor((e) => clients.ActiveClient.enqueue(async () => onDidChangeActiveTextEditor(e))));
|
||||
disposables.push(vscode.window.onDidChangeTextEditorVisibleRanges(e => onDidChangeTextEditorVisibleRanges(e)));
|
||||
disposables.push(vscode.window.onDidChangeActiveTextEditor(e => onDidChangeActiveTextEditor(e)));
|
||||
ui.didChangeActiveEditor(); // Handle already active documents (for non-cpp files that we don't register didOpen).
|
||||
disposables.push(vscode.window.onDidChangeTextEditorSelection((e) => clients.ActiveClient.enqueue(async () => onDidChangeTextEditorSelection(e))));
|
||||
disposables.push(vscode.window.onDidChangeVisibleTextEditors((e) => clients.ActiveClient.enqueue(async () => onDidChangeVisibleTextEditors(e))));
|
||||
disposables.push(vscode.window.onDidChangeTextEditorSelection(e => onDidChangeTextEditorSelection(e)));
|
||||
disposables.push(vscode.window.onDidChangeVisibleTextEditors(e => onDidChangeVisibleTextEditors(e)));
|
||||
updateLanguageConfigurations();
|
||||
|
||||
reportMacCrashes();
|
||||
@@ -565,12 +565,10 @@ async function selectClient(): Promise<Client> {
|
||||
}
|
||||
|
||||
async function onResetDatabase(): Promise<void> {
|
||||
await clients.ActiveClient.ready;
|
||||
return clients.ActiveClient.resetDatabase();
|
||||
}
|
||||
|
||||
async function onRescanCompilers(sender?: any): Promise<void> {
|
||||
await clients.ActiveClient.ready;
|
||||
return clients.ActiveClient.rescanCompilers(sender);
|
||||
}
|
||||
|
||||
@@ -579,7 +577,6 @@ async function onAddMissingInclude(): Promise<void> {
|
||||
}
|
||||
|
||||
async function selectIntelliSenseConfiguration(sender?: any): Promise<void> {
|
||||
await clients.ActiveClient.ready;
|
||||
return clients.ActiveClient.promptSelectIntelliSenseConfiguration(sender);
|
||||
}
|
||||
|
||||
@@ -877,7 +874,6 @@ async function onFindAllReferences(uri: vscode.Uri, position: vscode.Position, t
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await client.ready;
|
||||
const result = await sendFindAllReferencesRequest(client, uri, position, token ?? CancellationToken.None);
|
||||
return result?.locations;
|
||||
}
|
||||
@@ -892,7 +888,6 @@ async function onGoToDefinition(uri: vscode.Uri, position: vscode.Position, toke
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await client.ready;
|
||||
return sendGoToDefinitionRequest(client, uri, position, token ?? CancellationToken.None);
|
||||
}
|
||||
|
||||
@@ -906,7 +901,6 @@ async function onPrepareCallHierarchy(uri: vscode.Uri, position: vscode.Position
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await client.ready;
|
||||
return sendPrepareCallHierarchyRequest(client, uri, position, token ?? CancellationToken.None);
|
||||
}
|
||||
|
||||
@@ -920,7 +914,6 @@ async function onCallHierarchyCallsTo(item: vscode.CallHierarchyItem, token?: vs
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await client.ready;
|
||||
return sendCallHierarchyCallsToRequest(client, item, token ?? CancellationToken.None);
|
||||
}
|
||||
|
||||
@@ -934,7 +927,6 @@ async function onCallHierarchyCallsFrom(item: vscode.CallHierarchyItem, token?:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await client.ready;
|
||||
return sendCallHierarchyCallsFromRequest(client, item, token ?? CancellationToken.None);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
* See 'LICENSE' in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vscode';
|
||||
import { CancellationToken, NotificationHandler, NotificationType, RequestType } from 'vscode-languageclient';
|
||||
import * as rpc from 'vscode-languageclient/node';
|
||||
import { ManualSignal } from '../Utility/Async/manualSignal';
|
||||
|
||||
export class LanguageClient {
|
||||
private _rpcClient?: rpc.LanguageClient;
|
||||
private readonly _started = new ManualSignal<void>(true);
|
||||
|
||||
/**
|
||||
* Returns a promise that waits for the RPC connection to be ready.
|
||||
*/
|
||||
public get ready(): Promise<void> {
|
||||
return this._started;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initialization state of the underlying RPC client.
|
||||
* This is used to indicate that the underlying RPC client has been initialized and is ready to send requests.
|
||||
* If resetting the RPC client, set this to false.
|
||||
*/
|
||||
public set isStarted(value: boolean) {
|
||||
if (value) {
|
||||
this._started.resolve();
|
||||
} else {
|
||||
this._started.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the underlying RPC client has been initialized.
|
||||
* Used in cases where a quick check of the initialization state is desired instead of waiting on the `ready` promise.
|
||||
*/
|
||||
public get isInitialized(): boolean {
|
||||
return !!this._rpcClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying RPC client.
|
||||
* This should only be called once during initialization.
|
||||
*/
|
||||
public setLanguageClient(languageClient?: rpc.LanguageClient): void {
|
||||
this._rpcClient = languageClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and return the underlying RPC client.
|
||||
* Strips away the `undefined` type from `this._rpcClient`.
|
||||
*/
|
||||
private get rpcClient(): rpc.LanguageClient {
|
||||
if (!this._rpcClient) {
|
||||
throw new Error("Attempting to use languageClient before initialized");
|
||||
}
|
||||
|
||||
return this._rpcClient;
|
||||
}
|
||||
|
||||
public get protocol2CodeConverter(): rpc.LanguageClient["protocol2CodeConverter"] {
|
||||
return this.rpcClient.protocol2CodeConverter;
|
||||
}
|
||||
|
||||
public get code2ProtocolConverter(): rpc.LanguageClient["code2ProtocolConverter"] {
|
||||
return this.rpcClient.code2ProtocolConverter;
|
||||
}
|
||||
|
||||
public async sendRequest<P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Promise<R> {
|
||||
await this.ready;
|
||||
return this.rpcClient.sendRequest(type, params, token);
|
||||
}
|
||||
|
||||
public async sendNotification<P>(type: NotificationType<P>, params?: P): Promise<void> {
|
||||
await this.ready;
|
||||
return this.rpcClient.sendNotification(type, params);
|
||||
}
|
||||
|
||||
public onNotification<P>(type: NotificationType<P>, handler: NotificationHandler<P>): Disposable {
|
||||
// These messages are received from cpptools, and therefore it is not needed to await the ready signal.
|
||||
return this.rpcClient.onNotification(type, handler);
|
||||
}
|
||||
|
||||
public stop(): Promise<void> {
|
||||
return this._rpcClient?.stop() ?? Promise.resolve();
|
||||
}
|
||||
}
|
||||
@@ -45,10 +45,8 @@ export function createProtocolFilter(): Middleware {
|
||||
// client.takeOwnership() will call client.TrackedDocuments.add() again, but that's ok. It's a Set.
|
||||
client.takeOwnership(document);
|
||||
void sendMessage(document);
|
||||
client.ready.then(() => {
|
||||
const cppEditors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => util.isCpp(e.document));
|
||||
client.onDidChangeVisibleTextEditors(cppEditors).catch(logAndReturn.undefined);
|
||||
}).catch(logAndReturn.undefined);
|
||||
void client.onDidChangeVisibleTextEditors(cppEditors).catch(logAndReturn.undefined);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
* See 'LICENSE' in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
export function escapePathForSquiggles(s: string): string {
|
||||
return s.replace(/[-"\/\\^$*+?.()|[\]{}]/g, (character: string): string =>
|
||||
character === '"' ? '\\\\"' : `\\${character}`);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
* See 'LICENSE' in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import { describe, it } from 'mocha';
|
||||
import { doesNotMatch, match, strictEqual } from 'node:assert';
|
||||
import { escapePathForSquiggles } from '../../src/Utility/Text/escape';
|
||||
|
||||
describe('Text escaping', () => {
|
||||
it('escapes paths for matching their JSON spelling', () => {
|
||||
strictEqual(escapePathForSquiggles('"'), '\\\\"');
|
||||
strictEqual(escapePathForSquiggles('\\'), '\\\\');
|
||||
strictEqual(escapePathForSquiggles('.*'), '\\.\\*');
|
||||
|
||||
const parsedPath: string = String.raw`C:\src"quoted"`;
|
||||
const sourcePath: string = String.raw`C:\src\"quoted\"`;
|
||||
const pattern: RegExp = new RegExp(`^${escapePathForSquiggles(parsedPath)}$`);
|
||||
match(sourcePath, pattern);
|
||||
doesNotMatch(parsedPath, pattern);
|
||||
});
|
||||
|
||||
it('handles repeated backslashes and regex metacharacters', () => {
|
||||
const parsedPath: string = String.raw`C:\\sdk\\[headers]+(x)?.h\\say"hello"and"goodbye`;
|
||||
const sourcePath: string = String.raw`C:\\sdk\\[headers]+(x)?.h\\say\"hello\"and\"goodbye`;
|
||||
const pattern: RegExp = new RegExp(`^${escapePathForSquiggles(parsedPath)}$`);
|
||||
|
||||
match(sourcePath, pattern);
|
||||
doesNotMatch(String.raw`C:\sdk\[headers]+(x)?.h\say\"hello\"and\"goodbye`, pattern);
|
||||
doesNotMatch(String.raw`C:\\sdk\\headers+(x)?.h\\say\"hello\"and\"goodbye`, pattern);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user