diff --git a/Extension/.eslintignore b/Extension/.eslintignore index 818c616170..2f0e3f1026 100644 --- a/Extension/.eslintignore +++ b/Extension/.eslintignore @@ -1,2 +1,4 @@ +gulpfile.js test/**/index.ts test/**/runTest.ts +tools/prepublish.js diff --git a/Extension/.eslintrc.js b/Extension/.eslintrc.js index 3b9c975cc4..ae4626842d 100644 --- a/Extension/.eslintrc.js +++ b/Extension/.eslintrc.js @@ -87,6 +87,7 @@ module.exports = { "error", "never" ], + "prefer-const": "error", "prefer-object-spread": "error", "space-in-parens": [ "error", diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 610b331d46..48d16dc9dc 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,5 +1,52 @@ # C/C++ for Visual Studio Code Change Log +## Version 0.29.0: July 15, 2020 +### New Features +* Add Doxygen comment support (to tooltip display of hover, completion, and signature help). [#658](https://github.com/microsoft/vscode-cpptools/issues/658) + * The way comments are formatted is controlled by the C_Cpp.simplifyStructuredComments setting." +* Auto-convert `.` to `->` when the type is a pointer. [#862](https://github.com/microsoft/vscode-cpptools/issues/862) +* Switch to using the VS Code Semantic Tokens API for semantic colorization (works with remoting). [PR #5401](https://github.com/microsoft/vscode-cpptools/pull/5401), [#3932](https://github.com/microsoft/vscode-cpptools/issues/3932), [#3933](https://github.com/microsoft/vscode-cpptools/issues/3933), [#3942](https://github.com/microsoft/vscode-cpptools/issues/3942) +* Add support for LogMessage Breakpoints for debug type `cppdbg`. [MIEngine#1013](https://github.com/microsoft/MIEngine/pull/1013) + +### Enhancements +* Automatically add `"${default}"` to the default `includePath` in `c_cpp_properties.json` if `C_Cpp.default.includePath` is set. [#3733](https://github.com/microsoft/vscode-cpptools/issues/3733) +* Add configuration provider logging to `C/C++: Log Diagnostics`. [#4826](https://github.com/microsoft/vscode-cpptools/issues/4826) +* Add support for the Debug Welcome Panel. [#4837](https://github.com/microsoft/vscode-cpptools/issues/4837) +* Update to clang-format 10. [#5194](https://github.com/microsoft/vscode-cpptools/issues/5194) +* Add system to store and query properties from the active C/C++ configuration. + * bugengine (@bugengine) [PR #5453](https://github.com/microsoft/vscode-cpptools/pull/5453) +* Add `quoteArgs` to `launch.json` schema. [PR #5639](https://github.com/microsoft/vscode-cpptools/pull/5639) +* Add logs for a resolved `launch.json` if "engineLogging" is enabled. [PR #5644](https://github.com/microsoft/vscode-cpptools/pull/5644) +* Add threadExit and processExit logging flags for 'cppvsdbg'. [PR #5652](https://github.com/microsoft/vscode-cpptools/pull/5652) + +### Bug Fixes +* Add localization support for autocomplete and hover text. [#5370](https://github.com/microsoft/vscode-cpptools/issues/5370) +* Some `updateChannel` fixes. [PR #5465](https://github.com/microsoft/vscode-cpptools/pull/5465) +* Fix wrong language standard used with compile commands. [#5498](https://github.com/microsoft/vscode-cpptools/issues/5498) +* Fix issue with defines and includes not being handled correctly in `compilerPath` or `compilerArgs`. [#5512](https://github.com/microsoft/vscode-cpptools/issues/5512) +* Add gcc/gcc-10 compiler detection. [#5540](https://github.com/microsoft/vscode-cpptools/issues/5540) +* Fix `--target` compiler arg getting overridden. [#5557](https://github.com/microsoft/vscode-cpptools/issues/5557) + * Matt Schulte (@schultetwin1) +* Fix Find All References and Rename when multiple references are on the same line. [#5568](https://github.com/microsoft/vscode-cpptools/issues/5568) +* Fix IntelliSense process crashes. [#5584](https://github.com/microsoft/vscode-cpptools/issues/5584), [#5629](https://github.com/microsoft/vscode-cpptools/issues/5629) +* Fix an add/remove workspace folder crash. [#5591](https://github.com/microsoft/vscode-cpptools/issues/5591) +* Fix default build tasks failing on Windows if the compiler isn't on the PATH. [#5604](https://github.com/microsoft/vscode-cpptools/issues/5604) +* Fix updating `files.associations` and .C files being associated with C instead of C++. [#5618](https://github.com/microsoft/vscode-cpptools/issues/5618) +* Fix IntelliSense malfunction when RxCpp is used. [#5619](https://github.com/microsoft/vscode-cpptools/issues/5619) +* Ignore "screen size is bogus" error when debugging. [PR #5669](https://github.com/microsoft/vscode-cpptools/pull/5669) + * nukoyluoglu (@nukoyluoglu) +* Fix `compile_commands.json` sometimes not updating. [#5687](https://github.com/microsoft/vscode-cpptools/issues/5687) +* Add msys2 clang compilers to the compiler search list (previously only gcc was handled). [#5697](https://github.com/microsoft/vscode-cpptools/issues/5697) +* Fix extension getting stuck when an "@" response file that doesn't end with ".rsp" is used in `compilerArgs`. [#5731](https://github.com/microsoft/vscode-cpptools/issues/5731) +* Fix forced includes not handled properly when parsed as compiler args. [#5738](https://github.com/microsoft/vscode-cpptools/issues/5738) +* Fix potential thread deadlock in cpptools. +* Fix copying a long value from debug watch results in pasting partial value [#5470](https://github.com/microsoft/vscode-cpptools/issues/5470) + * [PR MIEngine#1009](https://github.com/microsoft/MIEngine/pull/1009) +* Fix Modifying conditional breakpoints [#2297](https://github.com/microsoft/vscode-cpptools/issues/2297) + * [PR MIEngine#1010](https://github.com/microsoft/MIEngine/pull/1010) +* Fix find .exe in Windows path [#3076](https://github.com/microsoft/vscode-cpptools/issues/3076) + * [PR MIEngine#1001](https://github.com/microsoft/MIEngine/pull/1001) + ## Version 0.28.3: June 9, 2020 ### Enhancements * Update version of vscode-cpptools API to 4.0.1 [PR #5624](https://github.com/microsoft/vscode-cpptools/pull/5624) diff --git a/Extension/bin/messages/cs/messages.json b/Extension/bin/messages/cs/messages.json index a8ef6e763c..c2a603b5bf 100644 --- a/Extension/bin/messages/cs/messages.json +++ b/Extension/bin/messages/cs/messages.json @@ -1535,7 +1535,7 @@ "neplatná hodnota cannot-redefine", "duplicitní modifikátor funkce", "neplatný znak pro literál char16_t", - "__LPREFIX se nedá použít u literálů char8_t, char16_t nebo char32_t.", + null, "Nerozpoznaná konvence volání %s, musí být jednou z:", null, null, @@ -3122,7 +3122,7 @@ "zachytávání *this je v tomto režimu nestandardní", "Předpona atributu using ve stylu C++17 je v tomto režimu nestandardní.", "Vnořené obory názvů ve stylu C++17 jsou v tomto režimu nestandardní.", - "V deklaraci nemůžou být současně constexpr i consteval.", + "V deklaraci se může vyskytovat jen jedna z těchto možností: constexpr, consteval a constinit", "funkce nemůže být v tomto režimu zároveň consteval a virtuální", "U explicitní direktivy vytváření instancí není povolený modifikátor consteval.", "Modifikátor consteval tady není platný.", @@ -3166,7 +3166,7 @@ "Atribut internal_linkage se nevyskytuje v předchozí deklaraci.", "Pro %n se nenašel žádný vhodný kandidát pro dedukci argumentu šablony.", "Volání plně kvalifikovaného konstruktoru se nepovoluje.", - "Operátor porovnání se dá nastavit na výchozí hodnotu jen v definici třídy.", + "Operátor porovnání nastavený jako výchozí musí být členem třídy, na kterou se vztahuje, nebo pro ni musí být nastavený jako friend.", "Chybný typ %t pro parametr výchozího operátoru porovnání (musí to být odkaz na const X, kde X je uzavírající typ třídy)", "Návratový typ výchozího operátoru porovnání musí být bool.", "Výchozí operátor porovnání členů musí být const.", @@ -3233,6 +3233,8 @@ "co_await se může vztahovat jen na příkaz for založený na rozsahu.", "Typ rozsahu ve smyčce for založené na rozsahu se nedá vyvodit.", "Vložené proměnné jsou funkce standardu C++17.", + "Destrukční operátor delete vyžaduje jako první parametr %t.", + "Destrukční operátor delete nemůže mít parametry jiné než std::size_t a std::align_val_t.", "možnosti volné (relaxed) abstraktní třídy se dají použít jenom při kompilaci C++", "Neplatný začátek výrazu v klauzuli requires", "Výraz cast v klauzuli requires musí být v uvozovkách.", @@ -3242,7 +3244,7 @@ "Atomické omezení není konstanta.", "Hodnota atomického omezení se vyhodnotí jako false.", "Omezení šablony není splněné.", - "Definice koncepce se nemůže vyskytovat v tomto oboru.", + "V tomto oboru se definice konceptu nemůže vyskytovat.", "Neplatná změna deklarace %nd", "Nepodařilo se nahradit argumenty pro concept-id.", "Koncept je false.", @@ -3250,7 +3252,7 @@ "Šablona konceptu", "Klauzule requires není kompatibilní s %nfd.", "Očekával se atribut.", - "Neplatný začátek požadavku", + null, "Očekával se název typu.", "Parametr výpustky není ve výrazu requires povolený.", "Nepojmenovaný parametr ve výrazu requires nemá žádný efekt.", @@ -3274,14 +3276,14 @@ "Soubor modulu", "Nepodařilo se najít soubor modulu pro modul %sq.", "Soubor modulu %sq se nepovedlo naimportovat.", - "Očekával se soubor modulu %s1, ale našel se soubor modulu %s2.", + "Očekávalo se %s1, ale našlo se %s2.", "Při otevírání souboru modulu %sq", "Neznámý název oddílu %sq", - "Neznámé", - "Importovatelné záhlaví", - "EDG", - "IFC", - "Neočekávané", + "neznámý soubor modulu", + "soubor modulu s importovatelnou hlavičkou", + "soubor modulu EDG", + "soubor modulu IFC", + "neočekávaný soubor modulu", "Typ druhého operandu %t2 musí mít stejnou velikost jako %t1.", "Typ musí být možné triviálně kopírovat.", "Typ %t se pro vyhodnocování constexpr v __builtin_bit_cast v současné době nepodporuje.", @@ -3297,5 +3299,27 @@ "Tento operátor se na tomto místě nepodporuje. Uzavřete předchozí výraz new do závorek.", "Neplatné použití konceptu", "Výchozí operátor porovnání členů nemůže být kvalifikovaný jako &&.", - "Výchozí funkce pro porovnání constexpr volá funkci %nd, která constexpr není." + "Výchozí funkce pro porovnání constexpr volá funkci %nd, která constexpr není.", + "Porovnání paměti constexpr se podporuje jen pro celé číslo nejvyšší úrovně nebo objekty polí celých čísel.", + "Šablona konceptu nemůže mít přidružená omezení.", + "export se nepovoluje.", + "Export jednotlivých členů třídy se nepodporuje.", + "Exportovaná deklarace musí zavést název.", + "Deklarace exportu nemůže obsahovat deklaraci exportu (předchozí deklarace %p).", + "Deklarace exportu nemůže obsahovat deklaraci importu modulu.", + "Deklarace exportu se může vyskytnout jen v jednotce rozhraní modulu.", + "Deklarace exportu nemůže exportovat název s interním propojením.", + "Deklarace using zahrnuje %nfd.", + "Předdefinovaná funkce není dostupná, protože typy s plovoucí desetinnou čárkou __fp16 se nepodporují.", + "Výraz requires musí určovat alespoň jeden požadavek.", + "Modifikátor constinit tady není platný.", + "Modifikátor constinit je platný jen pro deklarace proměnných s dobou trvání úložiště static nebo thread.", + "Proměnná constinit vyžaduje dynamickou inicializaci.", + "Proměnná se už dříve deklarovala s constinit %p.", + "Použití deklarátoru funkce, která není prototyp", + "Argument nemůže mít typ kvalifikovaný jako const.", + "Ukazatel na člen neúplného typu %t se nepovoluje.", + "Rozšíření balíčku v init-capture se v tomto režimu nepodporuje.", + "Rozšíření balíčku v init-capture je funkce jazyka C++20.", + "Operátor porovnání v definici třídy nastavený jako výchozí musí být první deklarace daného operátoru porovnání (%nd)." ] \ No newline at end of file diff --git a/Extension/bin/messages/de/messages.json b/Extension/bin/messages/de/messages.json index 19a3ce9ceb..63564876c2 100644 --- a/Extension/bin/messages/de/messages.json +++ b/Extension/bin/messages/de/messages.json @@ -1535,7 +1535,7 @@ "Ungültiger Wert für Neudefinitionsfehler.", "Doppelter Funktionsmodifizierer.", "Ungültiges Zeichen für char16_t-Literal.", - "__LPREFIX kann nicht auf char8_t-, char16_t- oder char32_t-Literale angewendet werden.", + null, "Unbekannte Aufrufkonvention \"%s\", muss eine der folgenden Optionen sein:", null, null, @@ -2065,7 +2065,7 @@ "ein cli::pin_ptr-Rückgabetyp ist nicht zulässig", "Attribut %sq wird nur im %[C++/CLI]-Modus angewendet", "ein einfacher (Nicht-Nachverfolgungs-)Verweis kann nicht an eine Entität im verwalteten Heap gebunden werden", - "übertragbare Assembly", + "portierbare Assembly", "'%s' nicht von Standardassemblys geladen", "die Listeninitialisierungssyntax ist eine C++11-Funktion", "der Operand von sizeof kann kein Verweisklassentyp oder Schnittstellenklassentyp sein", @@ -3122,7 +3122,7 @@ "Das Erfassen von *this ist in diesem Modus nicht standardisiert.", "Attributpräfix \"using\" im C++17-Stil ist in diesem Modus nicht standardisiert.", "Geschachtelte Namespaces im C++17-Stil sind in diesem Modus nicht standardisiert.", - "\"constexpr\" und \"consteval\" können in einer Deklaration nicht zugleich auftreten.", + "In einer Deklaration kann nur einer der Werte \"constexpr\", \"consteval\" und \"constinit\" verwendet werden.", "Eine Funktion kann in diesem Modus nicht zugleich consteval und virtual sein.", "\"consteval\" ist in einer expliziten Instanziierungsdirektive nicht zulässig.", "\"consteval\" ist hier nicht gültig.", @@ -3166,7 +3166,7 @@ "Das Attribut \"internal_linkage\" war in keiner vorherigen Deklaration vorhanden.", "Für \"%n\" wurde kein geeigneter Kandidat für die Vorlagenargumentdeduktion gefunden.", "Der Aufruf eines vollqualifizierten Konstruktors ist nicht zulässig.", - "Ein Vergleichsoperator kann nur in einer Klassendefinition standardmäßig verwendet werden.", + "Ein auf den Standardwert festgelegter Vergleichsoperator muss ein Member oder Friend der Klasse sein, auf die er angewendet wird.", "Ungültiger Typ \"%t\" für den Parameter des Standardvergleichsoperators (muss \"reference to const X\" lauten, wobei X für den einschließenden Klassentyp steht).", "Der Rückgabetyp des Standardvergleichsoperators muss \"bool\" lauten.", "Ein standardmäßiger Membervergleichsoperator muss \"const\" lauten.", @@ -3233,6 +3233,8 @@ "co_await kann nur auf eine bereichsbasierte for-Anweisung angewendet werden.", "Der Typ des Bereichs kann in einer bereichsbasierten for-Schleife nicht abgeleitet werden.", "Inlinevariablen sind ein C++17-Feature.", + "Für eine \"operator delete\"-Funktion mit Zerstörung wird \"%t\" als erster Parameter benötigt.", + "Eine \"operator delete\"-Funktion mit Zerstörung kann nur die Parameter \"std::size_t\" und \"std::align_val_t\" aufweisen.", "Optionen einer lockeren abstrakten Klasse können nur beim Kompilieren von C++ verwendet werden.", "Ungültiger Start des Ausdrucks in requires-Klausel.", "Ein cast-Ausdruck in einer requires-Klausel muss in Klammern gesetzt werden.", @@ -3250,7 +3252,7 @@ "Konzeptvorlage", "Die requires-Klausel ist nicht mit \"%nfd\" kompatibel.", "Es wurde ein Attribut erwartet.", - "Ungültiger Start der Anforderung.", + null, "Es wurde ein Typname erwartet.", "Ein ellipsis-Parameter ist in einem requires-Ausdruck nicht zulässig.", "Ein unbenannter Parameter in einem requires-Ausdruck hat keine Auswirkungen.", @@ -3274,14 +3276,14 @@ "Moduldatei", "Die Moduldatei für das Modul \"%sq\" wurde nicht gefunden.", "Die Moduldatei \"%sq\" konnte nicht importiert werden.", - "Es wurde die Moduldatei \"%s1\" erwartet, stattdessen wurde die Moduldatei \"%s2\" gefunden.", + "Erwartet wurde \"%s1\", stattdessen gefunden: \"%s2\".", "beim Öffnen der Moduldatei \"%sq\"", "Unbekannter Partitionsname \"%sq\".", - "unbekanntes Element", - "importierbarer Header", - "EDG", - "IFC", - "unerwartetes Element", + "Unbekannte Moduldatei", + "Importierbare Headermoduldatei", + "EDG-Moduldatei", + "IFC-Moduldatei", + "Unerwartete Moduldatei", "Der Typ des zweiten Operanden, \"%t2\", muss die gleiche Größe aufweisen wie \"%t1\".", "Der Typ muss trivial kopierbar sein.", "Der Typ \"%t\" wird derzeit für die constexpr-Auswertung von \"__builtin_bit_cast\" nicht unterstützt.", @@ -3297,5 +3299,27 @@ "Der this-Operator ist an dieser Stelle nicht zulässig. Schließen Sie den vorangehenden new-Ausdruck in Klammern ein.", "Ungültige Verwendung von \"concept\".", "Ein standardmäßiger Membervergleichsoperator kann nicht &&-qualifiziert sein.", - "Die constexpr-Standardvergleichsfunktion ruft die Nicht-constexpr-Funktion \"%nd\" auf." + "Die constexpr-Standardvergleichsfunktion ruft die Nicht-constexpr-Funktion \"%nd\" auf.", + "Der constexpr-Speichervergleich wird nur für integer-Objekte oder array-of-integer-Objekte oberster Ebene unterstützt.", + "Einer Konzeptvorlage können keine Einschränkungen zugeordnet sein.", + "\"export\" ist nicht zulässig.", + "Das Exportieren einzelner Klassenmember ist nicht zulässig.", + "Eine exportierte Deklaration muss einen Namen einführen.", + "Eine Exportdeklaration kann keine Exportdeklaration enthalten (vorherige Deklaration: %p).", + "Eine Exportdeklaration kann keine Modulimportdeklaration enthalten.", + "Eine Exportdeklaration kann nur in einer Modulschnittstelleneinheit verwendet werden.", + "Eine Exportdeklaration kann keinen Namen mit interner Verknüpfung exportieren.", + "Die using-Deklaration enthält \"%nfd\".", + "Die integrierte Funktion ist nicht verfügbar, weil __fp16-Gleitkommatypen nicht unterstützt werden.", + "Für einen requires-Ausdruck muss mindestens eine Anforderung angegeben werden.", + "\"constinit\" ist hier nicht gültig.", + "\"constinit\" ist nur für Deklarationen von Variablen mit Speicherdauer \"static\" oder \"thread\" gültig.", + "Die constinit-Variable erfordert eine dynamische Initialisierung.", + "Die Variable wurde zuvor mit \"constinit\" deklariert: %p", + "Verwendung eines Funktionsdeklarators ohne Prototyp ", + "Das Argument darf keinen const-qualifizierten Typ aufweisen.", + "Eine Pointer-to-Member-Funktion eines unvollständigen Typs \"%t\" ist nicht zulässig.", + "Die Paketerweiterung in \"init-capture\" ist in diesem Modus nicht aktiviert.", + "Die Paketerweiterung in \"init-capture\" ist ein C++ 20-Feature.", + "Ein auf den Standardwert festgelegter Vergleichsoperator in einer Klassendefinition muss als erste Deklaration dieses Vergleichsoperators (%nd) aufgeführt sein." ] \ No newline at end of file diff --git a/Extension/bin/messages/es/messages.json b/Extension/bin/messages/es/messages.json index a88eae6ccd..afe6118057 100644 --- a/Extension/bin/messages/es/messages.json +++ b/Extension/bin/messages/es/messages.json @@ -1535,7 +1535,7 @@ "valor que indica que no se puede definir de nuevo no válido", "modificador de función duplicado", "carácter no válido para el literal char16_t", - "__LPREFIX no se puede aplicar a los literales char8_t, char16_t o char32_t", + null, "convención de llamada %s no reconocida, debe ser una de las siguientes:", null, null, @@ -2065,7 +2065,7 @@ "no se permite el tipo de valor devuelto cli::pin_ptr", "el atributo %sq se aplica solamente en el modo %[C++/CLI]", "una referencia simple (que no sea de seguimiento) no se puede enlazar a una entidad en el montón administrado", - "ensamblado portátil", + "ensamblado portable", "'%s' no se cargó de los ensamblados predeterminados", "la sintaxis de inicialización de la lista es una funcionalidad de C++11", "el operando de sizeof no puede ser un tipo de clase ref o interface", @@ -3122,7 +3122,7 @@ "la captura de *this no es estándar en este modo", "El prefijo del atributo \"using\" de estilo C++17 no es estándar en este modo", "Los espacios de nombres anidados de estilo C++17 no son estándar en este modo", - "\"constexpr\" y \"consteval\" no pueden aparecer simultáneamente en una declaración", + "solo puede aparecer uno de los elementos \"constexpr\", \"consteval\" y \"constinit'' en una declaración", "una función no puede ser consteval y virtual a la vez en este modo", "\"consteval\" no se permite en una directiva de creación de una instancia explícita", "\"consteval\" no es válido aquí", @@ -3166,7 +3166,7 @@ "El atributo \"internal_linkage\" no aparecía en una declaración anterior", "no se ha encontrado ningún candidato de deducción de argumentos de plantilla viable para %n", "no se permite una llamada de constructor completa", - "a un operador de comparación solo se le puede asignar un valor predeterminado en una definición de clase", + "un operador de comparación predeterminado debe ser un miembro o un elemento de confianza de la clase a la que se aplica", "tipo %t incorrecto para el parámetro del operador de comparación con valores predeterminados (debe ser una \"referencia a const X\", donde X es el tipo de clase envolvente)", "el tipo de valor devuelto del operador de comparación con valores predeterminados debe ser \"bool\"", "un operador de comparación de miembros con valores predeterminados debe ser \"const\"", @@ -3233,6 +3233,8 @@ "co_await solo se puede aplicar a una instrucción for basada en intervalo", "no se puede deducir el tipo de intervalo en el bucle \"for\" basado en intervalo", "las variables insertadas son una característica de C++17", + "el operador de destrucción requiere %t como primer parámetro", + "un operador de destrucción \"delete\" no puede tener parámetros distintos de std::size_t y std::align_val_t", "las opciones de clase abstracta flexible solo se pueden usar al compilar C++", "inicio no válido de la expresión en la cláusula requires", "una expresión cast en una cláusula requires debe estar entre paréntesis", @@ -3250,7 +3252,7 @@ "plantilla de concepto", "la cláusula requires es incompatible con %nfd", "se esperaba un atributo", - "inicio no válido del requisito", + null, "se esperaba un nombre de tipo", "no se permite un parámetro de puntos suspensivos en una expresión requires", "el parámetro sin nombre de la expresión requires no tiene ningún efecto", @@ -3274,14 +3276,14 @@ "archivo de módulo", "no se encuentra el archivo del módulo %sq", "No se puede importar el archivo de módulo %sq.", - "se esperaba el archivo de módulo %s1, pero se encontró el archivo de módulo %s2 en su lugar", + "se esperaba %s1, pero se encontró %s2 en su lugar", "al abrir el archivo de módulo %sq", - "nombre de partición %sq desconocida", - "desconocido", - "encabezado importable", - "EDG", - "IFC", - "inesperado", + "nombre de partición %sq desconocido", + "un archivo de módulo desconocido", + "un archivo de módulo de encabezado importable", + "un archivo de módulo EDG", + "un archivo de módulo IFC", + "un archivo de módulo inesperado", "el tipo del segundo operando %t2 debe tener el mismo tamaño que %t1", "el tipo debe poder copiarse de forma trivial", "no se admite el tipo %t para la evaluación constexpr de __builtin_bit_cast", @@ -3297,5 +3299,27 @@ "este operador no está permitido en este punto; incluya la expresión \"new\" anterior entre paréntesis", "uso no válido del concepto", "un operador de comparación de miembros con valores predeterminados no puede estar calificado con \"&&\"", - "la función de comparación constexpr predeterminada llama a una función %nd que no es constexpr" + "la función de comparación constexpr predeterminada llama a una función %nd que no es constexpr", + "la comparación de memoria de constexpr solo se admite para objetos de matriz de enteros o enteros de nivel superior", + "una plantilla de concepto no puede tener restricciones asociadas", + "no se permite \"export\"", + "no se permite la exportación de miembros de clases individuales", + "una declaración exportada debe introducir un nombre", + "una declaración de exportación no puede contener otra declaración de exportación (declaración %p anterior)", + "una declaración de exportación no puede contener una declaración de importación de módulo", + "una declaración de exportación solo puede aparecer en una unidad de interfaz de módulo", + "una declaración de exportación no puede exportar un nombre con vinculación interna", + "la declaración using incluye %nfd", + "la función builtin no está disponible porque no se admiten tipos de punto flotante __fp16", + "una expresión requires debe especificar al menos un requisito", + "\"constexpr\" no es válido aquí", + "\"constinit\" solo es válido para las declaraciones de variables con duración de almacenamiento estático o de subproceso", + "la variable constinit requiere la inicialización dinámica", + "la variable se declaró previamente con \"constinit\" %p", + "uso del declarador de función no prototipo", + "el argumento no puede tener un tipo calificado constante", + "no se permite un puntero a miembro de un tipo %t incompleto", + "la expansión del paquete en la captura de inicialización no está habilitada en este modo", + "la expansión del paquete en la captura de inicialización es una característica de C++20", + "un operador de comparación con valor predeterminado en una definición de clase debe ser la primera declaración de ese operador de comparación (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/fr/messages.json b/Extension/bin/messages/fr/messages.json index de645d816c..91bcf889fa 100644 --- a/Extension/bin/messages/fr/messages.json +++ b/Extension/bin/messages/fr/messages.json @@ -1535,7 +1535,7 @@ "valeur cannot-redefine non valide", "modificateur de fonction dupliqué", "caractère non valide pour le littéral char16_t", - "Impossible d'appliquer __LPREFIX aux littéraux char8_t, char16_t ou char32_t", + null, "convention d'appel inconnue %s, doit être l'une des suivantes :", null, null, @@ -3122,7 +3122,7 @@ "la capture de *this n'est pas standard dans ce mode", "Le préfixe d'attribut 'using' de style C++17 n'est pas standard dans ce mode", "Les espaces de noms imbriqués de style C++17 ne sont pas standard dans ce mode", - "'constexpr' et 'consteval' ne peuvent pas apparaître tous les deux dans une déclaration", + "seule une instance de 'constexpr', 'consteval' et 'constinit' peut apparaître dans une déclaration", "une fonction ne peut pas être à la fois consteval et virtual dans ce mode", "'consteval' n'est pas autorisé sur une directive d'instanciation explicite", "'consteval' est non valide ici", @@ -3166,7 +3166,7 @@ "l'attribut 'internal_linkage' n'est pas apparu dans une déclaration antérieure", "aucun candidat de déduction d'argument de modèle viable n'a été localisé pour %n", "un appel de constructeur complet n'est pas autorisé", - "un opérateur de comparaison peut uniquement être utilisé par défaut dans une définition de classe", + "un opérateur de comparaison par défaut doit être membre ou ami de la classe à laquelle il s'applique", "type %t incorrect pour le paramètre de l'opérateur de comparaison par défaut (il doit s'agir d'une 'référence à const X' où X est le type classe englobant)", "le type de retour de l'opérateur de comparaison par défaut doit être 'bool'", "un opérateur de comparaison de membres par défaut doit être 'const'", @@ -3233,6 +3233,8 @@ "co_await peut s'appliquer uniquement à une instruction for basée sur une plage", "impossible de déduire le type de la plage dans une boucle 'for' basée sur une plage", "les variables inline sont une fonctionnalité C++17", + "l'opérateur delete de destruction nécessite %t en tant que premier paramètre", + "un opérateur delete de destruction ne peut pas avoir d'autres paramètres que std::size_t et std::align_val_t", "les options de classe abstraite non limitées peuvent uniquement être utilisées durant la compilation en C++", "début d'expression non valide dans la clause requires", "une expression cast dans une clause requires doit être entre parenthèses", @@ -3250,7 +3252,7 @@ "modèle de concept", "clause requires incompatible avec %nfd", "attribut attendu", - "début d'exigence non valide", + null, "nom de type attendu", "un paramètre ellipse n'est pas autorisé dans une expression requires", "un paramètre sans nom dans une expression requires n'a aucun effet", @@ -3274,14 +3276,14 @@ "fichier de module", "fichier de module introuvable pour le module %sq", "impossible d'importer le fichier de module %sq", - "fichier de module %s1 attendu, fichier de module %s2 trouvé à la place", + "%s1 attendu, %s2 trouvé à la place", "à l'ouverture du fichier de module %sq", "nom de partition inconnu %sq", - "inconnu", - "en-tête importable", - "EDG", - "IFC", - "inattendu", + "fichier de module inconnu", + "fichier de module d'en-tête importable", + "fichier de module EDG", + "fichier de module IFC", + "fichier de module inattendu", "le type du deuxième opérande %t2 doit avoir la même taille que %t1", "le type doit pouvoir être copié de façon triviale", "le type %t n'est pas pris en charge pour l'évaluation de constexpr de __builtin_bit_cast", @@ -3297,5 +3299,27 @@ "cet opérateur n'est pas autorisé à ce stade ; mettez entre parenthèses l'expression new précédente", "utilisation non valide du concept", "un opérateur de comparaison de membres par défaut ne peut pas être qualifié en tant que '&&'", - "la fonction de comparaison constexpr par défaut appelle la fonction non constexpr %nd" + "la fonction de comparaison constexpr par défaut appelle la fonction non constexpr %nd", + "la comparaison de mémoire constexpr est prise en charge uniquement pour les objets d'entiers de niveau supérieur ou les objets de tableaux d'entiers", + "un modèle de concept ne peut pas avoir de contraintes associées", + "'export' n'est pas autorisé", + "l'exportation de membres de classe individuels n'est pas autorisée", + "une déclaration exportée doit introduire un nom", + "une déclaration export ne peut pas contenir de déclaration export (déclaration précédente %p)", + "une déclaration export ne peut pas contenir de déclaration import de module", + "une déclaration export ne peut apparaître que dans une unité d'interface de module", + "une déclaration export ne peut pas exporter un nom avec une liaison interne", + "la déclaration using inclut %nfd", + "la fonction intégrée n'est pas disponible, car les types à virgule flottante __fp16 ne sont pas pris en charge", + "une expression requires doit spécifier au moins une exigence", + "'constinit' est non valide ici", + "'constinit' est valide uniquement pour les déclarations de variables ayant une durée de stockage statique ou de thread", + "la variable constinit nécessite une initialisation dynamique", + "la variable a été déclarée avec 'constinit' %p", + "utilisation d'un déclarateur de fonction non-prototype", + "l'argument ne peut pas avoir un type qualifié const", + "un pointeur vers membre de type incomplet %t n'est pas autorisé", + "l'expansion de pack dans init-capture n'est pas activée dans ce mode", + "l'expansion de pack dans init-capture est une fonctionnalité C++20", + "un opérateur de comparaison par défaut dans une définition de classe doit être la première déclaration de cet opérateur de comparaison (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/it/messages.json b/Extension/bin/messages/it/messages.json index d96c36ef32..685eae5884 100644 --- a/Extension/bin/messages/it/messages.json +++ b/Extension/bin/messages/it/messages.json @@ -1535,7 +1535,7 @@ "valore di Impossibile ridefinire non valido", "modificatore di funzione duplicato", "carattere non valido per il valore letterale char16_t", - "non è possibile applicare __LPREFIX al valore letterale char8_t, char16_t o char32_t", + null, "convenzione di chiamata %s non riconosciuta. Deve essere una delle seguenti:", null, null, @@ -2065,7 +2065,7 @@ "tipo restituito cli::pin_ptr non consentito", "l'attributo %sq si applica solo in modalità %[C++/CLI]", "non è possibile associare un riferimento semplice (non di traccia) a un'entità nell'heap gestito", - "assembly portatile", + "assembly portabile", "'%s' non caricato da assembly predefiniti", "la sintassi di inizializzazione elenco è una funzionalità C++11", "l'operando di sizeof non può essere un tipo classe di interfaccia o un tipo classe di riferimento", @@ -3122,7 +3122,7 @@ "l'acquisizione di *this non è standard in questa modalità", "il prefisso dell'attributo di 'using' di tipo C++17 non è standard in questa modalità", "gli spazi dei nomi annidati di tipo C++17 non sono standard in questa modalità", - "una dichiarazione non può contenere sia 'constexpr' che 'consteval'", + "una dichiarazione può contenere solo una tra le variabili 'constexpr', 'consteval' e 'constinit'", "una funzione non può essere contemporaneamente consteval e virtual in questa modalità", "'consteval' non è consentito in una direttiva di creazione esplicita di un'istanza", "'consteval' non è valido in questo punto", @@ -3166,7 +3166,7 @@ "l'attributo 'internal_linkage' non era presente in una dichiarazione precedente", "non è stato trovato alcun candidato di deduzione dell'argomento di modello valido per %n", "una chiamata al costruttore completo non è consentita", - "un operatore di confronto può essere impostato come predefinito solo in una definizione di classe", + "l'operatore di confronto impostato come predefinito deve essere un membro o un elemento friend della classe a cui si applica", "il tipo %t per il parametro dell'operatore di confronto impostato come predefinito non è valido. Deve essere 'reference to const X' dove X è il tipo della classe contenitore", "il tipo restituito dell'operatore di confronto impostato come predefinito deve essere 'bool'", "un operatore di confronto membri impostato come predefinito non può essere 'const'", @@ -3233,6 +3233,8 @@ "co_await può essere applicato solo a un'istruzione for basata su intervallo", "non è possibile dedurre il tipo dell'intervallo nel ciclo 'for' basato su intervallo", "le variabili inline sono una funzionalità di C++17", + "per l'eliminazione dell'operatore di eliminazione definitiva è necessario specificare %t come primo parametro", + "per l'eliminazione di un operatore di eliminazione definitiva non è possibile specificare parametri diversi da std::size_t e std::align_val_t", "è possibile usare le opzioni di classe astratta di tipo relaxed solo quando si esegue la compilazione nel linguaggio C++", "l'inizio dell'espressione non è valido nella clausola requires", "un'espressione cast in una clausola requires deve essere racchiusa tra parentesi", @@ -3250,7 +3252,7 @@ "modello di concetto", "la clausola requires non è compatibile con %nfd", "è previsto un attributo", - "l'inizio del requisito non è valido", + null, "è previsto un nome di tipo", "in un'espressione requires non sono consentiti parametri con puntini di sospensione", "il parametro senza nome nell'espressione requires non ha alcun effetto", @@ -3274,14 +3276,14 @@ "file di modulo", "non è stato possibile trovare il file di modulo per il modulo %sq", "non è stato possibile importare il file di modulo %sq", - "è previsto il file di modulo %s1, ma è stato trovato il file di modulo %s2", + "è previsto %s1, ma è stato trovato %s2", "durante l'apertura del file di modulo %sq", "il nome di partizione %sq è sconosciuto", - "sconosciuto", - "intestazione importabile", - "EDG", - "IFC", - "imprevisto", + "un file di modulo sconosciuto", + "un file di modulo intestazione importabile", + "un file di modulo EDG", + "un file di modulo IFC", + "un file di modulo imprevisto", "il tipo del secondo operando %t2 deve avere le stesse dimensioni di %t1", "il tipo deve essere facilmente copiabile", "il tipo %t non è attualmente supportato per la valutazione constexpr di __builtin_bit_cast", @@ -3297,5 +3299,27 @@ "questo operatore non è consentito in questo punto. Racchiudere tra parentesi l'espressione new precedente", "uso del concetto non valido", "un operatore di confronto membri impostato come predefinito non può essere qualificato con '&&'", - "la funzione di confronto constexpr predefinita chiama la funzione non constexpr %nd" + "la funzione di confronto constexpr predefinita chiama la funzione non constexpr %nd", + "il confronto di memoria constexpr è supportato solo per gli oggetti intero o matrice di intero di primo livello", + "un modello di concetto non può avere vincoli associati", + "'export' non è consentito", + "l'esportazione di singoli membri di classe non è consentita", + "una dichiarazione esportata deve introdurre un nome", + "una dichiarazione di esportazione non può contenere una dichiarazione di esportazione (dichiarazione precedente %p)", + "una dichiarazione di esportazione non può contenere una dichiarazione di importazione del modulo", + "una dichiarazione di esportazione può essere presente solo in un'unità di interfaccia del modulo", + "una dichiarazione di esportazione non può esportare un nome con collegamento interno", + "la dichiarazione using include %nfd", + "la funzione predefinita non è disponibile perché i tipi a virgola mobile __fp16 non sono supportati", + "un'espressione requires deve specificare almeno un requisito", + "'constinit' non è valida in questo punto", + "'constinit' è valida solo per dichiarazioni con durata di archiviazione del thread o statica", + "con la variabile constinit è richiesta l'inizializzazione dinamica", + "la variabile è stata dichiarata in precedenza con 'constinit' %p", + "uso del dichiaratore di funzione non prototipo", + "l'argomento non può avere un tipo qualificato da const", + "non è consentito un puntatore a membro di un tipo incompleto %t", + "l'espansione del pacchetto in init-capture non è abilitata in questa modalità", + "l'espansione del pacchetto in init-capture è una funzionalità di C++20", + "un operatore di confronto impostato come predefinito in una definizione di classe deve essere la prima dichiarazione di tale operatore di confronto (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/ja/messages.json b/Extension/bin/messages/ja/messages.json index 1951bd9216..f756b13e08 100644 --- a/Extension/bin/messages/ja/messages.json +++ b/Extension/bin/messages/ja/messages.json @@ -1535,7 +1535,7 @@ "再定義できない無効な値です", "関数修飾子が重複しています", "char16_t リテラルには無効な文字です", - "__LPREFIX は char8_t、char16_t、または char32_t リテラルに適用できません", + null, "呼び出し規約 %s は認識されないため、次のいずれかを使用する必要があります:", null, null, @@ -2065,7 +2065,7 @@ "戻り値の型 cli::pin_ptr は使用できません", "属性 %sq は %[C++/CLI] モードでのみ適用されます", "単純 (非追跡) 参照はマネージド ヒープ上のエンティティにバインドできません", - "ポータブル アセンブリ", + "移植可能なアセンブリ", "'%s' は既定のアセンブリから読み込まれません", "リスト初期化構文は C++11 の機能です", "sizeof のオペランドは ref クラス型やインターフェイス クラス型であってはなりません", @@ -3122,7 +3122,7 @@ "*this のキャプチャはこのモードでは非標準です", "C++17 スタイルの 'using' 属性プレフィックスはこのモードでは非標準です", "C++17 スタイルの入れ子になった名前空間はこのモードでは非標準です", - "宣言で 'constexpr' および 'consteval' の両方を使用することはできません", + "宣言で使用できるのは、'constexpr'、'consteval'、および 'constinit'のうちの 1 つのみです", "このモードでは、関数に consteval と virtual の両方を指定することはできません", "明示的なインスタンス化ディレクティブでは 'consteval' を使用できません", "ここでは 'consteval' は無効です", @@ -3166,7 +3166,7 @@ "'internal_linkage' 属性は、前の宣言では使用されませんでした", "%n の有効なテンプレート引数演繹候補が見つかりませんでした", "完全修飾コンストラクターの呼び出しは許可されていません", - "比較演算子は、クラス定義でのみ既定値にすることができます", + "既定の比較演算子は、適用先のクラスのメンバーまたはフレンドでなければなりません。", "既定の比較演算子のパラメーターの型 %t が正しくありません ('const X' への参照でなければなりません。X は、囲むクラスの型です)", "既定の比較演算子の戻り値の型は 'bool' である必要があります", "既定のメンバー比較演算子は 'const' である必要があります", @@ -3233,6 +3233,8 @@ "co_await は範囲ベースの for ステートメントにのみ適用できます", "範囲ベースの 'for' ループの範囲の種類を推測できません", "インライン変数は C++17 の機能です", + "destroying operator delete には、最初のパラメーターとして %t が必要です", + "destroying operator delete に、std::size_t および std::align_val_t 以外のパラメーターを指定することはできません", "緩和された抽象クラス オプションは C++ をコンパイルするときにのみ使用できます", "requires 句の式の先頭が無効です", "requires 句内のキャスト式はかっこで囲む必要があります", @@ -3250,7 +3252,7 @@ "コンセプト テンプレート", "requires 句は %nfd と互換性がありません", "属性が必要です", - "要件の開始が無効です", + null, "型名が必要です", "requires 式では省略記号パラメーターは許可されていません", "requires 式に名前のないパラメーターを指定しても効果がありません", @@ -3274,14 +3276,14 @@ "モジュール ファイル", "モジュール %sq のモジュール ファイルが見つかりませんでした", "モジュール ファイル %sq をインポートできませんでした", - "%s1 モジュール ファイルが必要ですが、%s2 モジュール ファイルが見つかりました", + "%s1 が必要ですが、%s2 が見つかりました", "モジュール ファイル %sq を開くとき", "不明なパーティション名 %sq", - "不明", - "インポート可能なヘッダー", - "EDG", - "IFC", - "予期しない", + "不明なモジュール ファイル", + "インポート可能なヘッダー モジュール ファイル", + "EDG モジュール ファイル", + "IFC モジュール ファイル", + "予期しないモジュール ファイル", "第 2 オペランド %t2 の型は、%t1 と同じサイズである必要があります", "型は普通にコピー可能である必要があります", "型 %t は、現在、__builtin_bit_cast の constexpr 評価ではサポートされていません", @@ -3297,5 +3299,27 @@ "この演算子はこの時点では許可されていません。先行する新しい式をかっこで囲んでください", "概念が正しく使用されていません", "既定のメンバー比較演算子を '&&' で修飾することはできません", - "既定の constexpr 比較関数は、constexpr ではない関数 %nd を呼び出します" + "既定の constexpr 比較関数は、constexpr ではない関数 %nd を呼び出します", + "constexpr のメモリ比較は、トップレベルの整数または整数の配列オブジェクトでのみサポートされています", + "概念テンプレートに関連する制約を持たせることはできません", + "[エクスポート] は許可されていません", + "個別のクラス メンバーのエクスポートは許可されていません", + "エクスポートされた宣言は名前を導入する必要があります", + "エクスポート宣言にエクスポート宣言を含めることはできません (前の宣言 %p)", + "エクスポート宣言にモジュール インポート宣言を含めることはできません", + "エクスポート宣言はモジュール インターフェイス ユニットでのみ使用できます", + "エクスポート宣言では、内部リンケージを含む名前をエクスポートできません", + "using 宣言には %nfd が含まれます", + "fp16 の浮動小数点型がサポートされていないので、ビルトイン関数を使用できません(__F)", + "requires 式には少なくとも 1 つの要件を指定する必要があります", + "ここでは 'constinit' は無効です", + "'constinit' は、静的またはスレッド ストレージ存続期間を持つ変数の宣言にのみ有効です", + "constinit 変数には動的な初期化が必要です", + "変数は、以前に 'constinit' %p で宣言されました", + "プロトタイプ以外の関数宣言子の使用", + "引数に const 修飾型を指定することはできません", + "不完全な型 %t のメンバーへのポインターは使用できません", + "初期化キャプチャのパック展開はこのモードでは有効ではありません", + "初期化キャプチャのパック展開は C++20 の機能です", + "クラス定義で既定値にされた比較演算子は、その比較演算子の最初の宣言でなければなりません (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/ko/messages.json b/Extension/bin/messages/ko/messages.json index 0a863a037b..f795e983bb 100644 --- a/Extension/bin/messages/ko/messages.json +++ b/Extension/bin/messages/ko/messages.json @@ -1535,7 +1535,7 @@ "다시 정의할 수 없는 값이 잘못되었습니다.", "중복된 함수 한정자", "char16_t 리터럴에 대한 잘못된 문자", - "__LPREFIX를 char8_t, char16_t 또는 char32_t 리터럴에 적용할 수 없습니다.", + null, "인식할 수 없는 호출 규칙 %s, 다음 중 하나여야 함:", null, null, @@ -3122,7 +3122,7 @@ "*this 캡처는 이 모드에서 표준이 아닙니다.", "C++17 스타일 'using' 특성 접두사는 이 모드에서 표준이 아닙니다.", "C++17 스타일 중첩 네임스페이스는 이 모드에서 표준이 아닙니다.", - "'constexpr' 및 'consteval'을 둘 다 한 선언에서 사용할 수는 없습니다.", + "선언에 'constexpr', 'consteval' 및 'constinit' 중 하나만 나타날 수 있습니다.", "이 모드에서 함수가 동시에 consteval 및 virtual일 수는 없습니다.", "'consteval'은 명시적 인스턴스화 지시문에서 사용할 수 없습니다.", "'consteval'은 여기에 유효하지 않습니다.", @@ -3166,7 +3166,7 @@ "'internal_linkage' 특성이 이전 선언에 나타나지 않았습니다.", "%n에 대한 실행 가능한 템플릿 인수 추론 후보를 찾을 수 없음", "정규화된 생성자 호출은 허용되지 않습니다.", - "비교 연산자는 클래스 정의에서 기본값으로만 사용할 수 있습니다.", + "기본 비교 연산자는 적용되는 클래스의 멤버 또는 friend여야 합니다.", "기본 비교 연산자의 매개 변수에 대한 잘못된 형식 %t('const X에 대한 참조'여야 함, 여기서 X는 바깥쪽 클래스 형식임)", "기본 비교 연산자의 반환 형식은 'bool'이어야 합니다.", "기본 멤버 비교 연산자는 'cost'여야 합니다.", @@ -3233,6 +3233,8 @@ "co_await는 범위 기반의 for 문에만 적용할 수 있습니다.", "범위 기반의 'for' 루프에서 범위 형식을 추론할 수 없습니다.", "인라인 변수는 C++17 기능입니다.", + "destroying operator delete에는 첫 번째 매개 변수로 %t이(가) 필요합니다.", + "destroying operator delete는 std::size_t 및 std::align_val_t 이외의 매개 변수를 가질 수 없습니다.", "낮은 수준의 추상 클래스 옵션은 C++를 컴파일할 경우에만 사용할 수 있습니다.", "requires 절에서 식의 시작이 잘못되었습니다.", "requires 절의 캐스트 식은 괄호로 묶어야 합니다.", @@ -3250,7 +3252,7 @@ "개념 템플릿", "requires 절이 %nfd과(와) 호환되지 않습니다.", "특성이 필요합니다.", - "요구 사항의 시작이 잘못되었습니다.", + null, "형식 이름이 필요합니다.", "requires 식에는 가변 매개 변수(...)를 사용할 수 없습니다.", "requires 식의 명명되지 않은 매개 변수는 영향을 주지 않습니다.", @@ -3274,14 +3276,14 @@ "모듈 파일", "모듈 %sq의 모듈 파일을 찾을 수 없습니다.", "모듈 파일 %sq을(를) 가져올 수 없습니다.", - "%s1 모듈 파일이 필요한데 %s2 모듈 파일이 발견되었습니다.", + "%s1이(가) 필요한데, %s2이(가) 발견되었습니다.", "%sq 모듈 파일을 열 때", "알 수 없는 파티션 이름 %sq", - "알 수 없음", - "가져올 수 있는 헤더", - "EDG", - "IFC", - "예기치 않음", + "알 수 없는 모듈 파일", + "가져올 수 있는 헤더 모듈 파일", + "EDG 모듈 파일", + "IFC 모듈 파일", + "예기치 않은 모듈 파일", "두 번째 피연산자 %t2의 형식은 %t1과(와) 크기가 같아야 합니다.", "형식은 일반적으로 복사할 수 있어야 합니다.", "%t 형식은 현재 __builtin_bit_cast의 constexpr 평가에서 지원되지 않습니다.", @@ -3293,9 +3295,31 @@ "생성자를 상속하기 위해 %t의 하위 개체를 생성할 수 없습니다. 암시적 기본 생성자가 삭제됩니다.", "%n은(는) void를 반환해야 합니다.", "잘못된 멤버 선언 시작", - "'자동' 필요", + "'auto'가 필요합니다.", "이 시점에 이 연산자를 사용할 수 없습니다. 앞의 새 식을 괄호로 묶으세요.", "잘못된 개념 사용", "기본 멤버 비교 연산자는 '&&'-qualified일 수 없습니다.", - "기본 constexpr 비교 함수에서 비 constexpr 함수 %nd 호출" + "기본 constexpr 비교 함수에서 비 constexpr 함수 %nd 호출", + "constexpr 메모리 비교는 최상위 정수 또는 정수 배열 개체에 대해서만 지원됩니다.", + "개념 템플릿에는 관련된 제약 조건이 있을 수 없습니다.", + "'export'는 허용되지 않습니다.", + "개별 클래스 멤버를 내보낼 수 없습니다.", + "내보낸 선언은 이름이 있어야 합니다.", + "내보내기 선언은 내보내기 선언(이전 선언 %p)을 포함할 수 없습니다.", + "내보내기 선언은 모듈 가져오기 선언을 포함할 수 없습니다.", + "내보내기 선언은 모듈 인터페이스 단위에만 나타날 수 있습니다.", + "내보내기 선언은 내부 링크가 있는 이름을 내보낼 수 없습니다.", + "using 선언에 %nfd가 포함되어 있습니다.", + "__fp16 부동 소수점 형식이 지원되지 않으므로 기본 제공 함수를 사용할 수 없습니다.", + "requires 식은 하나 이상의 요구 사항을 지정해야 합니다.", + "'constinit'는 여기에 유효하지 않습니다.", + "'constinit'는 정적 또는 스레드 저장 기간을 사용하는 변수 선언에만 유효합니다.", + "constinit 변수에는 동적 초기화가 필요합니다.", + "변수가 이전에 'constinit' %p(으)로 선언되었습니다.", + "프로토타입 함수가 아닌 함수 선언자를 사용합니다.", + "인수에는 const 한정 형식을 사용할 수 없습니다.", + "불완전한 형식 %t의 멤버 포인터는 사용할 수 없습니다.", + "init-capture의 팩 확장은 이 모드에서 사용할 수 없습니다.", + "init-capture의 팩 확장은 C++20 기능입니다.", + "클래스 정의의 기본 비교 연산자는 해당 비교 연산자(%nd)의 첫 번째 선언이어야 합니다." ] \ No newline at end of file diff --git a/Extension/bin/messages/pl/messages.json b/Extension/bin/messages/pl/messages.json index ffaff1de97..4e2d0b4eef 100644 --- a/Extension/bin/messages/pl/messages.json +++ b/Extension/bin/messages/pl/messages.json @@ -1535,7 +1535,7 @@ "nieprawidłowa wartość flagi cannot-redefine", "zduplikowany modyfikator funkcji", "nieprawidłowy znak dla literału char16_t", - "Nie można zastosować makra __LPREFIX do literałów char8_t, char16_t ani char32_t", + null, "nierozpoznana konwencja wywoływania %s. Musi ona być jedną z następujących:", null, null, @@ -3122,7 +3122,7 @@ "przechwycenie wyrażenia *this jest niestandardowe w tym trybie", "prefiks atrybutu „using” zgodny ze specyfikacją C++17 jest niestandardowy w tym trybie", "zagnieżdżone przestrzenie nazw zgodne ze specyfikacją C++17 są niestandardowe w tym trybie", - "słowa kluczowe „constexpr” i „consteval” nie mogą występować razem w deklaracji", + "tylko jeden element „constexpr, „consteval” i „constinit” może występować w deklaracji", "funkcja nie może być jednocześnie zadeklarowana jako consteval i virtual w tym trybie", "słowo kluczowe „consteval” jest niedozwolone dla jawnej dyrektywy tworzenia wystąpienia", "słowo kluczowe „consteval” nie jest prawidłowe w tym miejscu", @@ -3166,7 +3166,7 @@ "atrybut „internal_linkage” nie pojawił się we wcześniejszej deklaracji", "nie znaleziono zdatnego kandydata wnioskowania argumentu szablonu dla elementu %n", "wywołanie w pełni kwalifikowanego konstruktora jest niedozwolone", - "operator porównania może być tylko domyślny w definicji klasy", + "przyjęty domyślnie operator porównania musi być składową lub elementem zaprzyjaźnionym klasy, do której ma zastosowanie", "nieprawidłowy typ %t parametru domyślnego operatora porównania (wymagany jest typ „reference to const X”, gdzie X jest typem klasy otaczającej)", "zwracanym typem domyślnego operatora porównania musi być „bool”", "domyślny operator porównania elementu członkowskiego musi mieć wartość „const”", @@ -3233,6 +3233,8 @@ "element co_await można zastosować tylko do instrukcji for opartej na zakresie", "nie można wywnioskować typu zakresu w pętli „for” opartej na zakresie.", "zmienne wbudowane to funkcja języka C++ 17", + "niszczący operator delete wymaga elementu %t jako pierwszego parametru", + "niszczący operator delete nie może mieć parametrów innych niż std::size_t i std::align_val_t", "opcje swobodnej klasy abstrakcyjnej mogą być używane tylko podczas kompilowania kodu C++", "nieprawidłowy początek wyrażenia w klauzuli requires", "wyrażenie rzutowania w klauzuli requires musi być ujęte w nawiasy", @@ -3250,7 +3252,7 @@ "szablon koncepcji", "klauzula requires jest niezgodna z elementem %nfd", "oczekiwano atrybutu", - "nieprawidłowy początek wymagania", + null, "oczekiwano nazwy typu", "parametr wielokropka nie jest dozwolony w wyrażeniu requires", "parametr bez nazwy wyrażeniu requires nie ma żadnego wpływu", @@ -3274,14 +3276,14 @@ "plik modułu", "nie można odnaleźć pliku modułu dla modułu %sq", "nie można zaimportować pliku modułu %sq", - "oczekiwano pliku modułu %s1, a zamiast tego znaleziono plik modułu %s2", + "oczekiwano elementu %s1, zamiast niego znaleziono element %s2", "podczas otwierania pliku modułu %sq", "nieznana nazwa partycji %sq", - "nieznany", - "nagłówek, który można zaimportować", - "element EDG", - "obiekt IFC", - "nieoczekiwany", + "nieznany plik modułu", + "plik modułu z importowalnym nagłówkiem", + "plik modułu EDG", + "plik modułu IFC", + "nieoczekiwany plik modułu", "typ drugiego operandu %t2 musi mieć taki sam rozmiar jak element %t1", "typ musi być możliwy do skopiowania w prosty sposób", "typ %t nie jest obecnie obsługiwany na potrzeby oceny wyrażenia constexpr dla elementu __builtin_bit_cast", @@ -3293,9 +3295,31 @@ "nie można wykonać konstrukcji podobiektu %t na potrzeby dziedziczenia konstruktorów — niejawny konstruktor domyślny został usunięty", "Element %n musi zwracać wartość void", "nieprawidłowy początek deklaracji członkowskiej", - "oczekiwano wartości „auto”", + "oczekiwano elementu „auto”", "ten operator jest niedozwolony w tym miejscu; umieść w nawiasie poprzednie nowe wyrażenie", "nieprawidłowe użycie koncepcji", "domyślny operator porównania elementu członkowskiego nie może być kwalifikowany przez element „&&”", - "domyślna funkcja porównywania constexpr wywołuje funkcję non-constexpr %nd" + "domyślna funkcja porównywania constexpr wywołuje funkcję non-constexpr %nd", + "Porównywanie pamięci constexpr jest obsługiwane tylko w przypadku obiektów najwyższego poziomu w postaci liczby całkowitej lub obiektów typu tablica liczb całkowitych", + "z szablonem koncepcji nie mogą być skojarzone ograniczenia", + "Polecenie „export” jest niedozwolone", + "eksportowanie pojedynczych elementów członkowskich klasy jest niedozwolone", + "wyeksportowana deklaracja musi wprowadzić nazwę", + "deklaracja eksportu nie może zawierać deklaracji eksportu (poprzednia deklaracja %p)", + "deklaracja eksportu nie może zawierać deklaracji importu modułu", + "deklaracja eksportu może występować tylko w jednostce interfejsu modułu", + "deklaracja eksportu nie może eksportować nazwy z powiązaniem wewnętrznym", + "deklaracja using zawiera %nfd", + "funkcja wbudowana jest niedostępna, ponieważ typy liczb zmiennoprzecinkowych __fp16 nie są obsługiwane", + "wyrażenie requires musi określać co najmniej jedno wymaganie", + "słowo kluczowe „constinit” nie jest tutaj prawidłowe", + "element „constinit” jest prawidłowy tylko w deklaracjach zmiennych z czasem trwania magazynowania statycznym lub wątku", + "Zmienna constinit wymaga inicjowania dynamicznego", + "zmienna została wcześniej zadeklarowana za pomocą elementu „constinit” %p", + "Używanie nieprototypowego deklaratora funkcji", + "argument nie może mieć typu kwalifikowanego jako const", + "wskaźnik do składowej niepełnego typu %t jest niedozwolony", + "rozszerzenie pakietu w funkcji init-capture nie jest włączone w tym trybie", + "rozszerzenie pakietu w funkcji init-capture to funkcja języka C++20", + "operator porównania przyjęty domyślnie w definicji klasy musi być pierwszą deklaracją tego operatora porównania (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/pt-br/messages.json b/Extension/bin/messages/pt-br/messages.json index 7181ca7f99..9dd9710960 100644 --- a/Extension/bin/messages/pt-br/messages.json +++ b/Extension/bin/messages/pt-br/messages.json @@ -1535,7 +1535,7 @@ "valor de não pode definir novamente inválido", "modificador de função duplicado", "caractere inválido para literal char16_t", - "O __LPREFIX não pode ser aplicado aos literais char8_t, char16_t ou char32_t", + null, "convenção de chamadas não reconhecida %s, deve ser um dos:", null, null, @@ -3122,7 +3122,7 @@ "a captura de *this está fora do padrão neste modo", "O atributo 'using' de estilo C++17 está fora do padrão neste modo", "Os namespaces aninhados de estilo C++17 estão fora do padrão neste modo", - "'constexpr' e 'consteval' não podem aparecer juntos em uma declaração", + "somente uma das opções: 'constexpr', 'consteval' e 'constinit' pode aparecer em uma declaração", "uma função não pode ser tanto consteval quanto virtual neste modo", "'consteval' não é permitido em uma diretiva explícita de instanciação", "'consteval' não é válido aqui", @@ -3166,7 +3166,7 @@ "o atributo 'internal_linkage' não apareceu em uma declaração anterior", "não foi encontrado nenhum candidato viável à dedução de argumento de modelo para %n", "uma chamada de construtor totalmente qualificada não é permitida", - "um operador de comparação pode ser usado como padrão somente em uma definição de classe", + "um operador de comparação usado como padrão precisa ser um membro ou um friend da classe à qual se aplica", "tipo incorreto %t para o parâmetro do operador de comparação usado como padrão (precisa ser 'referência à const X', em que X é o tipo de classe delimitadora)", "o tipo de retorno do operador de comparação usado como padrão precisa ser 'bool'", "um operador de comparação de membros usado como padrão precisa ser 'const'", @@ -3233,6 +3233,8 @@ "co_await pode ser aplicado somente a uma instrução 'for' baseada em intervalos", "não é possível deduzir o tipo de intervalo no loop 'for' com base em intervalos", "as variáveis embutidas são um recurso do C++17", + "a destruição do operador de exclusão exige %t como primeiro parâmetro", + "a destruição de um operador de exclusão não pode ter parâmetros diferentes de std::size_t e std::align_val_t", "opções de classe abstrata reduzidas podem ser usadas somente ao compilar C++", "início de expressão inválido na cláusula requires", "uma expressão de conversão em uma cláusula requires precisa estar entre parênteses", @@ -3250,7 +3252,7 @@ "modelo de conceito", "cláusula requires incompatível com %nfd", "um atributo é esperado", - "início de requisito inválido", + null, "um nome de tipo é esperado", "um parâmetro de reticências não é permitido em uma expressão requires", "o parâmetro sem nome na expressão requires não tem efeito", @@ -3274,14 +3276,14 @@ "arquivo de módulo", "não foi possível localizar o arquivo de módulo para o módulo %sq", "não foi possível importar o arquivo de módulo %sq", - "o arquivo de módulo %s1 era esperado; em vez dele, foi encontrado o arquivo de módulo %s2", + "era esperado %s1, foi encontrado %s2", "ao abrir o arquivo de módulo %sq", "nome de partição desconhecido %sq", - "um desconhecido", - "um cabeçalho importável", - "um EDG", - "um IFC", - "um inesperado", + "um arquivo de módulo desconhecido", + "um arquivo de módulo de cabeçalho importável", + "um arquivo de módulo EDG", + "um arquivo de módulo IFC", + "um arquivo de módulo inesperado", "o tipo do segundo operando %t2 precisa ter o mesmo tamanho que %t1", "o tipo precisa ser fácil de ser copiado", "no momento, não há suporte para o tipo %t para a avaliação constexpr de __builtin_bit_cast", @@ -3293,9 +3295,31 @@ "a construção de subobjeto de %t para construtores herdados não pode ser executada. O construtor padrão implícito foi excluído", "%n precisa retornar nulo", "declaração de início de membro inválida", - "'auto' esperado", + "'auto' era esperado", "este operador não é permitido neste ponto; coloque parênteses na nova expressão anterior", "uso inválido do conceito", "um operador de comparação de membros usado como padrão não pode ser qualificado por '&&'", - "a função de comparação constexpr padrão chama a função não constexpr %nd" + "a função de comparação constexpr padrão chama a função não constexpr %nd", + "só há suporte para a comparação de memória constexpr para os objetos inteiros de nível superior ou matriz de inteiro", + "um modelo de conceito não pode ter restrições associadas", + "'export' não é permitido", + "a exportação de membros de classe individuais não é permitida", + "uma declaração exportada precisa introduzir um nome", + "uma declaração export não pode conter uma declaração export (declaração anterior %p)", + "uma declaração de exportação não pode conter uma declaração de importação de módulo", + "uma declaração export só pode aparecer em uma unidade de interface de módulo", + "uma declaração export não pode exportar um nome com vínculo interno", + "a declaração using inclui %nfd", + "a função interna não está disponível porque não há suporte para tipos de ponto flutuante __fp16", + "uma expressão requires precisa especificar pelo menos um requisito", + "'constinit' não é válido aqui", + "'constinit' só é válido para declarações de variáveis com duração de armazenamento estática ou de thread", + "a variável constinit requer uma inicialização dinâmica", + "a variável foi declarada anteriormente com 'constinit' %p", + "uso de declarador de função sem protótipo", + "o argumento não pode ter um tipo qualificado como const", + "um ponteiro para membro de um tipo incompleto %t não é permitido", + "a expansão de pacote em init-capture não está habilitada neste modo", + "a expansão de pacote em init-capture é um recurso do C++20", + "um operador de comparação usado como padrão em uma definição de classe precisa ser a primeira declaração desse operador de comparação (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/ru/messages.json b/Extension/bin/messages/ru/messages.json index 4701665d39..18e89842bf 100644 --- a/Extension/bin/messages/ru/messages.json +++ b/Extension/bin/messages/ru/messages.json @@ -1535,7 +1535,7 @@ "недопустимое значение cannot-redefine", "повторяющийся модификатор функции", "недопустимый знак для литерала char16_t", - "__LPREFIX не может применяться к литералам char8_t, char16_t или char32_t", + null, "нераспознанное соглашение о вызовах %s; необходимо использовать одно из следующих:", null, null, @@ -3122,7 +3122,7 @@ "захват значения *this является нестандартным в этом режиме", "Префикс атрибута using в стиле C++17 является нестандартным в этом режиме", "Вложенные пространства имен в стиле C++17 являются нестандартными в этом режиме", - "constexpr и consteval не могут присутствовать в объявлении вместе", + "в объявлении может использоваться только одно из ключевых слов \"constexpr\", \"consteval\" и \"constinit\"", "в этом режиме функция не может быть consteval и virtual одновременно", "consteval не допускается в директиве явного создания экземпляра", "consteval здесь не допускается", @@ -3166,7 +3166,7 @@ "атрибут \"internal_linkage\" отсутствует в предыдущем объявлении", "Не найдено подходящего кандидата для дедукции аргумента шаблона для %n.", "полный вызов конструктора не допускается", - "оператор сравнения можно использовать по умолчанию только в определении класса", + "оператор сравнения по умолчанию должен быть членом или дружественным классом класса, к которому он применяется", "недопустимый тип %t для параметра оператора сравнения по умолчанию (необходимо указать ссылку на константу X, где X — тип включающего класса)", "необходимо использовать возвращаемый тип оператора сравнения по умолчанию \"bool\"", "необходимо использовать оператор сравнения элемента по умолчанию \"const\"", @@ -3233,6 +3233,8 @@ "co_await можно применить только к оператору for на основе диапазонов.", "Невозможно вывести тип диапазона в цикле for на основе диапазона.", "встроенные переменные — это функция C++17", + "для оператора удаления delete необходимо указать %t в качестве первого параметра", + "оператор удаления delete не может иметь параметров, типы которых отличаются от std::size_t и std::align_val_t", "Нестрогие параметры абстрактного класса можно использовать только при компиляции C++.", "Недопустимое начало выражения в предложении requires", "Выражение приведения в предложении requires должно быть заключено в круглые скобки", @@ -3245,12 +3247,12 @@ "Определение концепции не может находиться в этой области", "Недопустимое повторное объявление %nd", "Не удалось подставить аргументы для идентификатора концепции", - "Концепция имеет значение false", + "концепция имеет значение false", "Использование здесь предложения requires запрещено (не шаблонная функция)", - "Шаблон концепции", + "шаблон концепции", "Предложение requires несовместимо с %nfd", - "требуется атрибут", - "Недопустимое начало требования", + "ожидается атрибут", + null, "Требуется имя типа", "Использование параметра-многоточия в выражении requires запрещено", "Неименованный параметр в выражении requires не оказывает никакого влияния", @@ -3274,14 +3276,14 @@ "файл модуля", "не удалось найти файл модуля для модуля %sq", "не удалось импортировать файл модуля %sq", - "Ожидался файл модуля %s1, вместо него обнаружен файл модуля %s2", + "ожидалось \"%s1\", но было использовано \"%s2\"", "При открытии файла модуля %sq", "Неизвестное имя раздела %sq", - "неизвестный", - "Пригодный для импорта заголовок", - "EDG", - "IFC", - "непредвиденный", + "неизвестный файл модуля", + "импортируемый файл модуля заголовка", + "файл модуля EDG", + "файл модуля IFC", + "непредвиденный файл модуля", "тип второго операнда %t2 должен иметь тот же размер, что и %t1.", "тип должен поддерживать элементарное копирование.", "тип %t сейчас не поддерживается в вычислении constexpr для __builtin_bit_cast.", @@ -3293,9 +3295,31 @@ "невозможно выполнить конструирование подобъекта %t для наследования конструкторов — неявный конструктор по умолчанию удален.", "%n требует возврата void.", "недопустимое начало объявления элемента", - "требуется \"auto\"", + "ожидается \"auto\"", "этот оператор не может использоваться в этом месте; заключите предыдущее выражение new в скобки", "недопустимое использование концепции", "оператор сравнения элемента по умолчанию не может быть квалифицирован как \"&&\"", - "функция сравнения constexpr по умолчанию вызывает функцию %nd, не являющуюся constexpr" + "функция сравнения constexpr по умолчанию вызывает функцию %nd, не являющуюся constexpr", + "Сравнение памяти с помощью constexpr поддерживается только для целочисленных объектов верхнего уровня или массивов целых чисел", + "шаблон концепции не может иметь связанные ограничения", + "использование \"export\" запрещено", + "экспорт отдельных членов класса запрещен", + "экспортированное объявление должно представлять имя", + "объявление экспорта не может содержать объявление экспорта (предыдущее объявление %p)", + "объявление экспорта не может содержать объявление импорта модуля", + "объявление экспорта может находиться только в блоке интерфейса модуля", + "объявление экспорта не может экспортировать имя с внутренней компоновкой", + "объявление using включает %nfd", + "встроенная функция недоступна, так как типы с плавающей запятой __fp16 не поддерживаются", + "в выражении requires должно быть указано по крайней мере одно требование", + "\"constinit\" не может использоваться здесь", + "\"constinit\" может использоваться только для объявлений переменных со сроком хранения в статическом или потоковом хранилище", + "для переменной constinit требуется динамическая инициализация", + "переменная ранее была объявлена с \"constinit\" %p", + "использование объявления функции, не являющегося прототипом", + "аргумент не может иметь тип, квалифицированный как const", + "недопустимый указатель на член неполного типа %t", + "расширение пакета в init-capture не включено в этом режиме", + "расширение пакета в init-capture — это функция C++ 20", + "оператор сравнения по умолчанию в определении класса должен быть первым объявлением этого оператора сравнения (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/tr/messages.json b/Extension/bin/messages/tr/messages.json index 69b2076162..dc565621be 100644 --- a/Extension/bin/messages/tr/messages.json +++ b/Extension/bin/messages/tr/messages.json @@ -1535,7 +1535,7 @@ "yeniden tanımlanamaz değeri geçersiz", "işlev değiştiricisi yineleniyor", "char16_t sabit değeri için geçersiz karakter", - "__LPREFIX, char8_t, char16_t veya char32_t sabit değerlerine uygulanamıyor", + null, "çağrı kuralı %s tanınmıyor, şunlardan biri olmalıdır:", null, null, @@ -3122,7 +3122,7 @@ "* yakalama bu modda standart dışı", "C++17 stili 'using' öznitelik ön eki bu modda standart dışı", "C++17 stili iç içe geçmiş ad alanları bu modda standart dışı", - "'constexpr' ve 'consteval' bir bildirimde birlikte bulunamaz", + "bir bildirimde yalnızca bir 'constexpr', 'consteval' ve 'constinit' görünebilir", "bu modda bir işlev hem consteval hem de sanal olamaz", "Açık örnek oluşturma yönergesinde 'consteval' öğesine izin verilmez", "'consteval' burada geçerli değildir", @@ -3166,7 +3166,7 @@ "'internal_linkage' özniteliği önceki bir bildirimde görünmedi", "%n için uygun bir şablon bağımsız değişkeni çıkarsama adayı bulunamadı", "tam oluşturucu çağrısına izin verilmiyor", - "karşılaştırma işleci yalnızca sınıf tanımında varsayılan olarak ayarlanabilir", + "varsayılan olarak kullanılan karşılaştırma işleci, uygulandığı sınıfın bir üyesi veya arkadaşı olmalıdır", "varsayılan olarak ayarlanan karşılaştırma işlecinin parametresi için %t türü hatalı ('const X başvurusu' olmalıdır; burada X, kapsayan sınıf türüdür)", "varsayılan olarak ayarlanan karşılaştırma işlecinin dönüş türü 'bool' olmalıdır", "varsayılan olarak ayarlanan üye karşılaştırma işleci 'const' olmalıdır", @@ -3233,6 +3233,8 @@ "co_await yalnızca aralık tabanlı for deyimine uygulanabilir", "aralık tabanlı 'for' döngüsündeki aralık türü çıkarsanamıyor", "satır içi değişkenler bir C++17 özelliğidir", + "yok etme işleci silme işlemi birinci parametre olarak %t gerektirir", + "yok etme işleci silme, std::size_t ve std::align_val_t dışında parametrelere sahip olamaz", "kısıtlanmamış soyut sınıf seçenekleri yalnızca C++ derlenirken kullanılabilir", "requires yan tümcesindeki ifadenin başlangıcı geçersiz", "requires yan tümcesindeki tür dönüştürme ifadesi ayraç içine alınmalıdır", @@ -3250,7 +3252,7 @@ "kavram şablonu", "requires yan tümcesi %nfd ile uyumsuz", "öznitelik bekleniyordu", - "geçersiz gereksinim başlangıcı", + null, "tür adı bekleniyordu", "requires ifadesinde üç nokta parametresine izin verilmez", "requires ifadesindeki adlandırılmamış parametrenin etkisi yok", @@ -3274,28 +3276,50 @@ "modül dosyası", "%sq modülü için modül dosyası bulunamadı", "%sq modül dosyası içeri aktarılamadı", - "%s1 modül dosyası bekleniyordu ancak bunun yerine %s2 modül dosyası bulundu", + "%s1 bekleniyordu ancak bunun yerine %s2 bulundu", "%sq modül dosyası açılırken", "%sq bölüm adı bilinmiyor", - "bilinmeyen", - "İçeri aktarılabilen üst bilgi", - "EDG", - "IFC", - "beklenmeyen", + "bilinmeyen bir modül dosyası", + "içeri aktarılabilir üst bilgi modülü dosyası", + "EDG modülü dosyası", + "IFC modülü dosyası", + "beklenmeyen bir modül dosyası", "%t2 ikinci işlenenin türü, %t1 ile aynı boyutta olmalıdır", "tür, üç yana kopyalanabilir olmalıdır", "%t türü şu anda __builtin_bit_cast constexpr değerlendirmesi için desteklenmiyor", "Bitfields %t sahip sınıf türleri, __builtin_bit_cast constexpr değerlendirmesi için şu anda desteklenmiyor", "başvuru türündeki statik olmayan veri üyesi __builtin_bit_cast %t constexpr değerlendirmesi yapılmasını engelliyor", "geçici tür %t __builtin_bit_cast constexpr değerlendirmesi yapılmasını engelliyor", - "bir Union, işaretçi veya üye işaretçisi türü %t __builtin_bit_cast constexpr değerlendirmesine engel olur", + "bir %t türü birleşim, işaretçi veya üye işaretçisi __builtin_bit_cast constexpr değerlendirmesine engel oluyor", "%npT (decl %p kullanılarak devralındı)", "devralma oluşturucuları için %t alt nesne oluşturma gerçekleştirilemiyor; örtük varsayılan Oluşturucu silindi", "%n void döndürmesi gerekir", "üye bildiriminin başlangıcı geçersiz", - "'auto' bekleniyor", + "'auto' bekleniyordu", "bu işlece bu noktada izin verilmiyor; önceki yeni ifadeyi parantez içine alın", "kavram kullanımı geçersiz", "varsayılan olarak ayarlanan üye karşılaştırma işleci tam '&&' ile nitelenemez", - "varsayılan constexpr karşılaştırma işlevi constexpr olmayan %nd işlevini çağırıyor" + "varsayılan constexpr karşılaştırma işlevi constexpr olmayan %nd işlevini çağırıyor", + "constexpr bellek karşılaştırması yalnızca üst düzey tamsayı veya tamsayı dizisi nesneleri için desteklenir", + "kavram şablonunda ilişkili kısıtlamalar olamaz", + "'export'a izin verilmiyor", + "sınıf üyelerini tek tek dışarı aktarmaya izin verilmiyor", + "dışarı aktarılan bildirim bir ad tanıtmalıdır", + "dışarı aktarma bildirimi, dışarı aktarma bildirimi içeremez (önceki bildirim %p)", + "dışarı aktarma bildirimi, modül içeri aktarma bildirimi içeremez", + "dışarı aktarma bildirimi yalnızca modül arabirim ünitesinde görünebilir", + "dışarı aktarma bildirimi, iç bağlantıya sahip bir adı dışarı aktaramaz", + "Kullanılan bildirim %nfd içeriyor", + "__fp16 kayan nokta türleri desteklenmediği için yerleşik işlev kullanılamıyor", + "requires ifadesi en az bir gereksinim belirtmelidir", + "'constinit' burada geçerli değil", + "'constinit' yalnızca statik veya iş parçacığı depolama süresine sahip değişkenlerin bildirimleri için geçerlidir", + "constinit değişkeni dinamik başlatma gerektiriyor", + "değişken daha önceden 'constinit' %p ile bildirildi", + "prototip olmayan işlev bildiricisi kullanımı", + "bağımsız değişken const olarak nitelenmiş bir türe sahip olamaz", + "eksik tür %t için işaretçiden üyeye öğesine izin verilmez", + "init-capture içinde paket genişletme bu modda etkin değil", + "init-capture özelliğindeki paket genişletme bir C++ 20 özelliğidir", + "sınıf tanımında varsayılan olarak kullanılan bir karşılaştırma işleci, ilgili karşılaştırma işlecinin ilk bildirimi olmalıdır (%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/zh-CN/messages.json b/Extension/bin/messages/zh-CN/messages.json index 9f6336a20c..d03cc7bbf9 100644 --- a/Extension/bin/messages/zh-CN/messages.json +++ b/Extension/bin/messages/zh-CN/messages.json @@ -1535,7 +1535,7 @@ "cannot-redefine 值无效", "重复的函数修饰符", "char16_t 文本的无效字符", - "__LPREFIX 不可应用于 char8_t、char16_t 或 char32_t 文本", + null, "无法识别的调用约定 %s,必须为以下内容之一:", null, null, @@ -3122,7 +3122,7 @@ "正在捕获 *这在此模式中是非标准的", "C++17 样式 \"using\" 属性前缀在此模式中是非标准的", "C++17 样式嵌套命名空间在此模式中是非标准的", - "\"constexpr\" 和 \"consteval\" 不能同时出现在声明中", + "声明中只能出现 \"constexpr\"、\"consteval\" 和 \"constinit\" 中的一个", "在此模式下,函数不能同时为 consteval 和 virtual", "不允许对显式实例化指令使用 \"consteval\"", "\"consteval\" 在此处无效", @@ -3166,7 +3166,7 @@ "\"internal_linkage\" 属性未出现在之前的声明中", "未找到 %n 的可行模板参数推导候选项", "不允许使用完全限定的构造函数调用", - "仅可在类定义中将比较运算符设为默认值", + "默认比较运算符必须是它适用于的类的成员或友元", "默认比较运算符的参数的类型 %t 不正确(必须是“对 const X 的引用”,其中 X 是封闭类类型)", "默认比较运算符的返回类型必须是 \"bool\"", "默认成员比较运算符必须为 \"const\"", @@ -3233,6 +3233,8 @@ "co_await 只能应用到基于范围的 for 语句", "无法在基于范围的 \"for\" 循环中推断范围类型", "内联变量是 C++17 功能", + "销毁运算符 delete 需要 %t 作为第一个参数", + "销毁运算符 delete 不能具有 std::size_t 和 std::align_val_t 以外的参数", "宽松抽象类选项只能在编译 C++ 时使用", "requires 子句中表达式的开头无效", "requires 子句中的强制转换表达式必须放在括号中", @@ -3250,7 +3252,7 @@ "概念模板", "requires 子句与 %nfd 不兼容", "预期特性", - "要求的开头无效", + null, "预期类型名称", "requires 表达式中不允许使用省略号参数", "requires 表达式中未命名的参数不起任何作用", @@ -3274,18 +3276,18 @@ "模块文件", "找不到模块 %sq 的模块文件", "无法导入模块文件 %sq", - "预期 %s1 模块文件,但找到 %s2 模块文件", + "预期 %s1,但找到 %s2", "打开模块文件 %sq 时", "未知的分区名称 %sq", - "未知", - "可导入标头", - "EDG", - "IFC", - "非预期", + "未知模块文件", + "可导入标头模块文件", + "EDG 模块文件", + "IFC 模块文件", + "意外的模块文件", "第二个操作数的类型 %t2 必须与 %t1 大小相同", "类型必须可轻松复制", "类型 %t 当前不支持对 __builtin_bit_cast 进行 constexpr 计算", - "位域为 %t 的类类型不支持对 __builtin_bit_cast 进行 constexpr 计算", + "位域为 %t 的类类型当前不支持对 __builtin_bit_cast 进行 constexpr 计算", "引用类型 %t 的非静态数据成员阻止对 __builtin_bit_cast 进行 constexpr 计算", "易失类型 %t 阻止对 __builtin_bit_cast 进行 constexpr 计算", "联合类型、指针类型或指向成员的指针类型 %t 阻止对 __builtin_bit_cast 进行 constexpr 计算", @@ -3297,5 +3299,27 @@ "此位置不允许使用此运算符;请前面的新表达式括起来", "概念的使用无效", "默认成员比较运算符不能是 \"&&\" 限定", - "默认的 constexpr 比较函数会调用非 constexpr 函数 %nd" + "默认的 constexpr 比较函数会调用非 constexpr 函数 %nd", + "只有顶级整数或数组整数对象支持 constexpr 内存比较", + "概念模板不能具有关联约束", + "不允许使用 \"export\"", + "不允许导出单个类成员", + "导出的声明必须引入名称", + "导出声明不能包含导出声明(以前的声明 %p)", + "导出声明不能包含模块导入声明", + "导出声明只能出现在模块接口单元中", + "导出声明无法导出具有内部链接的名称", + "using 声明包括 %nfd", + "内置函数不可用,因为不支持 __fp16 浮点类型", + "requires 表达式必须指定至少一个要求", + "\"constinit\" 在此处无效", + "\"constinit\" 仅对具有静态或线程存储持续时间的变量的声明有效", + "constinit 变量需要动态初始化", + "以前使用 \"constinit\" %p 声明了变量", + "使用非原型函数声明符", + "参数不能具有常量限定类型", + "不允许使用不完整类型 %t 的指向成员的指针", + "此模式下未启用 init-capture 中的包扩展", + "init-capture 中的包扩展是 C++ 20 功能", + "类定义中默认的比较运算符必须是该比较运算符的第一个声明(%nd)" ] \ No newline at end of file diff --git a/Extension/bin/messages/zh-TW/messages.json b/Extension/bin/messages/zh-TW/messages.json index 1bf259d38b..fa513765b0 100644 --- a/Extension/bin/messages/zh-TW/messages.json +++ b/Extension/bin/messages/zh-TW/messages.json @@ -1535,7 +1535,7 @@ "無法重新定義的值無效", "函式修飾元重複", "char16_t literal 的字元無效", - "__LPREFIX 無法套用至 char8_t、char16_t 或 char32_t 常值", + null, "無法辨認的呼叫慣例 %s,必須是下列其中一個: ", null, null, @@ -3122,7 +3122,7 @@ "在此模式中擷取 *這個不是標準用法", "在此模式中 C++17 樣式的 'using' 屬性前置詞不是標準用法", "在此模式中 C++17 樣式的巢狀命名空間不是標準用法", - "'constexpr' 和 'consteval' 不能同時出現在宣告中", + "只有 'constexpr'、'consteval' 或 'constinit' 其中之一可以出現宣告上", "在此模式中函式不可同時為 consteval 和 virtual", "明確具現化指示詞中不允許 'consteval'", "'consteval' 在這裡無效", @@ -3166,7 +3166,7 @@ "'internal_linkage' 屬性未出現在前一個宣告上", "找不到 %n 的任何可行範本引數推算候選", "不允許完整的建構函式呼叫", - "比較運算子只有在類別定義中才能是預設", + "預設比較運算子必須是其所套用之類別的成員或 Friend", "預設比較運算子參數的類型 %t 不正確 (必須是 'reference to const X',其中 X 是外層類別類型)", "預設比較運算子的傳回型別必須是 'bool'", "預設的成員比較運算子必須是 'const'", @@ -3233,6 +3233,8 @@ "co_await 只能套用至範圍架構 for 陳述式", "無法推算範圍架構 'for' 迴圈中的範圍類型", "內嵌變數為 C++17 功能", + "終結運算子 Delete 需要 %t 作為第一個參數", + "終結運算子 Delete 不能有除了 std::size_t 與 std::align_val_t 的參數", "寬鬆抽象類別選項只有在編譯 C++ 時才能使用", "requires 子句中運算式的開頭無效", "requires 子句中的 cast 運算式必須以括號括住", @@ -3245,12 +3247,12 @@ "概念定義不能出現在此範圍中", "%nd 的重新宣告無效", "概念識別碼的引數替代失敗", - "概念為 false", + "概念為 False", "此處不允許使用 requires 子句 (非樣板化函式)", "概念範本", "requires 子句與 %nfd 不相容", - "必須為屬性名稱", - "需求的開頭無效", + "必須是屬性", + null, "必須為類型名稱", "requires 運算式中不允許使用省略符號參數", "requires 運算式中未命名的參數沒有作用", @@ -3274,14 +3276,14 @@ "模組檔案", "找不到模組 %sq 的模組檔案", "無法匯入模組檔案 %sq", - "必須為 %s1 模組檔案,但找到 %s2 模組檔案", + "必須為 %s1,但找到 %s2", "在開啟模組檔案 %sq 時", "未知的分割名稱 %sq", - "未知的", - "可匯入的標頭", - "EDG", - "IFC", - "未預期的", + "未知的模組檔案", + "可匯入的標頭模組檔案", + "EDG 模組檔案", + "IFC 模組檔案", + "未預期的模組檔案", "第二個運算元 %t2 的類型必須與 %t1 的大小相同", "類型必須可以原樣複製", "__builtin_bit_cast 的 constexpr 評估目前不支援類型 %t", @@ -3293,9 +3295,31 @@ "無法執行用於繼承建構函式的 %t 子物件建構 -- 已刪除隱含的預設建構函式", "%n 必須傳回 void", "成員宣告開頭無效", - "必須為 'auto'", + "必須是 'auto'", "目前不允許此運算子; 請以括號括住前面的 new 運算式", "概念使用無效", "預設的成員比較運算子不可限定為 '&&'", - "預設 constexpr 比較函式會呼叫非 constexpr 函式 %nd" + "預設 constexpr 比較函式會呼叫非 constexpr 函式 %nd", + "只有最上層整數或整數陣列物件支援 constexpr 記憶體比較", + "概念範本不能具有已建立關聯的條件約束", + "不允許 'export'", + "不允許匯出個別類別成員", + "匯出的宣告必須引入名稱", + "匯出宣告不能包含匯出宣告 (前一個宣告 %p)", + "匯出宣告不能包含模組匯入宣告", + "匯出宣告只能出現在模組介面單位中", + "匯出宣告不能匯出具有內部連結的名稱", + "using 宣告包含 %nfd", + "因為不支援 __fp16 浮點數類型,所以無法使用內建函式", + "Requires 運算式必須至少指定一個需求", + "'constinit' 在這裡無效", + "'constinit' 只對具有靜態或執行緒儲存期的變數宣告有效", + "constinit 變數需要進行動態初始化", + "變數先前使用 'constinit' %p 宣告", + "使用非原型函式宣告子", + "引數不能有常數限定類型", + "不允許使用不完整類型 %t 的成員指標", + "此模式未啟用 init-capture 中的參數序列展開式", + "init-capture 中的參數序列展開式是 C++20 功能", + "類別定義中預設的比較運算子,必須為該比較運算子的第一個宣告 (%nd)" ] \ No newline at end of file diff --git a/Extension/c_cpp_properties.schema.json b/Extension/c_cpp_properties.schema.json index 723c107ee4..d3546407a1 100644 --- a/Extension/c_cpp_properties.schema.json +++ b/Extension/c_cpp_properties.schema.json @@ -145,7 +145,7 @@ }, "customConfigurationVariables": { "type": "object", - "description": "Custom variables that can be queried through the command ${cpptools:activeConfigCustomVariable} to use for the input variables in launch.json.", + "description": "Custom variables that can be queried through the command ${cpptools:activeConfigCustomVariable} to use for the input variables in launch.json or tasks.json.", "patternProperties": { "(^.+$)": { "type": "string" diff --git a/Extension/gulpfile.js b/Extension/gulpfile.js index 3213700baa..4c41a0dfa8 100644 --- a/Extension/gulpfile.js +++ b/Extension/gulpfile.js @@ -444,36 +444,49 @@ gulp.task("generate-native-strings", (done) => { let stringIndex = 1; for (let property in stringTable) { - let stringName = property; let stringValue = stringTable[property]; + let hintValue; + if (typeof stringValue !== "string") + { + hintValue = stringValue.hint; + stringValue = stringValue.text; + } // Add to native enum nativeEnumContent += ` ${property} = ${stringIndex},\n`; // Add to native string table - nativeStringTableContent += ` ${JSON.stringify(stringTable[property])},\n`; + nativeStringTableContent += ` ${JSON.stringify(stringValue)},\n`; // Add to TypeScript switch // Skip empty strings, which can be used to prevent enum/index reordering - if (stringTable[property] != "") { - // It's possible that a translation may skip "{#}" entries, so check for up to 20 of them. + if (stringValue != "") { + // It's possible that a translation may skip "{#}" entries, so check for up to 50 of them. let numArgs = 0; - for (let i = 0; i < 20; i++) { + for (let i = 0; i < 50; i++) { if (stringValue.includes(`{${i}}`)) { numArgs = i + 1; } } typeScriptSwitchContent += ` case ${stringIndex}:\n`; if (numArgs != 0) { - typeScriptSwitchContent += ` if (!stringArgs) {\n`; - typeScriptSwitchContent += ` break;\n`; - typeScriptSwitchContent += ` }\n`; + typeScriptSwitchContent += ` if (stringArgs) {\n`; + if (hintValue) { + typeScriptSwitchContent += ` message = localize({ key: ${JSON.stringify(property)}, comment: [${JSON.stringify(hintValue)}] }, ${JSON.stringify(stringValue)}`; + } else { + typeScriptSwitchContent += ` message = localize(${JSON.stringify(property)}, ${JSON.stringify(stringValue)}`; + } + for (let i = 0; i < numArgs; i++) { + typeScriptSwitchContent += `, stringArgs[${i}]`; + } + typeScriptSwitchContent += `);\n break;\n }\n`; } - typeScriptSwitchContent += ` message = localize(${JSON.stringify(property)}, ${JSON.stringify(stringTable[property])}`; - for (let i = 0; i < numArgs; i++) { - typeScriptSwitchContent += `, stringArgs[${i}]`; + if (hintValue) { + typeScriptSwitchContent += ` message = localize({ key: ${JSON.stringify(property)}, comment: [${JSON.stringify(hintValue)}] }, ${JSON.stringify(stringValue)}`; + } else { + typeScriptSwitchContent += ` message = localize(${JSON.stringify(property)}, ${JSON.stringify(stringValue)}`; } - typeScriptSwitchContent += ");\n break;\n"; + typeScriptSwitchContent += `);\n break;\n`; } ++stringIndex; }; @@ -492,6 +505,8 @@ import * as nls from 'vscode-nls'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); +export const localizedStringCount: number = ${stringIndex}; + export function lookupString(stringId: number, stringArgs?: string[]): string { let message: string = ""; switch (stringId) { @@ -518,7 +533,7 @@ ${typeScriptSwitchContent} #pragma once -enum class localized_string_id +enum class localized_string_id : unsigned int { blank = 0, ${nativeEnumContent}}; diff --git a/Extension/i18n/chs/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/chs/c_cpp_properties.schema.json.i18n.json index 9c0024c773..0b02713358 100644 --- a/Extension/i18n/chs/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/chs/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "如果为 true,则仅处理以标头形式直接或间接包含的文件;如果为 false,则处理指定的包含路径下的所有文件。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "所生成的符号数据库的路径。如果指定了相对路径,则它将相对于工作区的默认存储位置。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "标记分析器在搜索包含的标头时要使用的路径列表。默认情况下,按递归方式搜索这些路径。指定 \"*\" 可指示非递归搜索。例如: \"/usr/include\" 将搜索所有子目录,而 \"/usr/include/*\" 将不搜索所有子目录。", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "可通过命令 ${cpptools:activeConfigCustomVariable} 查询要用于 launch.json 或 tasks.json 的输入变量的自定义变量。", "c_cpp_properties.schema.json.definitions.env": "可通过 ${变量} 或 ${env:变量} 语法在此文件中的任意位置重用的自定义变量。", "c_cpp_properties.schema.json.definitions.version": "配置文件的版本。此属性由扩展托管。请勿更改它。", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "控制扩展是否报告在 c_cpp_properties.json 中检测到的错误。" diff --git a/Extension/i18n/chs/package.i18n.json b/Extension/i18n/chs/package.i18n.json index 22b44f4514..ff8ffec1cb 100644 --- a/Extension/i18n/chs/package.i18n.json +++ b/Extension/i18n/chs/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "未指定 \"browse.limitSymbolsToIncludedHeaders\" 时或将其设置为 \"${default}\" 时要在配置中使用的值。", "c_cpp.configuration.default.systemIncludePath.description": "要用于系统包含路径的值。如果已设置,它会覆盖通过 \"compilerPath\" 和 \"compileCommands\" 设置获取的系统包含路径。", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "控制扩展是否报告在 c_cpp_properties.json 中检测到的错误。", + "c_cpp.configuration.default.customConfigurationVariables.description": "未设置 \"customConfigurationVariables\" 时要在配置中使用的值,或 \"customConfigurationVariables\" 中存在 \"${default}\" 作为键时要插入的值。", "c_cpp.configuration.updateChannel.description": "设置为“预览体验”以自动下载并安装扩展的最新预览体验版本,其中包括即将推出的功能和 bug 修复。", "c_cpp.configuration.experimentalFeatures.description": "控制“实验性”功能是否可用。", "c_cpp.configuration.suggestSnippets.description": "如果为 true,则由语言服务器提供片段。", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "要执行的完全限定的管道命令。", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "传递给管道程序配置连接的命令行参数。", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "传递给程序的环境变量。", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "如果 pipeProgram 的单个参数包含字符(如空格或制表符),是否应引用它? 如果为 \"false\",则将不再自动引用调试程序命令。\n默认为 \"true\"。", "c_cpp.debuggers.logging.description": "用于确定应将哪些类型的消息记录到调试控制台的可选标志。", "c_cpp.debuggers.logging.exceptions.description": "用于确定是否应将异常消息记录到调试控制台的可选标志。默认为 true。", "c_cpp.debuggers.logging.moduleLoad.description": "用于确定是否应将模块加载事件记录到调试控制台的可选标志。默认为 true。", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "用于确定是否应将诊断调试引擎消息记录到调试控制台的可选标志。默认为 false。", "c_cpp.debuggers.logging.trace.description": "用于确定是否应将诊断适配器命令跟踪记录到调试控制台的可选标志。默认为 false。", "c_cpp.debuggers.logging.traceResponse.description": "用于确定是否应将诊断适配器命令和响应跟踪记录到调试控制台的可选标志。默认为 false。", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "用于确定是否应将线程退出消息记录到调试控制台的可选标志。默认值: \"false\"。", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "用于确定是否应将目标进程退出消息记录到调试控制台的可选标志;否则调试停止。默认值: \"true\"。", "c_cpp.debuggers.text.description": "要执行的调试命令。", "c_cpp.debuggers.description.description": "此命令的可选说明。", "c_cpp.debuggers.ignoreFailures.description": "如果为 true,应忽略此命令的失败。默认值为 false。", diff --git a/Extension/i18n/chs/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/chs/src/Debugger/configurationProvider.i18n.json index 5f4f83ea6c..9a50b2111e 100644 --- a/Extension/i18n/chs/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/chs/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "类型为“{0}”的调试程序仅在 Windows 上可用。在当前 OS 平台上使用类型“{1}”。", "lldb.framework.install.xcode": "详细信息", "lldb.framework.not.found": "找不到用于 lldb-mi 的 \"LLDB.framework\"。请安装 XCode 或 XCode 命令行工具。", + "debugger.launchConfig": "启动配置:", "lldb.find.failed": "缺少 lldb-mi 可执行文件的依赖项“{0}”。", "lldb.search.paths": "搜索范围:", "lldb.install.help": "要解决此问题,请通过 Apple App Store 安装 XCode,或通过在终端窗口运行“{0}”来安装 XCode 命令行工具。", diff --git a/Extension/i18n/chs/src/nativeStrings.i18n.json b/Extension/i18n/chs/src/nativeStrings.i18n.json index 7604e66fb4..c255fb4d29 100644 --- a/Extension/i18n/chs/src/nativeStrings.i18n.json +++ b/Extension/i18n/chs/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "未能查询编译器。正在回退到无位数。", "intellisense_client_creation_aborted": "已中止创建 IntelliSense 客户端: {0}", "include_errors_config_provider_intellisense_disabled ": "基于 configurationProvider 设置提供的信息检测到 #include 错误。此翻译单元({0})的 IntelliSense 功能将由标记分析器提供。", - "include_errors_config_provider_squiggles_disabled ": "基于 configurationProvider 设置提供的信息检测到 #include 错误。已针对此翻译单元({0})禁用波形曲线。" + "include_errors_config_provider_squiggles_disabled ": "基于 configurationProvider 设置提供的信息检测到 #include 错误。已针对此翻译单元({0})禁用波形曲线。", + "preprocessor_keyword": "预处理器关键字", + "c_keyword": "C 关键字", + "cpp_keyword": "C++ 关键字", + "overload": "还有 1 个重载", + "overloads": "还有 %d 个重载", + "specialization": "还有 1 个专业化", + "specializations": "还有 %d 个专业化", + "expands_to": "扩展到:", + "file_label": "文件:", + "parameters_label": "参数:", + "returns_label": "返回:", + "deprecated_label": "已弃用:", + "exceptions_label": "异常:" } \ No newline at end of file diff --git a/Extension/i18n/cht/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/cht/c_cpp_properties.schema.json.i18n.json index e68926d449..41402c03f0 100644 --- a/Extension/i18n/cht/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/cht/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "設為 true,就會只處理直接或間接以標頭形式包含的檔案; 設為 false,則會處理位於指定 include 路徑下的所有檔案。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "產生的符號資料庫路徑。如果指定了相對路徑,就會是相對於工作區預設儲存位置的路徑。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "供標籤剖析器在搜尋包含的標頭時使用的路徑清單。根據預設,會在這些路徑進行遞迴搜尋。指定 '*' 來指示非遞迴搜尋。例如: '/usr/include' 會在所有子目錄中搜尋,但 '/usr/include/*' 不會。", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "可透過命令 ${cpptools:activeConfigCustomVariable} 查詢的自訂變數,用於 launch.json 或 tasks.js 的輸入變數。", "c_cpp_properties.schema.json.definitions.env": "可以透過使用 ${變數} 或 ${環境:變數} 語法,在此檔案中任何地方重複使用的自訂變數。", "c_cpp_properties.schema.json.definitions.version": "組態檔版本。此屬性受延伸模組管理,請勿變更。", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "控制延伸模組是否會回報 c_cpp_properties.json 中偵測到的錯誤。" diff --git a/Extension/i18n/cht/package.i18n.json b/Extension/i18n/cht/package.i18n.json index 02e4e45e71..ba9d3f3a20 100644 --- a/Extension/i18n/cht/package.i18n.json +++ b/Extension/i18n/cht/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "當 \"browse.limitSymbolsToIncludedHeaders\" 未指定或設定為 \"${default}\" 時,要在組態中使用的值。", "c_cpp.configuration.default.systemIncludePath.description": "要用於系統包含路徑的值。若設定,會覆寫透過 \"compilerPath\" 和 \"compileCommands\" 設定所取得的系統包含路徑。", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "控制延伸模組是否會回報 c_cpp_properties.json 中偵測到的錯誤。", + "c_cpp.configuration.default.customConfigurationVariables.description": "當未設定 \"customConfigurationVariables\" 時要在組態中使用的值,或當 \"${default}\" 在 \"customConfigurationVariables\" 中顯示為索引鍵時要插入的值。", "c_cpp.configuration.updateChannel.description": "設定為「測試人員」以自動下載並安裝最新的延伸模組測試人員組建 (包括即將推出的功能和更新)。", "c_cpp.configuration.experimentalFeatures.description": "控制「實驗性」功能是否可用。", "c_cpp.configuration.suggestSnippets.description": "若為 true,則由語言伺服器提供程式碼片段。", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "要執行的完整管道命令。", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "傳遞至管道程式以設定連線的命令列引數。", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "傳遞至管道程式的環境變數。", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "若 pipeProgram 的個別引數包含字元 (例如空格或定位字元),是否應該加上引號? 若設定為 'false',不會再自動為偵錯工具命令加上引號。\n預設為 'true'。", "c_cpp.debuggers.logging.description": "選擇性旗標,用以判斷應記錄到偵錯主控台的訊息類型。", "c_cpp.debuggers.logging.exceptions.description": "選擇性旗標,用以判斷是否應將例外狀況訊息記錄到偵錯主控台。預設為 true。", "c_cpp.debuggers.logging.moduleLoad.description": "選擇性旗標,用以判斷是否應將模組載入事件記錄到偵錯主控台。預設為 true。", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "選擇性旗標,用以判斷是否應將診斷偵錯引擎訊息記錄到偵錯主控台。預設為 false。", "c_cpp.debuggers.logging.trace.description": "選擇性旗標,用以判斷是否應將診斷介面卡命令追蹤記錄到偵錯主控台。預設為 false。", "c_cpp.debuggers.logging.traceResponse.description": "選擇性旗標,用以判斷是否應將診斷介面卡命令和回應追蹤記錄到偵錯主控台。預設為 false。", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "選用旗標,可決定是否要將執行緒結束訊息記錄到偵錯主控台。預設: `false`。", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "選用旗標,可決定要將目標流程結束訊息記錄到偵錯主控台,或停止偵錯。預設: `true`。", "c_cpp.debuggers.text.description": "要執行的偵錯工具命令。", "c_cpp.debuggers.description.description": "命令的選擇性描述。", "c_cpp.debuggers.ignoreFailures.description": "若為 true,則應略過來自命令的失敗。預設值為 false。", diff --git a/Extension/i18n/cht/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/cht/src/Debugger/configurationProvider.i18n.json index f578de8169..fd320f0c76 100644 --- a/Extension/i18n/cht/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/cht/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "只能在 Windows 上使用類型為 '{0}' 的偵錯工具。在目前的 OS 平台上使用類型 '{1}'。", "lldb.framework.install.xcode": "更多資訊", "lldb.framework.not.found": "找不到 lldb-mi 的 'LLDB.framework'。請安裝 XCode 或 XCode 命令列工具。", + "debugger.launchConfig": "啟動設定:", "lldb.find.failed": "缺少 lldb-mi 可執行檔的相依性 '{0}'。", "lldb.search.paths": "已在下列位置中搜尋:", "lldb.install.help": "若要解決此問題,請透過 Apple App Store 安裝 XCode,或在終端機視窗中執行 '{0}' 以安裝 XCode 命令列工具。", diff --git a/Extension/i18n/cht/src/nativeStrings.i18n.json b/Extension/i18n/cht/src/nativeStrings.i18n.json index 8d2a6bd0b0..4724eba26e 100644 --- a/Extension/i18n/cht/src/nativeStrings.i18n.json +++ b/Extension/i18n/cht/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "無法查詢編譯器。請回復成沒有位元。", "intellisense_client_creation_aborted": "已中止建立 IntelliSense 用戶端: {0}", "include_errors_config_provider_intellisense_disabled ": "根據 configurationProvider 設定提供的資訊,偵測到 #include 錯誤。此編譯單位 ({0}) 的 IntelliSense 功能將由標籤剖析器提供。", - "include_errors_config_provider_squiggles_disabled ": "根據 configurationProvider 設定提供的資訊,偵測到 #include 錯誤。已停用此編譯單位 ({0}) 的波浪線。" + "include_errors_config_provider_squiggles_disabled ": "根據 configurationProvider 設定提供的資訊,偵測到 #include 錯誤。已停用此編譯單位 ({0}) 的波浪線。", + "preprocessor_keyword": "前置處理器關鍵字", + "c_keyword": "C 關鍵字", + "cpp_keyword": "C++ 關鍵字", + "overload": "還有 1 次多載", + "overloads": "還有 %d 次多載", + "specialization": "還有 1 次特殊化", + "specializations": "還有 %d 次特殊化", + "expands_to": "展開至:", + "file_label": "檔案:", + "parameters_label": "參數:", + "returns_label": "傳回:", + "deprecated_label": "已淘汰:", + "exceptions_label": "例外狀況:" } \ No newline at end of file diff --git a/Extension/i18n/csy/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/csy/c_cpp_properties.schema.json.i18n.json index adc0158df0..f90417f53c 100644 --- a/Extension/i18n/csy/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/csy/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "True, pokud chcete zpracovat jen soubory přímo nebo nepřímo zahrnuté jako hlavičky, false, pokud chcete zpracovat všechny soubory na zadaných cestách pro vložené soubory", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Cesta k vygenerované databázi symbolů. Pokud se zadá relativní cesta, nastaví se jako relativní k výchozímu umístění úložiště pracovního prostoru.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Seznam cest, které analyzátor značek použije při hledání zahrnutých hlaviček. Hledání na těchto cestách je standardně rekurzivní. Pokud chcete zadat nerekurzivní hledání, zadejte *. Příklad: /usr/include bude hledat ve všech podadresářích, zatímco /usr/include/* ne.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Vlastní proměnné, na které se dá poslat dotaz prostřednictvím příkazu ${cpptools:activeConfigCustomVariable}, aby se použily jako vstupní proměnné v souborech launch.json nebo tasks.json.", "c_cpp_properties.schema.json.definitions.env": "Vlastní proměnné, které se dají opakovaně použít kdekoli v tomto souboru pomocí syntaxe ${proměnná} nebo ${env:proměnná}.", "c_cpp_properties.schema.json.definitions.version": "Verze konfiguračního souboru. Tuto vlastnost spravuje rozšíření. Neměňte ji prosím.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Určuje, jestli rozšíření ohlásí chyby zjištěné v souboru c_cpp_properties.json." diff --git a/Extension/i18n/csy/package.i18n.json b/Extension/i18n/csy/package.i18n.json index 3c690e73e2..750aacb818 100644 --- a/Extension/i18n/csy/package.i18n.json +++ b/Extension/i18n/csy/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Hodnota, která se použije v konfiguraci, pokud se nezadá browse.limitSymbolsToIncludedHeaders nebo pokud se nastaví na ${default}", "c_cpp.configuration.default.systemIncludePath.description": "Hodnota, která se použije pro systémovou cestu pro vložené soubory. Pokud se nastaví, přepíše systémovou cestu pro vložené soubory získanou z nastavení compilerPath a compileCommands.", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Určuje, jestli rozšíření ohlásí chyby zjištěné v souboru c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Hodnota, která se použije v konfiguraci, pokud se nenastaví customConfigurationVariables, nebo hodnoty, které se mají vložit, pokud se v customConfigurationVariables jako klíč nachází ${default}", "c_cpp.configuration.updateChannel.description": "Pokud chcete automaticky stahovat a instalovat nejnovější sestavení rozšíření v programu Insider, která zahrnují připravované funkce a opravy chyb, nastavte možnost Účastníci programu Insider.", "c_cpp.configuration.experimentalFeatures.description": "Určuje, jestli je možné použít experimentální funkce.", "c_cpp.configuration.suggestSnippets.description": "Pokud se nastaví na true, jazykový server poskytne fragmenty kódu.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Plně kvalifikovaný příkaz kanálu, který se má provést", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Argumenty příkazového řádku, které se předávají do cílového programu, aby se nakonfigurovalo připojení", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Proměnné prostředí, které se předávají do cílového programu", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Pokud jednotlivé argumenty pro pipeProgram obsahují znaky (například mezery nebo tabulátory), mají se používat uvozovky? Pokud se nastaví hodnota false, nebudou se už v příkazu ladicího programu automaticky používat uvozovky. \nVýchozí hodnota je true.", "c_cpp.debuggers.logging.description": "Nepovinné příznaky, které určují, které typy zpráv se mají protokolovat do konzoly ladění", "c_cpp.debuggers.logging.exceptions.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění mají protokolovat zprávy výjimek. Výchozí hodnota je true.", "c_cpp.debuggers.logging.moduleLoad.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění mají protokolovat události načítání modulu. Výchozí hodnota je true.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění mají protokolovat diagnostické zprávy ladicího stroje. Výchozí hodnota je false.", "c_cpp.debuggers.logging.trace.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění má protokolovat trasování příkazů diagnostického adaptéru. Výchozí hodnota je false.", "c_cpp.debuggers.logging.traceResponse.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění má protokolovat trasování příkazů a odpovědí diagnostického adaptéru. Výchozí hodnota je false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Nepovinný příznak, který určuje, jestli se do konzoly ladění mají protokolovat ukončovací zprávy vlákna. Výchozí: false", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Nepovinný příznak, který určuje, jestli se mají ukončovací zprávy cílového procesu protokolovat do konzoly ladění, nebo jestli je ladění zastavené. Výchozí: true", "c_cpp.debuggers.text.description": "Příkaz ladicího programu, který se má provést", "c_cpp.debuggers.description.description": "Volitelný popis příkazu", "c_cpp.debuggers.ignoreFailures.description": "Pokud má hodnotu true, měla by se ignorovat selhání z daného příkazu. Výchozí hodnota je false.", diff --git a/Extension/i18n/csy/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/csy/src/Debugger/configurationProvider.i18n.json index ab79ef1337..bfbceed3d4 100644 --- a/Extension/i18n/csy/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/csy/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Ladicí program typu {0} je k dispozici jen ve Windows. Na aktuální platformě operačního systému použijte typ {1}.", "lldb.framework.install.xcode": "Další informace", "lldb.framework.not.found": "Nepovedlo se najít LLDB.framework pro lldb-mi. Nainstalujte prosím XCode nebo jeho nástroje příkazového řádku.", + "debugger.launchConfig": "Spustit konfiguraci:", "lldb.find.failed": "Chybí závislosti {0} pro spustitelný soubor lldb-mi.", "lldb.search.paths": "Prohledáno:", "lldb.install.help": "Pokud chcete tento problém vyřešit, buď nainstalujte XCode přes obchod Apple App Store, nebo v okně terminálu spusťte {0}, aby se nainstalovaly nástroje příkazového řádku XCode.", diff --git a/Extension/i18n/csy/src/main.i18n.json b/Extension/i18n/csy/src/main.i18n.json index 2f1b25ba18..5b5e3cb0db 100644 --- a/Extension/i18n/csy/src/main.i18n.json +++ b/Extension/i18n/csy/src/main.i18n.json @@ -6,7 +6,7 @@ { "architecture.not.supported": "Architektura {0} se nepodporuje. ", "apline.containers.not.supported": "Kontejnery Alpine se nepodporují.", - "native.binaries.not.supported": "Tato verze rozšíření {0} není kompatibilní s vaším operačním systémem. Stáhněte a nainstalujte si prosím verzi rozšíření {1}.", + "native.binaries.not.supported": "Tato verze rozšíření pro {0} není kompatibilní s vaším operačním systémem. Stáhněte a nainstalujte si prosím verzi rozšíření {1}.", "download.button": "Přejít na stránku stahování", "initialization.failed": "Nepovedlo se nainstalovat rozšíření C/C++. Další informace najdete v okně výstupu.", "updating.dependencies": "Aktualizují se závislosti C/C++...", diff --git a/Extension/i18n/csy/src/nativeStrings.i18n.json b/Extension/i18n/csy/src/nativeStrings.i18n.json index fef6bfbc53..f1a05ac5a2 100644 --- a/Extension/i18n/csy/src/nativeStrings.i18n.json +++ b/Extension/i18n/csy/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Nepovedlo se poslat dotaz na kompilátor. Probíhá návrat k režimu bez bitové verze.", "intellisense_client_creation_aborted": "Vytváření klienta IntelliSense se přerušilo: {0}", "include_errors_config_provider_intellisense_disabled ": "Na základě informací z nastavení configurationProvider se zjistily chyby direktivy #include. Funkce IntelliSense pro tuto jednotku překladu ({0}) bude poskytovat Tag Parser.", - "include_errors_config_provider_squiggles_disabled ": "Na základě informací z nastavení configurationProvider se zjistily chyby direktivy #include. Pro tuto jednotku překladu ({0}) se zakázaly vlnovky." + "include_errors_config_provider_squiggles_disabled ": "Na základě informací z nastavení configurationProvider se zjistily chyby direktivy #include. Pro tuto jednotku překladu ({0}) se zakázaly vlnovky.", + "preprocessor_keyword": "klíčové slovo preprocesoru", + "c_keyword": "Klíčové slovo jazyka C", + "cpp_keyword": "Klíčové slovo jazyka C++", + "overload": "+1 přetížení", + "overloads": "+%d přetížení", + "specialization": "+1 specializace", + "specializations": "+tento počet specializací: %d", + "expands_to": "Rozšiřuje se na:", + "file_label": "Soubor:", + "parameters_label": "Parametry:", + "returns_label": "Vrací:", + "deprecated_label": "Zastaralé:", + "exceptions_label": "Výjimky:" } \ No newline at end of file diff --git a/Extension/i18n/deu/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/deu/c_cpp_properties.schema.json.i18n.json index 50790e067a..38a97b228b 100644 --- a/Extension/i18n/deu/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/deu/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "TRUE, um nur die direkt oder indirekt als Header enthaltenen Dateien zu verarbeiten; FALSE, um alle Dateien unter den angegebenen Includepfaden zu verarbeiten.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Pfad zur generierten Symboldatenbank. Wenn ein relativer Pfad angegeben wird, wird er relativ zum Standardspeicherort des Arbeitsbereichs erstellt.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Eine Liste von Pfaden, die der Tagparser beim Suchen nach eingeschlossenen Headern verwenden soll. Die Suche in diesen Pfaden ist standardmäßig rekursiv. Geben Sie \"*\" an, um eine nicht rekursive Suche festzulegen. Beispiel: Bei \"/usr/include\" werden alle Unterverzeichnisse durchsucht, bei \"/usr/include/*\" nicht.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Benutzerdefinierte Variablen, die über den Befehl ${cpptools:activeConfigCustomVariable} abgefragt und für die Eingabevariablen in launch.json oder tasks.json verwendet werden können.", "c_cpp_properties.schema.json.definitions.env": "Benutzerdefinierte Variablen, die mithilfe der ${variable}- oder ${env:variable}-Syntax an beliebiger Stelle in dieser Datei wiederverwendet werden können.", "c_cpp_properties.schema.json.definitions.version": "Version der Konfigurationsdatei. Diese Eigenschaft wird von der Erweiterung verwaltet und darf nicht geändert werden.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Hiermit wird gesteuert, ob die Erweiterung in \"c_cpp_properties.json\" erkannte Fehler meldet." diff --git a/Extension/i18n/deu/package.i18n.json b/Extension/i18n/deu/package.i18n.json index f58b7a52eb..e5aafa86aa 100644 --- a/Extension/i18n/deu/package.i18n.json +++ b/Extension/i18n/deu/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Der Wert, der in einer Konfiguration verwendet werden soll, wenn \"browse.limitSymbolsToIncludedHeaders\" entweder nicht angegeben oder auf \"${default}\" festgelegt ist.", "c_cpp.configuration.default.systemIncludePath.description": "Der Wert, der für den Systemincludepfad verwendet werden soll. Wenn diese Option festgelegt ist, wird der über die Einstellungen \"compilerPath\" und \"compileCommands\" erhaltene Systemincludepfad überschrieben.", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Hiermit wird gesteuert, ob die Erweiterung in \"c_cpp_properties.json\" erkannte Fehler meldet.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Der Wert, der in einer Konfiguration verwendet werden soll, wenn \"customConfigurationVariables\" nicht angegeben ist, oder die einzufügenden Werte, wenn \"${default}\" als Schlüssel in \"customConfigurationVariables\" vorhanden ist.", "c_cpp.configuration.updateChannel.description": "Legen Sie den Wert auf \"Insiders\" fest, um die neuesten Insiders-Builds der Erweiterung, die neue Features und Bugfixes enthalten, automatisch herunterzuladen und zu installieren.", "c_cpp.configuration.experimentalFeatures.description": "Hiermit wird gesteuert, ob experimentelle Features verwendet werden können.", "c_cpp.configuration.suggestSnippets.description": "Wenn dieser Wert auf TRUE festgelegt ist, werden Codeausschnitte vom Sprachserver bereitgestellt.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Der vollqualifizierte auszuführende Pipebefehl.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Befehlszeilenargumente, die zum Konfigurieren der Verbindung an das Pipeprogramm übergeben werden.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Umgebungsvariablen, die an das Pipeprogramm übergeben werden.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Gibt an, ob Anführungszeichen gesetzt werden sollen, wenn die einzelnen pipeProgram-Argumente Zeichen enthalten (z. B. Leerzeichen oder Tabstopps). Bei Einstellung auf \"false\" wird der Debuggerbefehl nicht mehr automatisch in Anführungszeichen gesetzt. \nDer Standardwert ist \"true\".", "c_cpp.debuggers.logging.description": "Optionale Flags zum Festlegen, welche Nachrichtentypen in der Debugging-Konsole protokolliert werden sollen.", "c_cpp.debuggers.logging.exceptions.description": "Optionales Flag zum Festlegen, ob Ausnahmemeldungen in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist TRUE.", "c_cpp.debuggers.logging.moduleLoad.description": "Optionales Flag zum Festlegen, ob Modulladeereignisse in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist TRUE.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Optionales Flag zum Festlegen, ob Nachrichten der Diagnosedebug-Engine in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist FALSE.", "c_cpp.debuggers.logging.trace.description": "Optionales Flag zum Festlegen, ob die Befehlsablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist FALSE.", "c_cpp.debuggers.logging.traceResponse.description": "Optionales Flag zum Festlegen, ob die Befehls- und Antwortablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist FALSE.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Optionales Flag zum Bestimmen, ob Meldungen zum Beenden des Threads in der Debugging-Konsole protokolliert werden sollen. Standardwert: \"false\".", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Optionales Flag zum Bestimmen, ob Meldungen zum Beenden des Zielprozesses in der Debugging-Konsole protokolliert werden sollen oder das Debugging beendet werden soll. Standardwert: \"true\".", "c_cpp.debuggers.text.description": "Der auszuführende Debuggerbefehl.", "c_cpp.debuggers.description.description": "Optionale Beschreibung des Befehls.", "c_cpp.debuggers.ignoreFailures.description": "Wenn dieser Wert auf TRUE festgelegt ist, werden durch den Befehl verursachte Fehler ignoriert. Der Standardwert ist FALSE.", diff --git a/Extension/i18n/deu/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/deu/src/Debugger/configurationProvider.i18n.json index 334d0f115f..85ebe11e7a 100644 --- a/Extension/i18n/deu/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/deu/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Der Debugger vom Typ \"{0}\" ist nur unter Windows verfügbar. Verwenden Sie auf der aktuellen Betriebssystemplattform den Typ \"{1}\".", "lldb.framework.install.xcode": "Details", "lldb.framework.not.found": "\"LLDB.framework\" wurde für LLDB-Mi nicht gefunden. Installieren Sie XCode oder die XCode-Befehlszeilentools.", + "debugger.launchConfig": "Startkonfiguration:", "lldb.find.failed": "Fehlende Abhängigkeit \"{0}\" für ausführbare LLDB-MI-Datei.", "lldb.search.paths": "Gesucht in:", "lldb.install.help": "Um dieses Problem zu beheben, installieren Sie entweder XCode über den Apple App Store, oder installieren Sie die XCode-Befehlszeilentools, indem Sie \"{0}\" in einem Terminalfenster ausführen.", diff --git a/Extension/i18n/deu/src/nativeStrings.i18n.json b/Extension/i18n/deu/src/nativeStrings.i18n.json index c51fe7adf9..dccec5225a 100644 --- a/Extension/i18n/deu/src/nativeStrings.i18n.json +++ b/Extension/i18n/deu/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Fehler beim Abfragen des Compilers. Es wird ein Fallback auf keine Bitanzahl durchgeführt.", "intellisense_client_creation_aborted": "IntelliSense-Clienterstellung abgebrochen: {0}", "include_errors_config_provider_intellisense_disabled ": "Basierend auf den von der configurationProvider-Einstellung bereitgestellten Informationen wurden #include-Fehler festgestellt. IntelliSense-Features für diese Übersetzungseinheit ({0}) werden vom Tagparser bereitgestellt.", - "include_errors_config_provider_squiggles_disabled ": "Basierend auf den von der configurationProvider-Einstellung bereitgestellten Informationen wurden #include-Fehler festgestellt. Wellenlinien sind für diese Übersetzungseinheit deaktiviert ({0})." + "include_errors_config_provider_squiggles_disabled ": "Basierend auf den von der configurationProvider-Einstellung bereitgestellten Informationen wurden #include-Fehler festgestellt. Wellenlinien sind für diese Übersetzungseinheit deaktiviert ({0}).", + "preprocessor_keyword": "Präprozessor-Schlüsselwort", + "c_keyword": "C-Schlüsselwort", + "cpp_keyword": "C++-Schlüsselwort", + "overload": "+1 Überladung", + "overloads": "+%d Überladungen", + "specialization": "+1 Spezialisierung", + "specializations": "+%d Spezialisierungen", + "expands_to": "Wird erweitert auf:", + "file_label": "Datei:", + "parameters_label": "Parameter:", + "returns_label": "Rückgabe:", + "deprecated_label": "Veraltet:", + "exceptions_label": "Ausnahmen:" } \ No newline at end of file diff --git a/Extension/i18n/esn/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/esn/c_cpp_properties.schema.json.i18n.json index d41bb1e1aa..c20441c797 100644 --- a/Extension/i18n/esn/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/esn/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "true para procesar únicamente los archivos incluidos directa o indirectamente como encabezados; false para procesar todos los archivos en las rutas de acceso de inclusión especificadas.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Ruta de acceso a la base de datos de símbolos generada. Si se especifica una ruta de acceso relativa, será relativa a la ubicación de almacenamiento predeterminada del área de trabajo.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Lista de rutas de acceso que usará el analizador de etiquetas al buscar los encabezados incluidos. De forma predeterminada, la búsqueda en estas rutas de acceso es recursiva. Especifique “*” para indicar una búsqueda no recursiva. Por ejemplo, “/usr/include” buscará en todos los subdirectorios, mientras que “/usr/include/*” no lo hará.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Variables personalizadas que pueden consultarse mediante el comando ${cpptools:activeConfigCustomVariable} para utilizarlas en las variables de entrada en launch.json o tasks.json.", "c_cpp_properties.schema.json.definitions.env": "Las variables personalizadas se pueden reutilizar en cualquier ubicación del archivo mediante la sintaxis ${variable} o ${env:variable}.", "c_cpp_properties.schema.json.definitions.version": "Versión del archivo de configuración. La extensión administra esta propiedad, no la modifique.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Controla si la extensión notificará los errores detectados en c_cpp_properties.json." diff --git a/Extension/i18n/esn/package.i18n.json b/Extension/i18n/esn/package.i18n.json index 914e25406d..37d25637c2 100644 --- a/Extension/i18n/esn/package.i18n.json +++ b/Extension/i18n/esn/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Valor que debe usarse en una configuración si no se ha especificado \"browse.limitSymbolsToIncludedHeaders\" o se ha establecido en \"${default}\".", "c_cpp.configuration.default.systemIncludePath.description": "Valor que debe usarse para la ruta de acceso de inclusión del sistema. Si se establece, invalida la ruta de acceso de inclusión del sistema adquirida a través de las opciones de configuración \"compilerPath\" y \"compileCommands\".", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Controla si la extensión notificará los errores detectados en c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Valor que debe usarse en una configuración si no se establece \"customConfigurationVariables\", o bien los valores que se deben insertar si se especifica \"${default}\" como clave en \"customConfigurationVariables\".", "c_cpp.configuration.updateChannel.description": "Establezca esta opción en \"Insiders\" para descargar e instalar automáticamente las compilaciones más recientes de Insiders para la extensión, que incluyen nuevas características y correcciones de errores.", "c_cpp.configuration.experimentalFeatures.description": "Controla si se pueden usar las características \"experimentales\".", "c_cpp.configuration.suggestSnippets.description": "Si se establece en true, el servidor de lenguaje proporciona los fragmentos de código.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Comando de canalización completo para ejecutar.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Argumentos de la línea de comandos que se pasan al programa de canalización para configurar la conexión.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Variables de entorno que se pasan al programa de canalización.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Si los argumentos individuales de pipeProgram contienen caracteres (como espacios o tabulaciones), ¿debe incluirse entre comillas? Si es \"false\", el comando del depurador dejará de incluirse entre comillas automáticamente. \nEl valor predeterminado es \"true\".", "c_cpp.debuggers.logging.description": "Marcas opcionales que determinan los tipos de mensajes que deben registrarse en la Consola de depuración.", "c_cpp.debuggers.logging.exceptions.description": "Marca opcional que determina si los mensajes de excepción deben registrarse en la Consola de depuración. El valor predeterminado es true.", "c_cpp.debuggers.logging.moduleLoad.description": "Marca opcional que determina si los eventos de carga de módulos deben registrarse en la Consola de depuración. El valor predeterminado es true.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Marca opcional que determina si los mensajes del motor de depuración de diagnóstico deben registrarse en la Consola de depuración. El valor predeterminado es false.", "c_cpp.debuggers.logging.trace.description": "Marca opcional que determina si el seguimiento de comandos del adaptador de diagnóstico debe registrarse en la Consola de depuración. El valor predeterminado es false.", "c_cpp.debuggers.logging.traceResponse.description": "Marca opcional que determina si el seguimiento de comandos y respuestas del adaptador de diagnóstico debe registrarse en la Consola de depuración. El valor predeterminado es false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Marca opcional que determina si los mensajes de salida de subprocesos deben registrarse en la Consola de depuración. El valor predeterminado es \"false\".", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Marca opcional para determinar si los mensajes de salida del proceso de destino deben registrarse en la Consola de depuración o bien la depuración se ha detenido. El valor predeterminado es \"true\".", "c_cpp.debuggers.text.description": "Comando del depurador para ejecutar.", "c_cpp.debuggers.description.description": "Descripción opcional del comando.", "c_cpp.debuggers.ignoreFailures.description": "Si se establece en true, los errores del comando deben omitirse. El valor predeterminado es false.", diff --git a/Extension/i18n/esn/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/esn/src/Debugger/configurationProvider.i18n.json index 324a9da872..a133595682 100644 --- a/Extension/i18n/esn/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/esn/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "El depurador de tipo \"{0}\" solo está disponible en Windows. Use el tipo \"{1}\" en la plataforma de sistema operativo actual.", "lldb.framework.install.xcode": "Más información", "lldb.framework.not.found": "No se encuentra \"LLDB.framework\" para lldb-mi. Instale XCode o las herramientas de línea de comandos de XCode.", + "debugger.launchConfig": "Configuración de inicio:", "lldb.find.failed": "Falta la dependencia \"{0}\" para el ejecutable lldb-mi.", "lldb.search.paths": "Buscado en:", "lldb.install.help": "Para resolver este problema, instale XCode mediante App Store de Apple o instale las herramientas de línea de comandos de XCode ejecutando \"{0}\" en una ventana de terminal.", diff --git a/Extension/i18n/esn/src/nativeStrings.i18n.json b/Extension/i18n/esn/src/nativeStrings.i18n.json index 913699768d..3e314fdd5b 100644 --- a/Extension/i18n/esn/src/nativeStrings.i18n.json +++ b/Extension/i18n/esn/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "No se pudo consultar el compilador. Revirtiendo para no establecer ningún valor de bits.", "intellisense_client_creation_aborted": "Se anuló la creación del cliente de IntelliSense: {0}", "include_errors_config_provider_intellisense_disabled ": "Se han detectado errores de #include basados en la información proporcionada por configurationProvider. El analizador de etiquetas proporcionará las características de IntelliSense para esta unidad de traducción ({0}).", - "include_errors_config_provider_squiggles_disabled ": "Se han detectado errores de #include basados en la información proporcionada por configurationProvider. El subrayado ondulado está deshabilitado para esta unidad de traducción ({0})." + "include_errors_config_provider_squiggles_disabled ": "Se han detectado errores de #include basados en la información proporcionada por configurationProvider. El subrayado ondulado está deshabilitado para esta unidad de traducción ({0}).", + "preprocessor_keyword": "palabra clave del preprocesador", + "c_keyword": "Palabra clave de C", + "cpp_keyword": "Palabra clave de C++", + "overload": "1 sobrecarga más", + "overloads": "%d sobrecargas más", + "specialization": "1 especialización más", + "specializations": "%d especializaciones más", + "expands_to": "Se expande a:", + "file_label": "Archivo:", + "parameters_label": "Parámetros:", + "returns_label": "Devuelve:", + "deprecated_label": "En desuso:", + "exceptions_label": "Excepciones:" } \ No newline at end of file diff --git a/Extension/i18n/fra/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/fra/c_cpp_properties.schema.json.i18n.json index fc85a1baf8..d05947e522 100644 --- a/Extension/i18n/fra/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/fra/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "true pour traiter uniquement les fichiers inclus directement ou indirectement comme des en-têtes, false pour traiter tous les fichiers sous les chemins d'inclusion spécifiés.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Chemin de la base de données de symboles générée. Si un chemin relatif est spécifié, il est relatif à l'emplacement de stockage par défaut de l'espace de travail.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Liste de chemins que l'analyseur de balises doit utiliser pour la recherche des en-têtes inclus. La recherche dans ces chemins est récursive par défaut. Spécifiez '*' pour indiquer une recherche non récursive. Par exemple : '/usr/include' effectue une recherche dans tous les sous-répertoires, contrairement à '/usr/include/*'.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Variables personnalisées qui peuvent être interrogées par le biais de la commande ${cpptools:activeConfigCustomVariable} à utiliser pour les variables d'entrée dans launch.json ou tasks.json.", "c_cpp_properties.schema.json.definitions.env": "Variables personnalisées pouvant être réutilisées partout dans ce fichier à l'aide de la syntaxe ${variable} ou ${env:variable}.", "c_cpp_properties.schema.json.definitions.version": "Version du fichier de configuration. Cette propriété est gérée par l'extension. Ne la changez pas.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Contrôle si l'extension signale les erreurs détectées dans c_cpp_properties.json." diff --git a/Extension/i18n/fra/package.i18n.json b/Extension/i18n/fra/package.i18n.json index 274a7626b7..e81917bb10 100644 --- a/Extension/i18n/fra/package.i18n.json +++ b/Extension/i18n/fra/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Valeur à utiliser dans une configuration si \"browse.limitSymbolsToIncludedHeaders\" n'est pas spécifié ou a la valeur \"${default}\".", "c_cpp.configuration.default.systemIncludePath.description": "Valeur à utiliser pour le chemin d'inclusion système. Si cette option est définie, elle remplace le chemin d'inclusion système obtenu via les paramètres \"compilerPath\" et \"compileCommands\".", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Contrôle si l'extension signale les erreurs détectées dans c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Valeur à utiliser dans une configuration si \"customConfigurationVariables\" n'est pas défini, ou valeurs à insérer si \"${default}\" est présent dans \"customConfigurationVariables\".", "c_cpp.configuration.updateChannel.description": "Définissez \"Insiders\" pour télécharger et installer automatiquement les dernières builds Insiders de l'extension, qui comprend les fonctionnalités à venir et des résolutions de bogues.", "c_cpp.configuration.experimentalFeatures.description": "Contrôle si les fonctionnalités \"expérimentales\" sont utilisables.", "c_cpp.configuration.suggestSnippets.description": "Si la valeur est true, des extraits de code sont fournis par le serveur de langage.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Commande canal complète à exécuter.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Arguments de ligne de commande passés au programme canal pour configurer la connexion.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Variables d'environnement passées au programme canal.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Si des arguments individuels de pipeProgram contiennent des caractères (par exemple des espaces ou des tabulations), doivent-ils être placés entre guillemets ? Si la valeur est 'false', la commande de débogueur n'est plus automatiquement placée entre guillemets. \nLa valeur par défaut est 'true'.", "c_cpp.debuggers.logging.description": "Indicateurs facultatifs pour déterminer les types de messages à journaliser dans la console de débogage.", "c_cpp.debuggers.logging.exceptions.description": "Indicateur facultatif pour déterminer si les messages d'exception doivent être journalisés dans la console de débogage. La valeur par défaut est true.", "c_cpp.debuggers.logging.moduleLoad.description": "Indicateur facultatif pour déterminer si les événements de chargement de module doivent être journalisés dans la console de débogage. La valeur par défaut est true.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Indicateur facultatif pour déterminer si les messages du moteur de débogage de diagnostic doivent être journalisés dans la console de débogage. La valeur par défaut est false.", "c_cpp.debuggers.logging.trace.description": "Indicateur facultatif pour déterminer si le suivi de commande de l'adaptateur de diagnostic doit être journalisé dans la console de débogage. La valeur par défaut est false.", "c_cpp.debuggers.logging.traceResponse.description": "Indicateur facultatif pour déterminer si le suivi de commande et de réponse de l'adaptateur de diagnostic doit être journalisé dans la console de débogage. La valeur par défaut est false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Indicateur facultatif pour déterminer si les messages indiquant la sortie du thread doivent être journalisés dans la console de débogage. Valeur par défaut : 'false'.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Indicateur facultatif pour déterminer si les messages indiquant la sortie du processus cible doivent être journalisés dans la console de débogage ou si le débogage est arrêté. Valeur par défaut : 'true'.", "c_cpp.debuggers.text.description": "Commande de débogueur à exécuter.", "c_cpp.debuggers.description.description": "Description facultative de la commande.", "c_cpp.debuggers.ignoreFailures.description": "Si la valeur est true, les échecs de la commande doivent être ignorés. La valeur par défaut est false.", diff --git a/Extension/i18n/fra/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/fra/src/Debugger/configurationProvider.i18n.json index 2106e25d9e..b32e1f3415 100644 --- a/Extension/i18n/fra/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/fra/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Le débogueur de type '{0}' est disponible seulement sur Windows. Utilisez le type '{1}' sur la plateforme OS actuelle.", "lldb.framework.install.xcode": "En savoir plus", "lldb.framework.not.found": "Impossible de localiser 'LLDB.framework' pour lldb-mi. Installez XCode ou les outils en ligne de commande XCode.", + "debugger.launchConfig": "Lancer la configuration :", "lldb.find.failed": "La dépendance '{0}' est manquante pour l'exécutable lldb-mi.", "lldb.search.paths": "Recherche effectuée dans :", "lldb.install.help": "Pour résoudre ce problème, installez XCode via l'Apple App Store ou installez les outils en ligne de commande XCode en exécutant '{0}' dans une fenêtre de terminal.", diff --git a/Extension/i18n/fra/src/nativeStrings.i18n.json b/Extension/i18n/fra/src/nativeStrings.i18n.json index 9031f2f38a..335b140523 100644 --- a/Extension/i18n/fra/src/nativeStrings.i18n.json +++ b/Extension/i18n/fra/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Échec de l'interrogation du compilateur. Retour au mode sans nombre de bits.", "intellisense_client_creation_aborted": "Abandon de la création du client IntelliSense : {0}", "include_errors_config_provider_intellisense_disabled ": "Erreurs #include détectées d'après les informations fournies par le paramètre configurationProvider. Les fonctionnalités IntelliSense de cette unité de traduction ({0}) sont fournies par l'analyseur de balises.", - "include_errors_config_provider_squiggles_disabled ": "Erreurs #include détectées d'après les informations fournies par le paramètre configurationProvider. Les tildes sont désactivés pour cette unité de traduction ({0})." + "include_errors_config_provider_squiggles_disabled ": "Erreurs #include détectées d'après les informations fournies par le paramètre configurationProvider. Les tildes sont désactivés pour cette unité de traduction ({0}).", + "preprocessor_keyword": "mot clé de préprocesseur", + "c_keyword": "Mot clé C", + "cpp_keyword": "Mot clé C++", + "overload": "+1 surcharge", + "overloads": "+%d surcharges", + "specialization": "+1 spécialisation", + "specializations": "+%d spécialisations", + "expands_to": "Se développe sur :", + "file_label": "Fichier :", + "parameters_label": "Paramètres :", + "returns_label": "Retourne :", + "deprecated_label": "Déprécié :", + "exceptions_label": "Exceptions :" } \ No newline at end of file diff --git a/Extension/i18n/ita/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/ita/c_cpp_properties.schema.json.i18n.json index 6db73ffce7..aeb401c8ea 100644 --- a/Extension/i18n/ita/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/ita/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "true per elaborare solo i file inclusi direttamente o indirettamente come intestazioni; false per elaborare tutti i file nei percorsi di inclusione specificati.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Percorso del database dei simboli generato. Se viene specificato un percorso relativo, sarà relativo al percorso di archiviazione predefinito dell'area di lavoro.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Elenco di percorsi che il parser di tag userà durante la ricerca delle intestazioni incluse. Per impostazione predefinita, la ricerca in questi percorsi è ricorsiva. Specificare '*' per indicare la ricerca non ricorsiva. Ad esempio: con '/usr/include' la ricerca verrà estesa in tutte le sottodirectory, mentre con '/usr/include/*' sarà limitata a quella corrente.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Variabili personalizzate su cui è possibile eseguire query tramite il comando ${cpptools:activeConfigCustomVariable} da usare per le variabili di input in launch.jso o tasks.js.", "c_cpp_properties.schema.json.definitions.env": "Variabili personalizzate che è possibile riutilizzare in qualsiasi punto del file usando la sintassi ${variabile} o ${env:variabile}.", "c_cpp_properties.schema.json.definitions.version": "Versione del file di configurazione. Questa proprietà è gestita dall'estensione. Non modificarla.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Controlla se l'estensione segnalerà errori rilevati in c_cpp_properties.json." diff --git a/Extension/i18n/ita/package.i18n.json b/Extension/i18n/ita/package.i18n.json index 0c8381fbfc..2aa0352eb3 100644 --- a/Extension/i18n/ita/package.i18n.json +++ b/Extension/i18n/ita/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Valore da usare in una configurazione se \"browse.limitSymbolsToIncludedHeaders\" non è specificato o impostato su \"${default}\".", "c_cpp.configuration.default.systemIncludePath.description": "Valore da usare per il percorso di inclusione di sistema. Se è impostato, esegue l'override del percorso di inclusione di sistema acquisito con le impostazioni \"compilerPath\" e \"compileCommands\".", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Controlla se l'estensione segnalerà errori rilevati in c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Valore da usare in una configurazione se \"customConfigurationVariables\" non è impostato oppure valori da inserire se \"${default}\" è presente come chiave in \"customConfigurationVariables\".", "c_cpp.configuration.updateChannel.description": "Impostare su \"Insider\" per scaricare e installare automaticamente le build Insider più recenti dell'estensione, che includono funzionalità in arrivo e correzioni di bug.", "c_cpp.configuration.experimentalFeatures.description": "Controlla se le funzionalità \"sperimentali\" sono utilizzabili.", "c_cpp.configuration.suggestSnippets.description": "Se è true, i frammenti vengono forniti dal server di linguaggio.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Comando pipe completo da eseguire.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Argomenti della riga di comando passati al programma pipe per configurare la connessione.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Variabili di ambiente passate al programma pipe.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Indica se i singoli argomenti di pipeProgram devono essere racchiusi tra virgolette quando contengono caratteri, ad esempio spazi o tabulazioni. Se è 'false', il comando del debugger non verrà più racchiuso automaticamente tra virgolette. \nL'impostazione predefinita è 'true'.", "c_cpp.debuggers.logging.description": "Flag facoltativi per determinare i tipi di messaggi da registrare nella Console di debug.", "c_cpp.debuggers.logging.exceptions.description": "Flag facoltativo per determinare se i messaggi di eccezione devono essere registrati nella Console di debug. Il valore predefinito è true.", "c_cpp.debuggers.logging.moduleLoad.description": "Flag facoltativo per determinare se gli eventi di caricamento del modulo devono essere registrati nella Console di debug. Il valore predefinito è true.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Flag facoltativo per determinare se i messaggi del motore di debug di diagnostica devono essere registrati nella Console di debug. Il valore predefinito è false.", "c_cpp.debuggers.logging.trace.description": "Flag facoltativo per determinare se la traccia dei comandi dell'adattatore di diagnostica deve essere registrata nella Console di debug. Il valore predefinito è false.", "c_cpp.debuggers.logging.traceResponse.description": "Flag facoltativo per determinare se la traccia dei comandi e delle risposte dell'adattatore di diagnostica deve essere registrata nella Console di debug. Il valore predefinito è false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Flag facoltativo per determinare se i messaggi di uscita del thread devono essere registrati nella Console di debug. Impostazione predefinita: `false`.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Flag facoltativo per determinare se i messaggi di uscita del processo di destinazione devono essere registrati nella Console di debug o se il debug deve essere arrestato. Impostazione predefinita: `true`.", "c_cpp.debuggers.text.description": "Comando del debugger da eseguire.", "c_cpp.debuggers.description.description": "Descrizione facoltativa del comando.", "c_cpp.debuggers.ignoreFailures.description": "Se è true, gli errori del comando devono essere ignorati. Il valore predefinito è false.", diff --git a/Extension/i18n/ita/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/ita/src/Debugger/configurationProvider.i18n.json index 2ee2a21fee..73f8954cea 100644 --- a/Extension/i18n/ita/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/ita/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Il debugger di tipo '{0}' è disponibile solo in Windows. Usare il tipo '{1}' nella piattaforma corrente del sistema operativo.", "lldb.framework.install.xcode": "Ulteriori informazioni", "lldb.framework.not.found": "Non è possibile trovare 'LLDB.framework' per lldb-mi. Installare Xcode o gli strumenti da riga di comando Xcode.", + "debugger.launchConfig": "Configurazione di avvio:", "lldb.find.failed": "Manca la dipendenza '{0}' per l'eseguibile lldb-mi.", "lldb.search.paths": "Ricerca effettuata in:", "lldb.install.help": "Per risolvere questo problema, installare Xcode tramite Apple App Store oppure installare gli strumenti da riga di comando di Xcode eseguendo '{0}' in una finestra di terminale.", diff --git a/Extension/i18n/ita/src/nativeStrings.i18n.json b/Extension/i18n/ita/src/nativeStrings.i18n.json index cf2de08a7d..e070e82ec5 100644 --- a/Extension/i18n/ita/src/nativeStrings.i18n.json +++ b/Extension/i18n/ita/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Non è stato possibile eseguire una query sul compilatore. Verrà eseguito il fallback alla modalità senza numero di bit.", "intellisense_client_creation_aborted": "La creazione del client IntelliSense è stata interrotta: {0}", "include_errors_config_provider_intellisense_disabled ": "Sono stati rilevati errori #include sulla base delle informazioni fornite dall'impostazione configurationProvider. Le funzionalità IntelliSense per questa unità di conversione ({0}) verranno fornite dal parser di tag.", - "include_errors_config_provider_squiggles_disabled ": "Sono stati rilevati errori #include sulla base delle informazioni fornite dall'impostazione configurationProvider. I segni di revisione sono disabilitati per questa unità di conversione ({0})." + "include_errors_config_provider_squiggles_disabled ": "Sono stati rilevati errori #include sulla base delle informazioni fornite dall'impostazione configurationProvider. I segni di revisione sono disabilitati per questa unità di conversione ({0}).", + "preprocessor_keyword": "parola chiave del preprocessore", + "c_keyword": "parola chiave C", + "cpp_keyword": "parola chiave C++", + "overload": "+ 1 overload", + "overloads": "+ %d overload", + "specialization": "+ 1 specializzazione", + "specializations": "+ %d specializzazioni", + "expands_to": "Si espande in:", + "file_label": "File:", + "parameters_label": "Parametri:", + "returns_label": "Restituisce:", + "deprecated_label": "Deprecato:", + "exceptions_label": "Eccezioni:" } \ No newline at end of file diff --git a/Extension/i18n/jpn/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/jpn/c_cpp_properties.schema.json.i18n.json index 222ac1aeb6..69b06ad264 100644 --- a/Extension/i18n/jpn/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/jpn/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "ヘッダーとして直接的または間接的にインクルードされたファイルのみを処理する場合は true、指定したインクルード パスにあるすべてのファイルを処理する場合は false です。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "生成されるシンボル データベースへのパスです。相対パスを指定した場合、ワークスペースの既定のストレージの場所に対する相対パスになります。", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "インクルードされたヘッダーを検索する際にタグ パーサーが使用するパスの一覧です。既定では、これらのパスでの検索は再帰的です。非再帰的な検索を示すには、'*' を指定します。たとえば、'/usr/include' を指定するとすべてのサブディレクトリが検索されますが、'/usr/include/*' を指定すると検索されません。", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "launch.json または tasks.json で入力変数として使用するためにコマンド ${cpptools:activeConfigCustomVariable} を使用して照会できるカスタム変数。", "c_cpp_properties.schema.json.definitions.env": "${変数} 構文または ${env:変数} 構文を使用して、このファイルのどこからでも再利用できるカスタム変数です。", "c_cpp_properties.schema.json.definitions.version": "構成ファイルのバージョンです。このプロパティは、拡張機能によって管理されています。変更しないでください。", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "拡張機能が、c_cpp_properties.json で検出されたエラーを報告するかどうかを制御します。" diff --git a/Extension/i18n/jpn/package.i18n.json b/Extension/i18n/jpn/package.i18n.json index c6a0ded4c6..821a81748d 100644 --- a/Extension/i18n/jpn/package.i18n.json +++ b/Extension/i18n/jpn/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "\"browse.limitSymbolsToIncludedHeaders\" が指定されていないか、\"${default}\" に設定されている場合に、構成で使用される値です。", "c_cpp.configuration.default.systemIncludePath.description": "システム インクルード パスに使用する値です。これを設定した場合、\"compilerPath\" および \"compileCommands\" の設定によって取得されるシステム インクルード パスが上書きされます。", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "拡張機能が、c_cpp_properties.json で検出されたエラーを報告するかどうかを制御します。", + "c_cpp.configuration.default.customConfigurationVariables.description": "\"customConfigurationVariables\" が設定されていない場合に構成で使用される値、または \"customConfigurationVariables\" 内に \"${default}\" がキーとして存在する場合に挿入される値です。", "c_cpp.configuration.updateChannel.description": "\"Insider\" に設定すると、拡張機能の最新の Insider ビルドが自動的にダウンロードされてインストールされます。これには、次期バージョンの機能とバグ修正が含まれています。", "c_cpp.configuration.experimentalFeatures.description": "\"experimental\" の機能を使用できるかどうかを制御します。", "c_cpp.configuration.suggestSnippets.description": "true の場合、スニペットは言語サーバーによって提供されます。", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "実行するパイプ コマンドの完全修飾パス。", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "接続を構成するためにパイプ プログラムに渡すコマンド ライン引数。", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "パイプ プログラムに渡す環境変数。", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "pipeProgram の個々の引数に (スペースやタブなどの) 文字が含まれる場合に引用符で囲むかどうか。'false' に設定すると、デバッガー コマンドが自動的に引用符で囲まれることはなくなります。\n既定値は 'true' です。", "c_cpp.debuggers.logging.description": "どの種類のメッセージをデバッグ コンソールに記録する必要があるかを決定するオプションのフラグです。", "c_cpp.debuggers.logging.exceptions.description": "例外メッセージをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値は true です。", "c_cpp.debuggers.logging.moduleLoad.description": "モジュール読み込みイベントをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値は true です。", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "診断デバッグ エンジンのメッセージをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値は false です。", "c_cpp.debuggers.logging.trace.description": "診断アダプター コマンドのトレースをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値は false です。", "c_cpp.debuggers.logging.traceResponse.description": "診断アダプター コマンドと応答トレースをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値は false です", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "スレッドの終了メッセージをデバッグ コンソールに記録するかどうかを決定するオプションのフラグです。既定値: 'false'。", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "ターゲット プロセスの終了メッセージをデバッグ コンソールに記録するか、またはデバッグを停止するかを決定するオプションのフラグです。既定値: 'true'。", "c_cpp.debuggers.text.description": "実行するデバッガー コマンドです。", "c_cpp.debuggers.description.description": "コマンドの説明 (省略可能)。", "c_cpp.debuggers.ignoreFailures.description": "true に設定すると、コマンドの失敗は無視されます。既定値は false です。", diff --git a/Extension/i18n/jpn/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/jpn/src/Debugger/configurationProvider.i18n.json index 6650f33dee..2a61cd092c 100644 --- a/Extension/i18n/jpn/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/jpn/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "タイプ '{0}' のデバッガーは、Windows でのみ使用できます。現在の OS プラットフォームでは、タイプ '{1}' を使用してください。", "lldb.framework.install.xcode": "詳細", "lldb.framework.not.found": "lldb-mi の 'LLDB.framework' が見つかりません。XCode または XCode コマンド ライン ツールをインストールしてください。", + "debugger.launchConfig": "起動の構成:", "lldb.find.failed": "lldb-mi 実行可能ファイルの依存関係 '{0}' が見つかりません。", "lldb.search.paths": "検索対象:", "lldb.install.help": "この問題を解決するには、Apple App Store から XCode をインストールするか、またはターミナル ウィンドウで '{0}' を実行して XCode コマンド ライン ツールをインストールしてください。", diff --git a/Extension/i18n/jpn/src/nativeStrings.i18n.json b/Extension/i18n/jpn/src/nativeStrings.i18n.json index 3826cbd269..92c19c7d6b 100644 --- a/Extension/i18n/jpn/src/nativeStrings.i18n.json +++ b/Extension/i18n/jpn/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "コンパイラを照会できませんでした。ビットなしに戻ります。", "intellisense_client_creation_aborted": "IntelliSense クライアントの作成が中止されました: {0}", "include_errors_config_provider_intellisense_disabled ": "configurationProvider 設定によって提供された情報に基づいて、#include エラーが検出されました。この翻訳単位 ({0}) の IntelliSense 機能は、タグ パーサーによって提供されます。", - "include_errors_config_provider_squiggles_disabled ": "configurationProvider 設定によって提供された情報に基づいて、#include エラーが検出されました。この翻訳単位 ({0}) では、波線が無効になっています。" + "include_errors_config_provider_squiggles_disabled ": "configurationProvider 設定によって提供された情報に基づいて、#include エラーが検出されました。この翻訳単位 ({0}) では、波線が無効になっています。", + "preprocessor_keyword": "プリプロセッサ キーワード", + "c_keyword": "C キーワード", + "cpp_keyword": "C++ キーワード", + "overload": "+1 個のオーバーロード", + "overloads": "+%d 個のオーバーロード", + "specialization": "+1 個の特殊化", + "specializations": "+%d 個の特殊化", + "expands_to": "展開先:", + "file_label": "ファイル:", + "parameters_label": "パラメーター:", + "returns_label": "戻り値:", + "deprecated_label": "非推奨:", + "exceptions_label": "例外:" } \ No newline at end of file diff --git a/Extension/i18n/kor/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/kor/c_cpp_properties.schema.json.i18n.json index f5ab48b46e..9c378bbe47 100644 --- a/Extension/i18n/kor/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/kor/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "true인 경우 직접적으로 또는 간접적으로 헤더로 포함된 파일만 처리되고, false인 경우 지정된 포함 경로 아래의 모든 파일이 처리됩니다.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "생성된 기호 데이터베이스의 경로입니다. 상대 경로가 지정된 경우 작업 영역의 기본 스토리지 위치에 대해 상대적으로 만들어집니다.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "포함된 헤더를 검색하는 동안 사용할 태그 파서의 경로 목록입니다. 기본적으로 이 경로 검색은 재귀적입니다. 비재귀적 검색을 나타내려면 '*'를 지정합니다. 예: '/usr/include'는 모든 하위 디렉터리를 검색하지만 '/usr/include/*'는 하위 디렉터리를 검색하지 않습니다.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "launch.json 또는 tasks.json의 입력 변수에 사용하기 위해 ${cpptools:activeConfigCustomVariable} 명령을 통해 쿼리할 수 있는 사용자 지정 변수입니다.", "c_cpp_properties.schema.json.definitions.env": "${변수} 또는 ${환경 변수} 구문을 사용하여 이 파일 내 어디서나 재사용할 수 있는 사용자 지정 변수입니다.", "c_cpp_properties.schema.json.definitions.version": "구성 파일의 버전입니다. 이 속성은 확장에서 관리합니다. 변경하지 마세요.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "확장이 c_cpp_properties.json에서 탐지된 오류를 보고하도록 할지를 제어합니다." diff --git a/Extension/i18n/kor/package.i18n.json b/Extension/i18n/kor/package.i18n.json index 7dc4284f41..8412fb63c8 100644 --- a/Extension/i18n/kor/package.i18n.json +++ b/Extension/i18n/kor/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "\"browse.limitSymbolsToIncludedHeaders\"가 지정되지 않거나 \"${default}\"로 설정된 경우 구성에서 사용할 값입니다.", "c_cpp.configuration.default.systemIncludePath.description": "시스템 포함 경로에 사용할 값입니다. 설정하는 경우 \"compilerPath\" 및 \"compileCommands\" 설정을 통해 얻은 시스템 포함 경로를 재정의합니다.", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "확장이 c_cpp_properties.json에서 검색된 오류를 보고할지 여부를 제어합니다.", + "c_cpp.configuration.default.customConfigurationVariables.description": "\"customConfigurationVariables\"가 설정되지 않은 경우 구성에서 사용할 값 또는 \"${default}\"가 \"customConfigurationVariables\"에 키로 존재하는 경우 삽입할 값입니다.", "c_cpp.configuration.updateChannel.description": "예정된 기능과 버그 수정을 포함하는 확장의 최신 참가자 빌드를 자동으로 다운로드하여 설치하려면 \"참가자\"로 설정합니다.", "c_cpp.configuration.experimentalFeatures.description": "\"실험적\" 기능을 사용할 수 있는지 여부를 제어합니다.", "c_cpp.configuration.suggestSnippets.description": "True이면 언어 서버에서 코드 조각을 제공합니다.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "실행할 정규화된 파이프 명령입니다.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "연결을 구성하기 위해 파이프 프로그램에 전달되는 명령줄 인수입니다.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "파이프 프로그램에 전달되는 환경 변수입니다.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "pipeProgram의 개별 인수가 문자(예: 공백 또는 탭)를 포함하는 경우 따옴표를 붙여야 하나요? 'false'인 경우 디버거 명령은 더 이상 자동으로 따옴표를 붙이지 않습니다. \n기본값은 'true'입니다.", "c_cpp.debuggers.logging.description": "메시지 유형을 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다.", "c_cpp.debuggers.logging.exceptions.description": "예외 메시지를 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다. 기본값은 true입니다.", "c_cpp.debuggers.logging.moduleLoad.description": "모듈 로드 이벤트를 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다. 기본값은 true입니다.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "진단 디버그 엔진 메시지를 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다. 기본값은 false입니다.", "c_cpp.debuggers.logging.trace.description": "진단 어댑터 명령 추적을 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다. 기본값은 false입니다.", "c_cpp.debuggers.logging.traceResponse.description": "진단 어댑터 명령 및 응답 추적을 디버그 콘솔에 기록할지 여부를 결정하는 선택적 플래그입니다. 기본값은 false입니다.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "스레드 종료 메시지를 디버그 콘솔에 기록할지를 결정하는 선택적 플래그입니다. 기본값: `false`.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "대상 프로세스 종료 메시지를 디버그 콘솔에 기록할지 또는 디버깅을 중지할지를 결정하는 선택적 플래그입니다. 기본값: `true`.", "c_cpp.debuggers.text.description": "실행할 디버거 명령입니다.", "c_cpp.debuggers.description.description": "명령에 대한 선택적 설명입니다.", "c_cpp.debuggers.ignoreFailures.description": "True이면 명령 실패가 무시됩니다. 기본값은 false입니다.", diff --git a/Extension/i18n/kor/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/kor/src/Debugger/configurationProvider.i18n.json index b52c39bd69..f0fcceb083 100644 --- a/Extension/i18n/kor/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/kor/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "'{0}' 형식 디버거는 Windows에서만 사용할 수 있습니다. 현재 OS 플랫폼에서는 '{1}' 형식을 사용하세요.", "lldb.framework.install.xcode": "추가 정보", "lldb.framework.not.found": "lldb-mi에 대한 'LLDB.framework'를 찾을 수 없습니다. XCode 또는 XCode 명령줄 도구를 설치하세요.", + "debugger.launchConfig": "시작 구성:", "lldb.find.failed": "lldb-mi 실행 파일에 대한 '{0}' 종속성이 없습니다.", "lldb.search.paths": "다음에서 검색됨:", "lldb.install.help": "이 문제를 해결하려면 Apple App Store를 통해 XCode를 설치하거나, 터미널 창에서 '{0}'을(를) 실행하여 XCode 명령줄 도구를 설치하세요.", diff --git a/Extension/i18n/kor/src/nativeStrings.i18n.json b/Extension/i18n/kor/src/nativeStrings.i18n.json index 9add841bfe..7e7de4cfec 100644 --- a/Extension/i18n/kor/src/nativeStrings.i18n.json +++ b/Extension/i18n/kor/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "컴파일러를 쿼리하지 못했습니다. 0비트로 대체하는 중입니다.", "intellisense_client_creation_aborted": "IntelliSense 클라이언트 만들기가 중단되었습니다. {0}", "include_errors_config_provider_intellisense_disabled ": "configurationProvider 설정에서 제공하는 정보를 기준으로 #include 오류가 검색되었습니다. 태그 파서가 이 변환 단위({0})에 적합한 IntelliSense 기능을 제공합니다.", - "include_errors_config_provider_squiggles_disabled ": "configurationProvider 설정에서 제공하는 정보를 기준으로 #include 오류가 검색되었습니다. 이 변환 단위({0})에서 물결선을 사용할 수 없습니다." + "include_errors_config_provider_squiggles_disabled ": "configurationProvider 설정에서 제공하는 정보를 기준으로 #include 오류가 검색되었습니다. 이 변환 단위({0})에서 물결선을 사용할 수 없습니다.", + "preprocessor_keyword": "전처리기 키워드", + "c_keyword": "C 키워드", + "cpp_keyword": "C++ 키워드", + "overload": "+1개 오버로드", + "overloads": "+%d개 오버로드", + "specialization": "+1개 특수화", + "specializations": "+%d개 특수화", + "expands_to": "다음으로 확장:", + "file_label": "파일:", + "parameters_label": "매개 변수:", + "returns_label": "반환 값:", + "deprecated_label": "사용되지 않음:", + "exceptions_label": "예외:" } \ No newline at end of file diff --git a/Extension/i18n/plk/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/plk/c_cpp_properties.schema.json.i18n.json index 16c890d37b..a3ff78fff6 100644 --- a/Extension/i18n/plk/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/plk/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "Wartość true, aby przetwarzać tylko pliki bezpośrednio lub pośrednio dołączone jako nagłówki. Wartość false, aby przetwarzać wszystkie pliki w określonych ścieżkach dołączania.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Ścieżka do generowanej bazy danych symboli. Jeśli zostanie określona ścieżka względna, będzie to ścieżka względem domyślnej lokalizacji magazynowania obszaru roboczego.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Lista ścieżek, których analizator tagów ma używać podczas wyszukiwania dołączanych nagłówków. Wyszukiwanie w tych ścieżkach jest domyślnie rekurencyjne. Użyj znaku „*”, aby określić wyszukiwanie nierekurencyjne. Na przykład wartość „/usr/include” spowoduje przeszukanie wszystkich podkatalogów, w przeciwieństwie do wartości „/usr/include/*”.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Zmienne niestandardowe, względem których można wykonywać zapytania za pomocą polecenia ${cpptools:activeConfigCustomVariable}, aby użyć ich na potrzeby zmiennych wejściowych w plikach launch.js lub tasks.js.", "c_cpp_properties.schema.json.definitions.env": "Zmienne niestandardowe, których można używać ponownie w dowolnym miejscu tego pliku przy użyciu składni ${zmienna} lub ${env:zmienna}.", "c_cpp_properties.schema.json.definitions.version": "Wersja pliku konfiguracji. Tą właściwością zarządza rozszerzenie. Nie zmieniaj jej.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Określa, czy rozszerzenie będzie raportować błędy wykryte w pliku c_cpp_properties.json." diff --git a/Extension/i18n/plk/package.i18n.json b/Extension/i18n/plk/package.i18n.json index f7a1eb9445..7bd0a15d92 100644 --- a/Extension/i18n/plk/package.i18n.json +++ b/Extension/i18n/plk/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Wartość do użycia w konfiguracji, jeśli element „browse.limitSymbolsToIncludedHeaders” nie został określony lub ma wartość „${default}”.", "c_cpp.configuration.default.systemIncludePath.description": "Wartość do użycia na potrzeby ścieżki dołączania systemu. Jeśli jest ustawiona, zastępuje systemową ścieżką dołączania, którą można uzyskać za pomocą ustawień „compilerPath” i „compileCommands”.", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Określa, czy rozszerzenie będzie raportować błędy wykryte w pliku c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Wartość do użycia w konfiguracji, jeśli element „customConfigurationVariables” nie został ustawiony, lub wartości do wstawienia, jeśli element „${default}” istnieje jako klucz w ramach elementu „customConfigurationVariables”.", "c_cpp.configuration.updateChannel.description": "Ustaw na wartość „Insiders”, aby automatycznie pobrać i zainstalować najnowsze kompilacje niejawnych testerów rozszerzenia, które zawierają nadchodzące funkcje i poprawki błędów.", "c_cpp.configuration.experimentalFeatures.description": "Określa, czy można używać funkcji „eksperymentalnych”.", "c_cpp.configuration.suggestSnippets.description": "Jeśli wartość to true, fragmenty kodu są udostępniane przez serwer języka.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Polecenie w pełni kwalifikowanego potoku do wykonania.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Argumenty wiersza polecenia przekazywane do programu potoku w celu skonfigurowania połączenia.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Zmienne środowiskowe przekazywane do programu potoku.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Jeśli poszczególne argumenty elementu pipeProgram zawierają znaki (takie jak spacje lub tabulatory), czy mają być umieszczane w cudzysłowach? W przypadku wartości „false” polecenie debugera nie będzie już automatycznie umieszczane w cudzysłowach. \nWartość domyślna to „true”.", "c_cpp.debuggers.logging.description": "Opcjonalne flagi określające, które typy komunikatów powinny być rejestrowane w konsoli debugowania.", "c_cpp.debuggers.logging.exceptions.description": "Opcjonalna flaga określająca, czy komunikaty o wyjątkach powinny być rejestrowane w konsoli debugowania. Wartość domyślna to false.", "c_cpp.debuggers.logging.moduleLoad.description": "Opcjonalna flaga określająca, czy zdarzenia ładowania modułów powinny być rejestrowane w konsoli debugowania. Wartość domyślna to false.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Opcjonalna flaga określająca, czy komunikaty aparatu adaptera debugowania diagnostycznego powinny być rejestrowane w konsoli debugowania. Wartość domyślna to false.", "c_cpp.debuggers.logging.trace.description": "Opcjonalna flaga określająca, czy śledzenie polecenia adaptera diagnostycznego powinno być rejestrowane w konsoli debugowania. Wartość domyślna to false.", "c_cpp.debuggers.logging.traceResponse.description": "Opcjonalna flaga określająca, czy śledzenie polecenia adaptera diagnostycznego i odpowiedzi powinno być rejestrowane w konsoli debugowania. Wartość domyślna to false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Opcjonalna flaga określająca, czy komunikaty dotyczące zamknięcia wątku powinny być rejestrowane w konsoli debugowania. Wartość domyślna to „false”.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Opcjonalna flaga określająca, czy komunikaty dotyczące zamknięcia procesu docelowego powinny być rejestrowane w konsoli debugowania, czy debugowanie ma zostać zatrzymane. Wartość domyślna: „true”.", "c_cpp.debuggers.text.description": "Polecenie debugera do wykonania.", "c_cpp.debuggers.description.description": "Opcjonalny opis polecenia.", "c_cpp.debuggers.ignoreFailures.description": "Jeśli wartość to true, niepowodzenia polecenia powinny być ignorowane. Wartość domyślna to false.", diff --git a/Extension/i18n/plk/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/plk/src/Debugger/configurationProvider.i18n.json index 3b6095ab33..972aa722db 100644 --- a/Extension/i18n/plk/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/plk/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Debuger typu: „{0}” jest dostępny tylko w systemie Windows. Użyj typu: „{1}” na bieżącej platformie systemu operacyjnego.", "lldb.framework.install.xcode": "Więcej informacji", "lldb.framework.not.found": "Nie można zlokalizować elementu „LLDB.framework” dla narzędzia lldb-mi. Zainstaluj środowisko XCode lub narzędzia wiersza polecenia środowiska XCode.", + "debugger.launchConfig": "Konfiguracja uruchamiania:", "lldb.find.failed": "Brak zależności „{0}” dla pliku wykonywalnego lldb-mi.", "lldb.search.paths": "Wyszukano w:", "lldb.install.help": "Aby rozwiązać ten problem, zainstaluj środowisko XCode za pośrednictwem sklepu Apple App Store lub zainstaluj narzędzia wiersza polecenia środowiska XCode, uruchamiając polecenie „{0}” w oknie terminala.", diff --git a/Extension/i18n/plk/src/nativeStrings.i18n.json b/Extension/i18n/plk/src/nativeStrings.i18n.json index 687432c2d4..22ac10cbe4 100644 --- a/Extension/i18n/plk/src/nativeStrings.i18n.json +++ b/Extension/i18n/plk/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Nie można wykonać zapytania dotyczącego kompilatora. Powrót do braku liczby bitów.", "intellisense_client_creation_aborted": "Przerwano tworzenie klienta IntelliSense: {0}", "include_errors_config_provider_intellisense_disabled ": "Wykryto błędy #include na podstawie informacji podanych przez ustawienie configurationProvider. Funkcje IntelliSense dla tej jednostki tłumaczeniowej ({0}) będą udostępniane przez analizator tagów.", - "include_errors_config_provider_squiggles_disabled ": "Wykryto błędy #include na podstawie informacji podanych przez ustawienie configurationProvider. Zygzaki dla tej jednostki tłumaczeniowej ({0}) są wyłączone." + "include_errors_config_provider_squiggles_disabled ": "Wykryto błędy #include na podstawie informacji podanych przez ustawienie configurationProvider. Zygzaki dla tej jednostki tłumaczeniowej ({0}) są wyłączone.", + "preprocessor_keyword": "słowo kluczowe preprocesora", + "c_keyword": "Słowo kluczowe języka C", + "cpp_keyword": "Słowo kluczowe języka C++", + "overload": "+1 przeciążenie", + "overloads": "Przeciążenia: +%d", + "specialization": "+1 specjalizacja", + "specializations": "Specjalizacje: +%d", + "expands_to": "Jest rozwijane do:", + "file_label": "Plik:", + "parameters_label": "Parametry:", + "returns_label": "Zwraca:", + "deprecated_label": "Przestarzałe:", + "exceptions_label": "Wyjątki:" } \ No newline at end of file diff --git a/Extension/i18n/ptb/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/ptb/c_cpp_properties.schema.json.i18n.json index a7a0c11a07..cb503cbe01 100644 --- a/Extension/i18n/ptb/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/ptb/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "true para processar somente os arquivos direta ou indiretamente incluídos como cabeçalhos, false para processar todos os arquivos nos caminhos de inclusão especificados.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Caminho para o banco de dados de símbolo gerado. Se um caminho relativo for especificado, ele será criado em relação ao local de armazenamento padrão do workspace.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Uma lista de caminhos para o analisador de marca usar durante a pesquisa de cabeçalhos incluídos. A pesquisa nesses caminhos é recursiva por padrão. Especifique '*' para indicar pesquisa não recursiva. Por exemplo: '/usr/include' pesquisará por todos os subdiretórios enquanto '/usr/include/*' não pesquisará.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Variáveis personalizadas que podem ser consultadas por meio do comando ${cpptools:activeConfigCustomVariable} a serem usadas para as variáveis de entrada no launch.json ou tasks.json.", "c_cpp_properties.schema.json.definitions.env": "Variáveis personalizadas que podem ser reutilizadas em qualquer lugar neste arquivo usando a sintaxe ${variável} ou ${env:variável}.", "c_cpp_properties.schema.json.definitions.version": "Versão do arquivo de configuração. Esta propriedade é gerenciada pela extensão. Não a altere.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Controla se a extensão relatará erros detectados em c_cpp_properties.json." diff --git a/Extension/i18n/ptb/package.i18n.json b/Extension/i18n/ptb/package.i18n.json index ceb50e58af..52b8bae215 100644 --- a/Extension/i18n/ptb/package.i18n.json +++ b/Extension/i18n/ptb/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "O valor a ser usado em uma configuração se a opção \"browse.limitSymbolsToIncludedHeaders\" não for especificada ou estiver definida como \"${default}\".", "c_cpp.configuration.default.systemIncludePath.description": "O valor a ser usado para o caminho de inclusão do sistema. Se definido, substitui o caminho de inclusão do sistema adquirido por meio das configurações \"compilerPath\" e \"compileCommands\".", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Controla se a extensão relatará erros detectados em c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "O valor a ser usado em uma configuração se \"customConfigurationVariables\" não for definido ou os valores a serem inseridos se \"${default}\" estiver presente como uma chave em \"customConfigurationVariables\".", "c_cpp.configuration.updateChannel.description": "Defina como \"Insiders\" para baixar e instalar automaticamente os builds mais recentes do Insiders para a extensão, que incluem recursos futuros e correções de bugs.", "c_cpp.configuration.experimentalFeatures.description": "Controla se os recursos \"experimentais\" podem ser usados.", "c_cpp.configuration.suggestSnippets.description": "Se for true, os snippets serão fornecidos pelo servidor de idiomas.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "O comando do pipe totalmente qualificado para executar.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Argumentos da linha de comando passados para o programa do pipe para configurar a conexão.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Variáveis de ambiente passadas para o programa do pipe.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Se os argumentos individuais do pipeProgram contiverem caracteres (como espaços ou tabulações), eles deverão ser colocados entre aspas? Se 'false', o comando debugger não será mais colocado entre aspas automaticamente. \nO padrão é 'true'.", "c_cpp.debuggers.logging.description": "Sinalizadores opcionais para determinar quais tipos de mensagens devem ser registrados no Console de Depuração.", "c_cpp.debuggers.logging.exceptions.description": "Sinalizador opcional para determinar se as mensagens de exceção devem ser registradas no Console de Depuração. Usa true como padrão.", "c_cpp.debuggers.logging.moduleLoad.description": "Sinalizador opcional para determinar se os eventos de carregamento do módulo devem ser registrados no Console de Depuração. Usa true como padrão.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Sinalizador opcional para determinar se as mensagens do mecanismo de depuração de diagnóstico devem ser registradas no Console de Depuração. Usa false como padrão.", "c_cpp.debuggers.logging.trace.description": "Sinalizador opcional para determinar se o rastreamento de comandos do adaptador de diagnóstico deve ser registrado no Console de Depuração. Usa false como padrão.", "c_cpp.debuggers.logging.traceResponse.description": "Sinalizador opcional para determinar se o rastreamento de resposta e de comandos do adaptador de diagnóstico deve ser registrado no Console de Depuração. Usa false como padrão.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Sinalizador opcional para determinar se as mensagens de saída do thread devem ser registradas no Console de Depuração. Padrão: `false`.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Sinalizador opcional para determinar se o processo de destino sai das mensagens que devem ser registradas no Console de Depuração ou a depuração é interrompida. Padrão: `true`.", "c_cpp.debuggers.text.description": "O comando do depurador a se executar.", "c_cpp.debuggers.description.description": "Descrição opcional para o comando.", "c_cpp.debuggers.ignoreFailures.description": "Se for true, as falhas do comando deverão ser ignoradas. O valor padrão é false.", diff --git a/Extension/i18n/ptb/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/ptb/src/Debugger/configurationProvider.i18n.json index 89570c5d0e..3f5fb2ccc8 100644 --- a/Extension/i18n/ptb/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/ptb/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Depurador do tipo: '{0}' só está disponível no Windows. Use o tipo: '{1}' na plataforma do SO atual.", "lldb.framework.install.xcode": "Mais Informações", "lldb.framework.not.found": "Não é possível localizar 'LLDB.framework' para lldb-mi. Instale o XCode ou as Ferramentas de Linha de Comando do XCode.", + "debugger.launchConfig": "Iniciar configuração:", "lldb.find.failed": "Dependência ausente '{0}' no executável lldb-mi.", "lldb.search.paths": "Pesquisado em:", "lldb.install.help": "Para resolver esse problema, instale o XCode por meio da Apple App Store ou instale as Ferramentas de Linha de Comando do XCode executando '{0}' em uma janela de Terminal.", diff --git a/Extension/i18n/ptb/src/nativeStrings.i18n.json b/Extension/i18n/ptb/src/nativeStrings.i18n.json index f460fe055a..354f50b5aa 100644 --- a/Extension/i18n/ptb/src/nativeStrings.i18n.json +++ b/Extension/i18n/ptb/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Falha ao consultar o compilador. Voltando para nenhum número de bit.", "intellisense_client_creation_aborted": "Criação de cliente do IntelliSense anulada: {0}", "include_errors_config_provider_intellisense_disabled ": "#inclui erros detectados com base nas informações fornecidas pela configuração configurationProvider. Os recursos do IntelliSense para essa unidade de conversão ({0}) serão fornecidos pelo Analisador de Marca.", - "include_errors_config_provider_squiggles_disabled ": "#inclui erros detectados com base nas informações fornecidas pela configuração configurationProvider. Os rabiscos estão desabilitados para esta unidade de tradução ({0})." + "include_errors_config_provider_squiggles_disabled ": "#inclui erros detectados com base nas informações fornecidas pela configuração configurationProvider. Os rabiscos estão desabilitados para esta unidade de tradução ({0}).", + "preprocessor_keyword": "palavra-chave do pré-processador", + "c_keyword": "Palavra-chave C", + "cpp_keyword": "Palavra-chave C++", + "overload": "Mais 1 sobrecarga", + "overloads": "Mais %d sobrecargas", + "specialization": "Mais 1 especialização", + "specializations": "Mais %d especializações", + "expands_to": "Expande para:", + "file_label": "Arquivo:", + "parameters_label": "Parâmetros:", + "returns_label": "Retorna:", + "deprecated_label": "Preterido:", + "exceptions_label": "Exceções:" } \ No newline at end of file diff --git a/Extension/i18n/rus/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/rus/c_cpp_properties.schema.json.i18n.json index 4f7048bfce..07443771cf 100644 --- a/Extension/i18n/rus/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/rus/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "При значении true (истина) будут обрабатываться только файлы, прямо или косвенно включенные как файлы заголовков, а при значении false (ложь) — все файлы по указанным путям для включений.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Путь к создаваемой базе данных символов. При указании относительного пути он будет отсчитываться от используемого в рабочей области места хранения по умолчанию.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Список путей для анализатора тегов, используемый при поиске включаемых файлов заголовков. Поиск по этим путям по умолчанию рекурсивный. Чтобы использовать нерекурсивный, укажите \"*\". Например, если указать \"/usr/include\", будет выполнен поиск по всем подкаталогам, а если \"/usr/include/*\" — не будет.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "Пользовательские переменные, которые можно запросить с помощью команды ${cpptools:activeConfigCustomVariable}, чтобы использовать в качестве входных переменных в файле launch.js или tasks.js.", "c_cpp_properties.schema.json.definitions.env": "Пользовательские переменные, которые могут многократно применяться в любом месте этого файла с помощью синтаксиса ${переменная} или ${env:переменная}.", "c_cpp_properties.schema.json.definitions.version": "Версия файла конфигурации. Этим свойством управляет расширение. Не изменяйте его.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Определяет, будет ли расширение сообщать об ошибках, обнаруженных в c_cpp_properties.json." diff --git a/Extension/i18n/rus/package.i18n.json b/Extension/i18n/rus/package.i18n.json index 92f6da3303..315326d1de 100644 --- a/Extension/i18n/rus/package.i18n.json +++ b/Extension/i18n/rus/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "Значение, используемое в конфигурации, если параметр \"browse.limitSymbolsToIncludedHeaders\" не указан или имеет значение \"${default}\".", "c_cpp.configuration.default.systemIncludePath.description": "Значение, используемое для системного пути включения. Если этот параметр задан, он переопределяет системный путь включения, полученный с помощью параметров \"compilerPath\" и \"compileCommands\".", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Определяет, будет ли расширение сообщать об ошибках, обнаруженных в c_cpp_properties.json.", + "c_cpp.configuration.default.customConfigurationVariables.description": "Значение, используемое в конфигурации, если параметр \"customConfigurationVariables\" не установлен, или вставляемые значения, если в \"customConfigurationVariables\" присутствует значение \"${default}\" в качестве ключа.", "c_cpp.configuration.updateChannel.description": "Укажите значение \"Участники программы предварительной оценки\", чтобы автоматически скачать и установить последние сборки программы предварительной оценки, включающие в себя запланированные функции и исправления ошибок.", "c_cpp.configuration.experimentalFeatures.description": "Определяет, можно ли использовать \"экспериментальные\" функции.", "c_cpp.configuration.suggestSnippets.description": "Если задано значение true, фрагменты кода предоставляются языковым сервером.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Полная команда канала для выполнения.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Аргументы командной строки, переданные в программу канала для настройки подключения.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Переменные среды, переданные в программу канала.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Определяет, должны ли быть заключены в кавычки отдельные аргументы pipeProgram, если эти аргументы содержат символы (такие как пробелы или символы табуляции). Если задано значение \"false\", команда отладчика больше не будет автоматически заключаться в кавычки. \nЗначение по умолчанию — \"true\".", "c_cpp.debuggers.logging.description": "Необязательные флаги для определения типов сообщений, регистрируемых в консоли отладки.", "c_cpp.debuggers.logging.exceptions.description": "Необязательный флаг, определяющий, следует ли регистрировать сообщения об исключениях в консоли отладки. По умолчанию принимает значение true.", "c_cpp.debuggers.logging.moduleLoad.description": "Необязательный флаг, определяющий, следует ли регистрировать события загрузки модулей в консоли отладки. По умолчанию принимает значение true.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Необязательный флаг, определяющий, следует ли регистрировать сообщения диагностического модуля отладки в консоли отладки. По умолчанию принимает значение false.", "c_cpp.debuggers.logging.trace.description": "Необязательный флаг, определяющий, следует ли регистрировать трассировку команд диагностического адаптера в консоли отладки. По умолчанию принимает значение false.", "c_cpp.debuggers.logging.traceResponse.description": "Необязательный флаг, определяющий, следует ли регистрировать трассировку команд и ответов диагностического адаптера в консоли отладки. По умолчанию принимает значение false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Необязательный флаг, определяющий, следует ли записывать сообщения о выходе для потоков в консоль отладки. Значение по умолчанию: \"false\".", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Необязательный флаг, определяющий, следует ли записывать сообщения о выходе для целевого процесса в консоль отладки или останавливать отладку. Значение по умолчанию: \"true\".", "c_cpp.debuggers.text.description": "Команда отладчика для выполнения.", "c_cpp.debuggers.description.description": "Необязательное описание команды.", "c_cpp.debuggers.ignoreFailures.description": "Если задано значение true, сбои этой команды должны игнорироваться. Значение по умолчанию — false.", diff --git a/Extension/i18n/rus/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/rus/src/Debugger/configurationProvider.i18n.json index 8e2f306777..d9e9cf0a25 100644 --- a/Extension/i18n/rus/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/rus/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "Отладчик типа \"{0}\" доступен только в Windows. Используйте тип \"{1}\" на текущей платформе ОС.", "lldb.framework.install.xcode": "Дополнительные сведения", "lldb.framework.not.found": "Не удается найти \"LLDB.framework\" для lldb-mi. Установите XCode или средства командной строки XCode.", + "debugger.launchConfig": "Конфигурация запуска:", "lldb.find.failed": "Отсутствует зависимость \"{0}\" для исполняемого файла lldb-mi.", "lldb.search.paths": "Поиск был выполнен в следующих расположениях:", "lldb.install.help": "Чтобы устранить эту проблему, установите XCode через Apple App Store или установите средства командной строки XCode, выполнив команду \"{0}\" в окне терминала.", diff --git a/Extension/i18n/rus/src/nativeStrings.i18n.json b/Extension/i18n/rus/src/nativeStrings.i18n.json index 38731215c9..5a933c10d7 100644 --- a/Extension/i18n/rus/src/nativeStrings.i18n.json +++ b/Extension/i18n/rus/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Не удалось запросить сведения от компилятора. Возврат к режиму без использования разрядности.", "intellisense_client_creation_aborted": "Создание клиента IntelliSense прервано: {0}", "include_errors_config_provider_intellisense_disabled ": "обнаружены ошибки #include на основе сведений, предоставленных параметром configurationProvider. Функции IntelliSense для этой записи преобразования ({0}) будут предоставлены анализатором тегов.", - "include_errors_config_provider_squiggles_disabled ": "Обнаружены ошибки #include на основе сведений, предоставленных параметром configurationProvider. Волнистые линии для этой записи преобразования ({0}) отключены." + "include_errors_config_provider_squiggles_disabled ": "Обнаружены ошибки #include на основе сведений, предоставленных параметром configurationProvider. Волнистые линии для этой записи преобразования ({0}) отключены.", + "preprocessor_keyword": "ключевое слово препроцессора", + "c_keyword": "Ключевое слово C", + "cpp_keyword": "Ключевое слово C++", + "overload": "и еще одна перегрузка", + "overloads": "и другие перегрузки (%d)", + "specialization": "и еще одна специализация", + "specializations": "и другие специализации (%d)", + "expands_to": "Расширяется в:", + "file_label": "Файл:", + "parameters_label": "Параметры:", + "returns_label": "Возвращает:", + "deprecated_label": "Нерекомендуемый:", + "exceptions_label": "Исключения:" } \ No newline at end of file diff --git a/Extension/i18n/trk/c_cpp_properties.schema.json.i18n.json b/Extension/i18n/trk/c_cpp_properties.schema.json.i18n.json index f68fcad160..8ec987c675 100644 --- a/Extension/i18n/trk/c_cpp_properties.schema.json.i18n.json +++ b/Extension/i18n/trk/c_cpp_properties.schema.json.i18n.json @@ -20,6 +20,7 @@ "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.limitSymbolsToIncludedHeaders": "yalnızca doğrudan veya dolaylı olarak üst bilgi olarak dahil edilen dosyaları işlemek için true, belirtilen ekleme yolları altındaki tüm dosyaları işlemek için false.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.databaseFilename": "Oluşturulan sembol veritabanının yolu. Göreli bir yol belirtilirse, çalışma alanının varsayılan depolama konumuna göreli hale getirilir.", "c_cpp_properties.schema.json.definitions.configurations.items.properties.browse.properties.path": "Etiket ayrıştırıcısının eklenen üst bilgileri ararken kullanacağı yol listesi. Bu yollarda arama varsayılan olarak özyinelemelidir. Özyinelemeli olmayan aramayı göstermek için '*' belirtin. Örneğin: '/usr/include' tüm alt dizinlerde arar ancak '/usr/include/*' aramaz.", + "c_cpp_properties.schema.json.definitions.configurations.items.properties.customConfigurationVariables": "launch.json veya tasks.json içindeki giriş bağımsız değişkenleri için kullanılacak, ${cpptools:activeConfigCustomVariable} komutu aracılığıyla sorgulanabilen özel değişkenler.", "c_cpp_properties.schema.json.definitions.env": "${değişken} veya ${env:değişken} söz dizimi kullanılarak bu dosyada herhangi bir yerde yeniden kullanılabilen özel değişkenler.", "c_cpp_properties.schema.json.definitions.version": "Yapılandırma dosyasının sürümü. Bu özellik uzantı tarafından yönetilir. Lütfen değiştirmeyin.", "c_cpp_properties.schema.json.definitions.enableConfigurationSquiggles": "Uzantının c_cpp_properties.json dosyasında algılanan hataları bildirip bildirmeyeceğini denetler." diff --git a/Extension/i18n/trk/package.i18n.json b/Extension/i18n/trk/package.i18n.json index bca6208709..555a6adb27 100644 --- a/Extension/i18n/trk/package.i18n.json +++ b/Extension/i18n/trk/package.i18n.json @@ -65,6 +65,7 @@ "c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "\"browse.limitSymbolsToIncludedHeaders\" belirtilmemişse veya \"${default}\" olarak ayarlanmamışsa bir yapılandırmada kullanılacak değer.", "c_cpp.configuration.default.systemIncludePath.description": "Sistem ekleme yolu için kullanılacak değer. Ayarlanırsa \"compilerPath\" ve \"compileCommands\" ayarları aracılığıyla elde edilen sistem ekleme yolunu geçersiz kılar.", "c_cpp.configuration.default.enableConfigurationSquiggles.description": "Uzantının c_cpp_properties.json dosyasında algılanan hataları bildirip bildirmeyeceğini denetler.", + "c_cpp.configuration.default.customConfigurationVariables.description": "\"customConfigurationVariables\" ayarlanmamışsa bir yapılandırmada kullanılacak değer veya \"customConfigurationVariables\" içinde anahtar olarak \"${default}\" varsa eklenecek değerler.", "c_cpp.configuration.updateChannel.description": "Uzantının, gelecek özellikleri ve hata düzeltmelerini de içeren en son Insider üyeleri derlemelerini otomatik olarak indirip yüklemek için \"Insider üyeleri\" olarak ayarlayın.", "c_cpp.configuration.experimentalFeatures.description": "\"Deneysel\" özelliklerin kullanılabilir olup olmadığını denetler.", "c_cpp.configuration.suggestSnippets.description": "Değer true ise, kod parçacıkları dil sunucusu tarafından sağlanır.", @@ -82,6 +83,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "Çalıştırılacak tam kanal komutu.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Bağlantıyı yapılandırmak için kanal programına geçirilen komut satırı bağımsız değişkenleri.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Kanal programına geçirilen ortam değişkenleri.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "pipeProgram'a ait tek tek bağımsız değişkenler, boşluk veya sekme gibi karakterler içeriyorsa bunlar tırnak içine alınmalı mı? 'False' olarak ayarlanırsa, hata ayıklayıcısı komutu otomatik olarak tırnak içine alınmaz. \nVarsayılan değer: 'true'.", "c_cpp.debuggers.logging.description": "Hata Ayıklama Konsoluna ne tür iletilerin kaydedilmesi gerektiğini belirleyen isteğe bağlı bayraklar.", "c_cpp.debuggers.logging.exceptions.description": "Özel durum iletilerinin Hata Ayıklama Konsoluna kaydedilmesi gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan olarak true değerini alır.", "c_cpp.debuggers.logging.moduleLoad.description": "Modül yükleme olaylarının Hata Ayıklama Konsoluna kaydedilmesi gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan olarak true değerini alır.", @@ -89,6 +91,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Tanılama hata ayıklama altyapısı iletilerinin Hata Ayıklama Konsoluna kaydedilmesi gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan olarak false değerini alır.", "c_cpp.debuggers.logging.trace.description": "Tanılama bağdaştırıcısı komut izlemenin Hata Ayıklama Konsoluna kaydedilmesi gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan olarak false değerini alır.", "c_cpp.debuggers.logging.traceResponse.description": "Tanılama bağdaştırıcısı komut ve yanıt izlemenin Hata Ayıklama Konsoluna kaydedilmesi gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan olarak false değerini alır.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "İş parçacığı çıkışı iletilerinin Hata Ayıklama Konsolu'na kaydedilmesinin gerekip gerekmediğini belirleyen isteğe bağlı bayrak. Varsayılan: `false`.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Hedef işlem çıkışı iletilerinin Hata Ayıklama Konsolu'na kaydedilmesinin gerekip gerekmediğini veya hata ayıklama işleminin durdurulup durdurulmadığını belirleyen isteğe bağlı bayrak. Varsayılan: `true`.", "c_cpp.debuggers.text.description": "Çalıştırılacak hata ayıklayıcısı komutu.", "c_cpp.debuggers.description.description": "Komut için isteğe bağlı açıklama.", "c_cpp.debuggers.ignoreFailures.description": "Değer true ise komuttan gönderilen hatalar yoksayılmalıdır. Varsayılan olarak false değerini alır.", diff --git a/Extension/i18n/trk/src/Debugger/configurationProvider.i18n.json b/Extension/i18n/trk/src/Debugger/configurationProvider.i18n.json index c6db94472b..5879c92013 100644 --- a/Extension/i18n/trk/src/Debugger/configurationProvider.i18n.json +++ b/Extension/i18n/trk/src/Debugger/configurationProvider.i18n.json @@ -10,6 +10,7 @@ "debugger.not.available": "'{0}' türündeki hata ayıklayıcısı yalnızca Windows'da kullanılabilir. Geçerli işletim sistemi platformunda '{1}' türünü kullanın.", "lldb.framework.install.xcode": "Daha Fazla Bilgi", "lldb.framework.not.found": "lldb-mi için 'LLDB.framework' bulunamıyor. Lütfen XCode'u veya XCode Komut Satırı Araçları'nı yükleyin.", + "debugger.launchConfig": "Yapılandırmayı başlat:", "lldb.find.failed": "lldb-mi yürütülebilir dosyası için '{0}' bağımlılığı eksik.", "lldb.search.paths": "Şurada arandı:", "lldb.install.help": "Bu sorunu çözmek için, Apple App Store üzerinden XCode'u yükleyin ya da bir Terminal penceresinde '{0}' çalıştırarak XCode Komut Satırı Araçları'nı yükleyin.", diff --git a/Extension/i18n/trk/src/nativeStrings.i18n.json b/Extension/i18n/trk/src/nativeStrings.i18n.json index eb84edde13..e5c9125517 100644 --- a/Extension/i18n/trk/src/nativeStrings.i18n.json +++ b/Extension/i18n/trk/src/nativeStrings.i18n.json @@ -162,5 +162,18 @@ "fallback_to_no_bitness": "Derleyici sorgulanamadı. Bit genişliği yok durumuna geri dönülüyor.", "intellisense_client_creation_aborted": "IntelliSense istemcisi oluşturma işlemi durduruldu: {0}", "include_errors_config_provider_intellisense_disabled ": "configurationProvider ayarı tarafından sağlanan bilgilere göre #include hataları saptandı. Bu çeviri birimi ({0}) için IntelliSense özellikleri Etiket Ayrıştırıcısı tarafından sağlanır.", - "include_errors_config_provider_squiggles_disabled ": "configurationProvider ayarı tarafından sağlanan bilgilere göre #include hataları saptandı. Bu çeviri birimi ({0}) için dalgalı çizgiler devre dışı bırakıldı." + "include_errors_config_provider_squiggles_disabled ": "configurationProvider ayarı tarafından sağlanan bilgilere göre #include hataları saptandı. Bu çeviri birimi ({0}) için dalgalı çizgiler devre dışı bırakıldı.", + "preprocessor_keyword": "ön işlemci anahtar sözcüğü", + "c_keyword": "C anahtar sözcüğü", + "cpp_keyword": "C++ anahtar sözcüğü", + "overload": "1 aşırı yükleme daha", + "overloads": "%d aşırı yükleme daha", + "specialization": "1 özelleştirme daha", + "specializations": "%d özelleştirme daha", + "expands_to": "Şu öğeye genişler:", + "file_label": "Dosya:", + "parameters_label": "Parametreler:", + "returns_label": "Şunu döndürür:", + "deprecated_label": "Kullanım dışı:", + "exceptions_label": "Özel durumlar:" } \ No newline at end of file diff --git a/Extension/package.json b/Extension/package.json index d28b558a43..3e0a3141f0 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -2,7 +2,7 @@ "name": "cpptools", "displayName": "C/C++", "description": "C/C++ IntelliSense, debugging, and code browsing.", - "version": "0.28.3", + "version": "0.29.0", "publisher": "ms-vscode", "preview": true, "icon": "LanguageCCPP_color_128x.png", @@ -12,7 +12,7 @@ }, "license": "SEE LICENSE IN LICENSE.txt", "engines": { - "vscode": "^1.43.0" + "vscode": "^1.44.0" }, "bugs": { "url": "https://github.com/Microsoft/vscode-cpptools/issues", @@ -52,6 +52,13 @@ } ] }, + "viewsWelcome": [ + { + "view": "debug", + "contents": "To learn more about launch.json, see [Configuring C/C++ debugging](https://code.visualstudio.com/docs/cpp/launch-json-reference).", + "when": "debugStartLanguage == cpp || debugStartLanguage == c" + } + ], "problemMatchers": [ { "name": "gcc", @@ -243,6 +250,12 @@ "description": "%c_cpp.configuration.preferredPathSeparator.description%", "scope": "machine-overridable" }, + "C_Cpp.simplifyStructuredComments": { + "type": "boolean", + "default": true, + "description": "%c_cpp.configuration.simplifyStructuredComments.description%", + "scope": "application" + }, "C_Cpp.commentContinuationPatterns": { "type": "array", "default": [ @@ -672,6 +685,10 @@ { "type": "cppdbg", "label": "C++ (GDB/LLDB)", + "languages": [ + "c", + "cpp" + ], "variables": { "pickProcess": "extension.pickNativeProcess", "pickRemoteProcess": "extension.pickRemoteNativeProcess" @@ -964,6 +981,13 @@ }, "description": "%c_cpp.debuggers.pipeTransport.pipeEnv.description%", "default": {} + }, + "quoteArgs": { + "exceptions": { + "type": "boolean", + "description": "%c_cpp.debuggers.pipeTransport.quoteArgs.description%", + "default": true + } } } }, @@ -1150,6 +1174,13 @@ }, "description": "%c_cpp.debuggers.pipeTransport.pipeEnv.description%", "default": {} + }, + "quoteArgs": { + "exceptions": { + "type": "boolean", + "description": "%c_cpp.debuggers.pipeTransport.quoteArgs.description%", + "default": true + } } } }, @@ -1206,6 +1237,10 @@ { "type": "cppvsdbg", "label": "C++ (Windows)", + "languages": [ + "c", + "cpp" + ], "variables": { "pickProcess": "extension.pickNativeProcess" }, @@ -1324,6 +1359,16 @@ "type": "boolean", "description": "%c_cpp.debuggers.logging.engineLogging.description%", "default": false + }, + "threadExit": { + "type": "boolean", + "description": "%c_cpp.debuggers.cppvsdbg.logging.threadExit.description%", + "default": false + }, + "processExit": { + "type": "boolean", + "description": "%c_cpp.debuggers.cppvsdbg.logging.processExit.description%", + "default": true } } }, @@ -1500,16 +1545,150 @@ "configurationDefaults": { "[cpp]": { "editor.wordBasedSuggestions": false, - "editor.suggest.insertMode": "replace" + "editor.suggest.insertMode": "replace", + "editor.semanticHighlighting.enabled": true }, "[c]": { "editor.wordBasedSuggestions": false, - "editor.suggest.insertMode": "replace" + "editor.suggest.insertMode": "replace", + "editor.semanticHighlighting.enabled": true }, "[Log]": { "editor.wordWrap": "off" } - } + }, + "semanticTokenTypes": [ + { + "id": "referenceType", + "superType": "class", + "description": "A C++/CLI reference type." + }, + { + "id": "cliProperty", + "superType": "property", + "description": "A C++/CLI property." + }, + { + "id": "genericType", + "superType": "class", + "description": "A C++/CLI generic type." + }, + { + "id": "valueType", + "superType": "class", + "description": "A C++/CLI value type." + }, + { + "id": "templateFunction", + "superType": "function", + "description": "A template function." + }, + { + "id": "templateType", + "superType": "class", + "description": "A template type." + }, + { + "id": "operatorOverload", + "superType": "operator", + "description": "An overloaded operator." + }, + { + "id": "memberOperatorOverload", + "superType": "operator", + "description": "An overloaded operator member function." + }, + { + "id": "newOperator", + "superType": "operator", + "description": "A C++ new or delete operator." + }, + { + "id": "customLiteral", + "superType": "number", + "description": "A user-defined literal." + }, + { + "id": "numberLiteral", + "superType": "number", + "description": "A user-defined literal number." + }, + { + "id": "stringLiteral", + "superType": "string", + "description": "A user-defined literal string." + } + ], + "semanticTokenModifiers": [ + { + "id": "global", + "description": "Annotates a symbol that is declared in global scope." + }, + { + "id": "local", + "description": "Annotates a symbol that is declared in local scope." + } + ], + "semanticTokenScopes": [ + { + "scopes": { + "label": [ + "entity.name.label" + ], + "variable.global": [ + "variable.other.global" + ], + "variable.local": [ + "variable.other.local" + ], + "property.static": [ + "variable.other.property.static" + ], + "member.static": [ + "entity.name.function.member.static" + ], + "macro": [ + "entity.name.function.preprocessor" + ], + "referenceType": [ + "entity.name.type.class.reference" + ], + "cliProperty": [ + "variable.other.property.cli" + ], + "genericType": [ + "entity.name.type.class.generic" + ], + "valueType": [ + "entity.name.type.class.value" + ], + "templateFunction": [ + "entity.name.function.templated" + ], + "templateType": [ + "entity.name.type.class.templated" + ], + "operatorOverload": [ + "entity.name.function.operator" + ], + "memberOperatorOverload": [ + "entity.name.function.operator.member" + ], + "newOperator": [ + "keyword.operator.new" + ], + "numberLiteral": [ + "entity.name.operator.custom-literal.number" + ], + "customLiteral": [ + "entity.name.operator.custom-literal" + ], + "stringLiteral": [ + "entity.name.operator.custom-literal.string" + ] + } + } + ] }, "scripts": { "vscode:prepublish": "yarn run compile", @@ -1540,7 +1719,7 @@ "@types/plist": "^3.0.2", "@types/semver": "^7.1.0", "@types/tmp": "^0.1.0", - "@types/vscode": "1.43.0", + "@types/vscode": "1.44.0", "@types/webpack": "^4.39.0", "@types/which": "^1.3.2", "@types/yauzl": "^2.9.1", @@ -1604,7 +1783,7 @@ "runtimeDependencies": [ { "description": "C/C++ language components (Linux / x86_64)", - "url": "https://go.microsoft.com/fwlink/?linkid=2131174", + "url": "https://go.microsoft.com/fwlink/?linkid=2131982", "platforms": [ "linux" ], @@ -1618,7 +1797,7 @@ }, { "description": "C/C++ language components (OS X)", - "url": "https://go.microsoft.com/fwlink/?linkid=2131173", + "url": "https://go.microsoft.com/fwlink/?linkid=2132316", "platforms": [ "darwin" ], @@ -1629,7 +1808,7 @@ }, { "description": "C/C++ language components (Windows)", - "url": "https://go.microsoft.com/fwlink/?linkid=2131076", + "url": "https://go.microsoft.com/fwlink/?linkid=2132317", "platforms": [ "win32" ], diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 3f6a546f1d..8e9709ec97 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -36,6 +36,7 @@ "c_cpp.configuration.workspaceSymbols.description": "The symbols to include in the query results when 'Go to Symbol in Workspace' is invoked", "c_cpp.configuration.exclusionPolicy.description": "Instructs the extension when to use the \"files.exclude\" setting when determining which files should be added to the code navigation database while traversing through the paths in the \"browse.path\" array. \"checkFolders\" means that the exclusion filters will only be evaluated once per folder (individual files are not checked). \"checkFilesAndFolders\" means that the exclusion filters will be evaluated against every file and folder encountered. If your \"files.exclude\" setting only contains folders, then \"checkFolders\" is the best choice and will increase the speed at which the extension can initialize the code navigation database.", "c_cpp.configuration.preferredPathSeparator.description": "The character used as a path separator for #include auto-completion results.", + "c_cpp.configuration.simplifyStructuredComments.description": "If true, tooltips of hover and auto-complete will only display certain labels of structured comments. Otherwise, all comments are displayed.", "c_cpp.configuration.commentContinuationPatterns.items.anyof.string.description": "The pattern that begins a multiline or single line comment block. The continuation pattern defaults to ' * ' for multiline comment blocks or this string for single line comment blocks.", "c_cpp.configuration.commentContinuationPatterns.items.anyof.object.begin.description": "The pattern that begins a multiline or single line comment block.", "c_cpp.configuration.commentContinuationPatterns.items.anyof.object.continue.description": "The text that will be inserted on the next line when Enter is pressed inside a multiline or single line comment block.", @@ -43,7 +44,7 @@ "c_cpp.configuration.configurationWarnings.description": "Determines whether pop up notifications will be shown when a configuration provider extension is unable to provide a configuration for a source file.", "c_cpp.configuration.intelliSenseCachePath.description": "Defines the folder path for cached precompiled headers used by IntelliSense. The default cache path is \"%LocalAppData%/Microsoft/vscode-cpptools\" on Windows, \"$XDG_CACHE_HOME/vscode-cpptools/\" on Linux (or \"$HOME/.cache/vscode-cpptools/\" if XDG_CACHE_HOME is not defined), and \"$HOME/Library/Caches/vscode-cpptools/\" on Mac. The default path will be used if no path is specified or if a specified path is invalid.", "c_cpp.configuration.intelliSenseCacheSize.description": "Maximum size of the per-workspace hard drive space in megabytes for cached precompiled headers; the actual usage may fluctuate around this value. The default size is 5120 MB. Precompiled header caching is disabled when the size is 0.", - "c_cpp.configuration.default.includePath.description": "The value to use in a configuration if \"includePath\" is not specified, or the values to insert if \"${default}\" is present in \"includePath\".", + "c_cpp.configuration.default.includePath.description": "The value to use in a configuration if \"includePath\" is not specified in c_cpp_properties.json. If \"includePath\" is specified, add \"${default}\" to the array to insert the values from this setting.", "c_cpp.configuration.default.defines.description": "The value to use in a configuration if \"defines\" is not specified, or the values to insert if \"${default}\" is present in \"defines\".", "c_cpp.configuration.default.macFrameworkPath.description": "The value to use in a configuration if \"macFrameworkPath\" is not specified, or the values to insert if \"${default}\" is present in \"macFrameworkPath\".", "c_cpp.configuration.default.windowsSdkVersion.description": "Version of the Windows SDK include path to use on Windows, e.g. '10.0.17134.0'.", @@ -64,7 +65,7 @@ "c_cpp.configuration.updateChannel.description": "Set to \"Insiders\" to automatically download and install the latest Insiders builds of the extension, which include upcoming features and bug fixes.", "c_cpp.configuration.experimentalFeatures.description": "Controls whether \"experimental\" features are usable.", "c_cpp.configuration.suggestSnippets.description": "If true, snippets are provided by the language server.", - "c_cpp.configuration.enhancedColorization.description": "If enabled, code is colorized based on IntelliSense. This setting has no effect if IntelliSense is disabled or if using the Default High Contrast theme.", + "c_cpp.configuration.enhancedColorization.description": "If enabled, code is colorized based on IntelliSense. This setting only applies if intelliSenseEngine is set to \"Default\".", "c_cpp.configuration.codeFolding.description": "If enabled, code folding ranges are provided by the language server.", "c_cpp.configuration.vcpkg.enabled.markdownDescription": "Enable integration services for the [vcpkg dependency manager](https://aka.ms/vcpkg/).", "c_cpp.configuration.renameRequiresIdentifier.description": "If true, 'Rename Symbol' will require a valid C/C++ identifier.", @@ -78,6 +79,7 @@ "c_cpp.debuggers.pipeTransport.pipeProgram.description": "The fully qualified pipe command to execute.", "c_cpp.debuggers.pipeTransport.pipeArgs.description": "Command line arguments passed to the pipe program to configure the connection.", "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Environment variables passed to the pipe program.", + "c_cpp.debuggers.pipeTransport.quoteArgs.description": "If the pipeProgram's individual arguments contain characters (such as spaces or tabs), should it be quoted? If 'false', the debugger command will no longer be automatically quoted. \nDefault is 'true'.", "c_cpp.debuggers.logging.description": "Optional flags to determine what types of messages should be logged to the Debug Console.", "c_cpp.debuggers.logging.exceptions.description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.", "c_cpp.debuggers.logging.moduleLoad.description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.", @@ -85,6 +87,8 @@ "c_cpp.debuggers.logging.engineLogging.description": "Optional flag to determine whether diagnostic debug engine messages should be logged to the Debug Console. Defaults to false.", "c_cpp.debuggers.logging.trace.description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.", "c_cpp.debuggers.logging.traceResponse.description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the Debug Console. Defaults to false.", + "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Optional flag to determine whether thread exits messages should be logged to the Debug Console. Default: `false`.", + "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Optional flag to determine whether target process exits messages should be logged to the Debug Console., or debugging is stopped. Default: `true`.", "c_cpp.debuggers.text.description": "The debugger command to execute.", "c_cpp.debuggers.description.description": "Optional description for the command.", "c_cpp.debuggers.ignoreFailures.description": "If true, failures from the command should be ignored. Default value is false.", diff --git a/Extension/src/Debugger/ParsedEnvironmentFile.ts b/Extension/src/Debugger/ParsedEnvironmentFile.ts index 19a5e777d9..2a735297e5 100644 --- a/Extension/src/Debugger/ParsedEnvironmentFile.ts +++ b/Extension/src/Debugger/ParsedEnvironmentFile.ts @@ -24,7 +24,7 @@ export class ParsedEnvironmentFile { } public static CreateFromFile(envFile: string, initialEnv?: Environment[]): ParsedEnvironmentFile { - let content: string = fs.readFileSync(envFile, "utf8"); + const content: string = fs.readFileSync(envFile, "utf8"); return this.CreateFromContent(content, envFile, initialEnv); } @@ -35,8 +35,8 @@ export class ParsedEnvironmentFile { content = content.substr(1); } - let parseErrors: string[] = []; - let env: Map = new Map(); + const parseErrors: string[] = []; + const env: Map = new Map(); if (initialEnv) { // Convert array to map to prevent duplicate keys being created. @@ -80,7 +80,7 @@ export class ParsedEnvironmentFile { // Convert env map back to array. const arrayEnv: Environment[] = []; - for (let key of env.keys()) { + for (const key of env.keys()) { arrayEnv.push({name: key, value: env.get(key)}); } diff --git a/Extension/src/Debugger/attachQuickPick.ts b/Extension/src/Debugger/attachQuickPick.ts index 680267a303..ba966b7ace 100644 --- a/Extension/src/Debugger/attachQuickPick.ts +++ b/Extension/src/Debugger/attachQuickPick.ts @@ -33,7 +33,7 @@ export interface AttachItem extends vscode.QuickPickItem { export function showQuickPick(getAttachItems: () => Promise): Promise { return getAttachItems().then(processEntries => new Promise((resolve, reject) => { - let quickPick: vscode.QuickPick = vscode.window.createQuickPick(); + const quickPick: vscode.QuickPick = vscode.window.createQuickPick(); quickPick.title = localize("attach.to.process", "Attach to process"); quickPick.canSelectMany = false; quickPick.matchOnDescription = true; @@ -42,7 +42,7 @@ export function showQuickPick(getAttachItems: () => Promise): Prom quickPick.items = processEntries; quickPick.buttons = [new RefreshButton()]; - let disposables: vscode.Disposable[] = []; + const disposables: vscode.Disposable[] = []; quickPick.onDidTriggerButton(button => { getAttachItems().then(processEntries => quickPick.items = processEntries); @@ -53,7 +53,7 @@ export function showQuickPick(getAttachItems: () => Promise): Prom reject(new Error(localize("process.not.selected", "Process not selected."))); } - let selectedId: string | undefined = quickPick.selectedItems[0].id; + const selectedId: string | undefined = quickPick.selectedItems[0].id; disposables.forEach(item => item.dispose()); quickPick.dispose(); diff --git a/Extension/src/Debugger/attachToProcess.ts b/Extension/src/Debugger/attachToProcess.ts index a278bb3157..aaca23a63c 100644 --- a/Extension/src/Debugger/attachToProcess.ts +++ b/Extension/src/Debugger/attachToProcess.ts @@ -50,7 +50,7 @@ export class RemoteAttachPicker { } else { this._channel.clear(); - let pipeTransport: any = config ? config.pipeTransport : undefined; + const pipeTransport: any = config ? config.pipeTransport : undefined; if (!pipeTransport) { return Promise.reject(new Error(localize("no.pipetransport", "Chosen debug configuration does not contain {0}", "pipeTransport"))); @@ -84,15 +84,15 @@ export class RemoteAttachPicker { pipeProgram = pipeTransport.pipeProgram; } - let pipeArgs: string[] = pipeTransport.pipeArgs; + const pipeArgs: string[] = pipeTransport.pipeArgs; - let argList: string = RemoteAttachPicker.createArgumentList(pipeArgs); + const argList: string = RemoteAttachPicker.createArgumentList(pipeArgs); - let pipeCmd: string = `"${pipeProgram}" ${argList}`; + const pipeCmd: string = `"${pipeProgram}" ${argList}`; return this.getRemoteOSAndProcesses(pipeCmd) .then(processes => { - let attachPickOptions: vscode.QuickPickOptions = { + const attachPickOptions: vscode.QuickPickOptions = { matchOnDetail: true, matchOnDescription: true, placeHolder: localize("select.process.attach", "Select the process to attach to") @@ -113,7 +113,7 @@ export class RemoteAttachPicker { let parameterEnd: string = `)`; let escapedQuote: string = `\\\"`; - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.useBacktickCommandSubstitution) { parameterBegin = `\``; parameterEnd = `\``; @@ -139,12 +139,12 @@ export class RemoteAttachPicker { return util.execChildProcess(execCommand, undefined, this._channel).then(output => { // OS will be on first line // Processes will follow if listed - let lines: string[] = output.split(/\r?\n/); + const lines: string[] = output.split(/\r?\n/); if (lines.length === 0) { return Promise.reject(new Error(localize("pipe.failed", "Pipe transport failed to get OS and processes."))); } else { - let remoteOS: string = lines[0].replace(/[\r\n]+/g, ''); + const remoteOS: string = lines[0].replace(/[\r\n]+/g, ''); if (remoteOS !== "Linux" && remoteOS !== "Darwin") { return Promise.reject(new Error(`Operating system "${remoteOS}" not supported.`)); @@ -154,7 +154,7 @@ export class RemoteAttachPicker { if (lines.length === 1) { return Promise.reject(new Error(localize("no.process.list", "Transport attach could not obtain processes list."))); } else { - let processes: string[] = lines.slice(1); + const processes: string[] = lines.slice(1); return PsProcessParser.ParseProcessFromPsArray(processes) .sort((a, b) => { if (a.name === undefined) { @@ -166,8 +166,8 @@ export class RemoteAttachPicker { if (b.name === undefined) { return -1; } - let aLower: string = a.name.toLowerCase(); - let bLower: string = b.name.toLowerCase(); + const aLower: string = a.name.toLowerCase(); + const bLower: string = b.name.toLowerCase(); if (aLower === bLower) { return 0; } @@ -182,7 +182,7 @@ export class RemoteAttachPicker { private static createArgumentList(args: string[]): string { let argsString: string = ""; - for (let arg of args) { + for (const arg of args) { if (argsString) { argsString += " "; } diff --git a/Extension/src/Debugger/configurationProvider.ts b/Extension/src/Debugger/configurationProvider.ts index 35ad0ce053..780c439204 100644 --- a/Extension/src/Debugger/configurationProvider.ts +++ b/Extension/src/Debugger/configurationProvider.ts @@ -57,7 +57,7 @@ export class QuickPickConfigurationProvider implements vscode.DebugConfiguration } const items: MenuItem[] = configs.map(config => { - let menuItem: MenuItem = {label: config.name, configuration: config}; + const menuItem: MenuItem = {label: config.name, configuration: config}; // Rename the menu item for the default configuration as its name is non-descriptive. if (isDebugLaunchStr(menuItem.label)) { menuItem.label = localize("default.configuration.menuitem", "Default Configuration"); @@ -132,11 +132,11 @@ class CppConfigurationProvider implements vscode.DebugConfigurationProvider { // Generate new configurations for each build task. // Generating a task is async, therefore we must *await* *all* map(task => config) Promises to resolve. - let configs: vscode.DebugConfiguration[] = await Promise.all(buildTasks.map>(async task => { + const configs: vscode.DebugConfiguration[] = await Promise.all(buildTasks.map>(async task => { const definition: BuildTaskDefinition = task.definition as BuildTaskDefinition; const compilerName: string = path.basename(definition.compilerPath); - let newConfig: vscode.DebugConfiguration = {...defaultConfig}; // Copy enumerables and properties + const newConfig: vscode.DebugConfiguration = {...defaultConfig}; // Copy enumerables and properties newConfig.name = compilerName + buildAndDebugActiveFileStr(); newConfig.preLaunchTask = task.name; @@ -188,91 +188,101 @@ class CppConfigurationProvider implements vscode.DebugConfigurationProvider { * Try to add all missing attributes to the debug configuration being launched. */ resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult { - if (config) { - if (config.type === 'cppvsdbg') { - // Fail if cppvsdbg type is running on non-Windows - if (os.platform() !== 'win32') { - logger.getOutputChannelLogger().showWarningMessage(localize("debugger.not.available", "Debugger of type: '{0}' is only available on Windows. Use type: '{1}' on the current OS platform.", "cppvsdbg", "cppdbg")); - return undefined; - } + // [Microsoft/vscode#54213] If config or type is not specified, return null to trigger VS Code to open a configuration file. + if (!config || !config.type) { + return null; + } - // Disable debug heap by default, enable if 'enableDebugHeap' is set. - if (!config.enableDebugHeap) { - const disableDebugHeapEnvSetting: Environment = {"name" : "_NO_DEBUG_HEAP", "value" : "1"}; + if (config.type === 'cppvsdbg') { + // Fail if cppvsdbg type is running on non-Windows + if (os.platform() !== 'win32') { + logger.getOutputChannelLogger().showWarningMessage(localize("debugger.not.available", "Debugger of type: '{0}' is only available on Windows. Use type: '{1}' on the current OS platform.", "cppvsdbg", "cppdbg")); + return undefined; + } - if (config.environment && util.isArray(config.environment)) { - config.environment.push(disableDebugHeapEnvSetting); - } else { - config.environment = [disableDebugHeapEnvSetting]; - } + // Disable debug heap by default, enable if 'enableDebugHeap' is set. + if (!config.enableDebugHeap) { + const disableDebugHeapEnvSetting: Environment = {"name" : "_NO_DEBUG_HEAP", "value" : "1"}; + + if (config.environment && util.isArray(config.environment)) { + config.environment.push(disableDebugHeapEnvSetting); + } else { + config.environment = [disableDebugHeapEnvSetting]; } } + } - // Add environment variables from .env file - this.resolveEnvFile(config, folder); + // Add environment variables from .env file + this.resolveEnvFile(config, folder); - this.resolveSourceFileMapVariables(config); + this.resolveSourceFileMapVariables(config); - // Modify WSL config for OpenDebugAD7 - if (os.platform() === 'win32' && - config.pipeTransport && - config.pipeTransport.pipeProgram) { - let replacedPipeProgram: string | undefined; - const pipeProgramStr: string = config.pipeTransport.pipeProgram.toLowerCase().trim(); + // Modify WSL config for OpenDebugAD7 + if (os.platform() === 'win32' && + config.pipeTransport && + config.pipeTransport.pipeProgram) { + let replacedPipeProgram: string | undefined; + const pipeProgramStr: string = config.pipeTransport.pipeProgram.toLowerCase().trim(); - // OpenDebugAD7 is a 32-bit process. Make sure the WSL pipe transport is using the correct program. - replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, debugUtils.ArchType.ia32); + // OpenDebugAD7 is a 32-bit process. Make sure the WSL pipe transport is using the correct program. + replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, debugUtils.ArchType.ia32); - // If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace. - if (!replacedPipeProgram && !path.isAbsolute(pipeProgramStr) && config.pipeTransport.pipeCwd) { - const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim(); - const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr); + // If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace. + if (!replacedPipeProgram && !path.isAbsolute(pipeProgramStr) && config.pipeTransport.pipeCwd) { + const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim(); + const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr); - replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, debugUtils.ArchType.ia32); - } + replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, debugUtils.ArchType.ia32); + } - if (replacedPipeProgram) { - config.pipeTransport.pipeProgram = replacedPipeProgram; - } + if (replacedPipeProgram) { + config.pipeTransport.pipeProgram = replacedPipeProgram; } + } - const macOSMIMode: string = config.osx?.MIMode ?? config.MIMode; - const macOSMIDebuggerPath: string = config.osx?.miDebuggerPath ?? config.miDebuggerPath; + const macOSMIMode: string = config.osx?.MIMode ?? config.MIMode; + const macOSMIDebuggerPath: string = config.osx?.miDebuggerPath ?? config.miDebuggerPath; - const lldb_mi_10_x_path: string = path.join(util.extensionPath, "debugAdapters", "lldb-mi", "bin", "lldb-mi"); + const lldb_mi_10_x_path: string = path.join(util.extensionPath, "debugAdapters", "lldb-mi", "bin", "lldb-mi"); - // Validate LLDB-MI - if (os.platform() === 'darwin' && // Check for macOS - fs.existsSync(lldb_mi_10_x_path) && // lldb-mi 10.x exists - (!macOSMIMode || macOSMIMode === 'lldb') && - !macOSMIDebuggerPath // User did not provide custom lldb-mi - ) { - const frameworkPath: string | undefined = this.getLLDBFrameworkPath(); + // Validate LLDB-MI + if (os.platform() === 'darwin' && // Check for macOS + fs.existsSync(lldb_mi_10_x_path) && // lldb-mi 10.x exists + (!macOSMIMode || macOSMIMode === 'lldb') && + !macOSMIDebuggerPath // User did not provide custom lldb-mi + ) { + const frameworkPath: string | undefined = this.getLLDBFrameworkPath(); - if (!frameworkPath) { - const moreInfoButton: string = localize("lldb.framework.install.xcode", "More Info"); - const LLDBFrameworkMissingMessage: string = localize("lldb.framework.not.found", "Unable to locate 'LLDB.framework' for lldb-mi. Please install XCode or XCode Command Line Tools."); + if (!frameworkPath) { + const moreInfoButton: string = localize("lldb.framework.install.xcode", "More Info"); + const LLDBFrameworkMissingMessage: string = localize("lldb.framework.not.found", "Unable to locate 'LLDB.framework' for lldb-mi. Please install XCode or XCode Command Line Tools."); - vscode.window.showErrorMessage(LLDBFrameworkMissingMessage, moreInfoButton) - .then(value => { - if (value === moreInfoButton) { - let helpURL: string = "https://aka.ms/vscode-cpptools/LLDBFrameworkNotFound"; - vscode.env.openExternal(vscode.Uri.parse(helpURL)); - } - }); + vscode.window.showErrorMessage(LLDBFrameworkMissingMessage, moreInfoButton) + .then(value => { + if (value === moreInfoButton) { + const helpURL: string = "https://aka.ms/vscode-cpptools/LLDBFrameworkNotFound"; + vscode.env.openExternal(vscode.Uri.parse(helpURL)); + } + }); - return undefined; - } + return undefined; } } - // if config or type is not specified, return null to trigger VS Code to open a configuration file https://github.com/Microsoft/vscode/issues/54213 - return config && config.type ? config : null; + + if (config.logging?.engineLogging) { + const outputChannel: logger.Logger = logger.getOutputChannelLogger(); + outputChannel.appendLine(localize("debugger.launchConfig", "Launch configuration:")); + outputChannel.appendLine(JSON.stringify(config, undefined, 2)); + logger.showOutputChannel(); + } + + return config; } private getLLDBFrameworkPath(): string | undefined { const LLDBFramework: string = "LLDB.framework"; // Note: When adding more search paths, make sure the shipped lldb-mi also has it. See Build/lldb-mi.yml and 'install_name_tool' commands. - let searchPaths: string[] = [ + const searchPaths: string[] = [ "/Library/Developer/CommandLineTools/Library/PrivateFrameworks", // XCode CLI "/Applications/Xcode.app/Contents/SharedFrameworks" // App Store XCode ]; @@ -326,7 +336,7 @@ class CppConfigurationProvider implements vscode.DebugConfigurationProvider { } private resolveSourceFileMapVariables(config: vscode.DebugConfiguration): void { - let messages: string[] = []; + const messages: string[] = []; if (config.sourceFileMap) { for (const sourceFileMapSource of Object.keys(config.sourceFileMap)) { let message: string = ""; @@ -370,9 +380,9 @@ class CppConfigurationProvider implements vscode.DebugConfigurationProvider { private static async showFileWarningAsync(message: string, fileName: string): Promise { const openItem: vscode.MessageItem = { title: localize("open.envfile", "Open {0}", "envFile") }; - let result: vscode.MessageItem | undefined = await vscode.window.showWarningMessage(message, openItem); + const result: vscode.MessageItem | undefined = await vscode.window.showWarningMessage(message, openItem); if (result && result.title === openItem.title) { - let doc: vscode.TextDocument = await vscode.workspace.openTextDocument(fileName); + const doc: vscode.TextDocument = await vscode.workspace.openTextDocument(fileName); if (doc) { vscode.window.showTextDocument(doc); } @@ -416,14 +426,14 @@ abstract class DefaultConfigurationProvider implements IConfigurationAssetProvid configurations: IConfiguration[] = []; public getInitialConfigurations(debuggerType: DebuggerType): any { - let configurationSnippet: IConfigurationSnippet[] = []; + const configurationSnippet: IConfigurationSnippet[] = []; // Only launch configurations are initial configurations this.configurations.forEach(configuration => { configurationSnippet.push(configuration.GetLaunchConfiguration()); }); - let initialConfigurations: any = configurationSnippet.filter(snippet => snippet.debuggerType === debuggerType && snippet.isInitialConfiguration) + const initialConfigurations: any = configurationSnippet.filter(snippet => snippet.debuggerType === debuggerType && snippet.isInitialConfiguration) .map(snippet => JSON.parse(snippet.bodyText)); // If configurations is empty, then it will only have an empty configurations array in launch.json. Users can still add snippets. @@ -431,7 +441,7 @@ abstract class DefaultConfigurationProvider implements IConfigurationAssetProvid } public getConfigurationSnippets(): vscode.CompletionItem[] { - let completionItems: vscode.CompletionItem[] = []; + const completionItems: vscode.CompletionItem[] = []; this.configurations.forEach(configuration => { completionItems.push(convertConfigurationSnippetToCompetionItem(configuration.GetLaunchConfiguration())); @@ -500,7 +510,7 @@ class LinuxConfigurationProvider extends DefaultConfigurationProvider { } function convertConfigurationSnippetToCompetionItem(snippet: IConfigurationSnippet): vscode.CompletionItem { - let item: vscode.CompletionItem = new vscode.CompletionItem(snippet.label, vscode.CompletionItemKind.Snippet); + const item: vscode.CompletionItem = new vscode.CompletionItem(snippet.label, vscode.CompletionItemKind.Snippet); item.insertText = snippet.bodyText; diff --git a/Extension/src/Debugger/configurations.ts b/Extension/src/Debugger/configurations.ts index 7f3c0a1475..5ed3a0c17a 100644 --- a/Extension/src/Debugger/configurations.ts +++ b/Extension/src/Debugger/configurations.ts @@ -29,7 +29,7 @@ export function indentJsonString(json: string, numTabs: number = 1): string { } function formatString(format: string, args: string[]): string { - for (let arg in args) { + for (const arg in args) { format = format.replace("{" + arg + "}", args[arg]); } return format; @@ -107,9 +107,9 @@ abstract class Configuration implements IConfiguration { export class MIConfigurations extends Configuration { public GetLaunchConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("launch.string", "Launch").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("launch.string", "Launch").replace(/\"/g, "\\\"")}`; - let body: string = formatString(`{ + const body: string = formatString(`{ \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"` : "", @@ -125,9 +125,9 @@ export class MIConfigurations extends Configuration { } public GetAttachConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("attach.string", "Attach").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("attach.string", "Attach").replace(/\"/g, "\\\"")}`; - let body: string = formatString(`{ + const body: string = formatString(`{ \t${indentJsonString(createAttachString(name, this.miDebugger, this.executable))}, \t"MIMode": "${this.MIMode}"{0}{1} }`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "", @@ -146,9 +146,9 @@ export class MIConfigurations extends Configuration { export class PipeTransportConfigurations extends Configuration { public GetLaunchConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("pipe.launch", "Pipe Launch").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("pipe.launch", "Pipe Launch").replace(/\"/g, "\\\"")}`; - let body: string = formatString(` + const body: string = formatString(` { \t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))}, \t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))}, @@ -165,9 +165,9 @@ export class PipeTransportConfigurations extends Configuration { } public GetAttachConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("pipe.attach", "Pipe Attach").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("pipe.attach", "Pipe Attach").replace(/\"/g, "\\\"")}`; - let body: string = formatString(` + const body: string = formatString(` { \t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))}, \t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))}, @@ -186,9 +186,9 @@ export class PipeTransportConfigurations extends Configuration { export class WindowsConfigurations extends Configuration { public GetLaunchConfiguration(): IConfigurationSnippet { - let name: string = `(Windows) ${localize("launch.string", "Launch").replace(/\"/g, "\\\"")}`; + const name: string = `(Windows) ${localize("launch.string", "Launch").replace(/\"/g, "\\\"")}`; - let body: string = ` + const body: string = ` { \t${indentJsonString(createLaunchString(name, this.windowsDebugger, this.executable))} }`; @@ -204,9 +204,9 @@ export class WindowsConfigurations extends Configuration { } public GetAttachConfiguration(): IConfigurationSnippet { - let name: string = `(Windows) ${localize("attach.string", "Attach").replace(/\"/g, "\\\"")}`; + const name: string = `(Windows) ${localize("attach.string", "Attach").replace(/\"/g, "\\\"")}`; - let body: string = ` + const body: string = ` { \t${indentJsonString(createAttachString(name, this.windowsDebugger, this.executable))} }`; @@ -226,9 +226,9 @@ export class WSLConfigurations extends Configuration { public bashPipeProgram = process.arch === 'ia32' ? "${env:windir}\\\\sysnative\\\\bash.exe" : "${env:windir}\\\\system32\\\\bash.exe"; public GetLaunchConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("bash.on.windows.launch", "Bash on Windows Launch").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("bash.on.windows.launch", "Bash on Windows Launch").replace(/\"/g, "\\\"")}`; - let body: string = formatString(` + const body: string = formatString(` { \t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))}, \t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0} @@ -243,9 +243,9 @@ export class WSLConfigurations extends Configuration { } public GetAttachConfiguration(): IConfigurationSnippet { - let name: string = `(${this.MIMode}) ${localize("bash.on.windows.attach", "Bash on Windows Attach").replace(/\"/g, "\\\"")}`; + const name: string = `(${this.MIMode}) ${localize("bash.on.windows.attach", "Bash on Windows Attach").replace(/\"/g, "\\\"")}`; - let body: string = formatString(` + const body: string = formatString(` { \t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))}, \t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0} diff --git a/Extension/src/Debugger/extension.ts b/Extension/src/Debugger/extension.ts index c897b04cc2..64637ae1c2 100644 --- a/Extension/src/Debugger/extension.ts +++ b/Extension/src/Debugger/extension.ts @@ -17,7 +17,7 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo const localize: nls.LocalizeFunc = nls.loadMessageBundle(); // The extension deactivate method is asynchronous, so we handle the disposables ourselves instead of using extensonContext.subscriptions. -let disposables: vscode.Disposable[] = []; +const disposables: vscode.Disposable[] = []; export function buildAndDebugActiveFileStr(): string { return ` - ${localize("build.and.debug.active.file", 'Build and debug active file')}`; @@ -25,14 +25,14 @@ export function buildAndDebugActiveFileStr(): string { export function initialize(context: vscode.ExtensionContext): void { // Activate Process Picker Commands - let attachItemsProvider: AttachItemsProvider = NativeAttachItemsProviderFactory.Get(); - let attacher: AttachPicker = new AttachPicker(attachItemsProvider); + const attachItemsProvider: AttachItemsProvider = NativeAttachItemsProviderFactory.Get(); + const attacher: AttachPicker = new AttachPicker(attachItemsProvider); disposables.push(vscode.commands.registerCommand('extension.pickNativeProcess', () => attacher.ShowAttachEntries())); - let remoteAttacher: RemoteAttachPicker = new RemoteAttachPicker(); + const remoteAttacher: RemoteAttachPicker = new RemoteAttachPicker(); disposables.push(vscode.commands.registerCommand('extension.pickRemoteNativeProcess', (any) => remoteAttacher.ShowAttachEntries(any))); // Activate ConfigurationProvider - let configurationProvider: IConfigurationAssetProvider = ConfigurationAssetProviderFactory.getConfigurationProvider(); + const configurationProvider: IConfigurationAssetProvider = ConfigurationAssetProviderFactory.getConfigurationProvider(); // On non-windows platforms, the cppvsdbg debugger will not be registered for initial configurations. // This will cause it to not show up on the dropdown list. let vsdbgProvider: CppVsDbgConfigurationProvider | null = null; @@ -58,11 +58,11 @@ export function initialize(context: vscode.ExtensionContext): void { return Promise.resolve(); } - let configs: vscode.DebugConfiguration[] = (await provider.provideDebugConfigurations(folder)).filter(config => + const configs: vscode.DebugConfiguration[] = (await provider.provideDebugConfigurations(folder)).filter(config => config.name.indexOf(buildAndDebugActiveFileStr()) !== -1); if (vsdbgProvider) { - let vsdbgConfigs: vscode.DebugConfiguration[] = (await vsdbgProvider.provideDebugConfigurations(folder)).filter(config => + const vsdbgConfigs: vscode.DebugConfiguration[] = (await vsdbgProvider.provideDebugConfigurations(folder)).filter(config => config.name.indexOf(buildAndDebugActiveFileStr()) !== -1); if (vsdbgConfigs) { configs.push(...vsdbgConfigs); diff --git a/Extension/src/Debugger/nativeAttach.ts b/Extension/src/Debugger/nativeAttach.ts index 52291840f3..0180dbbd11 100644 --- a/Extension/src/Debugger/nativeAttach.ts +++ b/Extension/src/Debugger/nativeAttach.ts @@ -52,14 +52,14 @@ abstract class NativeAttachItemsProvider implements AttachItemsProvider { if (b.name === undefined) { return -1; } - let aLower: string = a.name.toLowerCase(); - let bLower: string = b.name.toLowerCase(); + const aLower: string = a.name.toLowerCase(); + const bLower: string = b.name.toLowerCase(); if (aLower === bLower) { return 0; } return aLower < bLower ? -1 : 1; }); - let attachItems: AttachItem[] = processEntries.map(p => p.toAttachItem()); + const attachItems: AttachItem[] = processEntries.map(p => p.toAttachItem()); return attachItems; }); } @@ -119,21 +119,21 @@ export class PsProcessParser { // Only public for tests. public static ParseProcessFromPs(processes: string): Process[] { - let lines: string[] = processes.split(os.EOL); + const lines: string[] = processes.split(os.EOL); return PsProcessParser.ParseProcessFromPsArray(lines); } public static ParseProcessFromPsArray(processArray: string[]): Process[] { - let processEntries: Process[] = []; + const processEntries: Process[] = []; // lines[0] is the header of the table for (let i: number = 1; i < processArray.length; i++) { - let line: string = processArray[i]; + const line: string = processArray[i]; if (!line) { continue; } - let processEntry: Process | undefined = PsProcessParser.parseLineFromPs(line); + const processEntry: Process | undefined = PsProcessParser.parseLineFromPs(line); if (processEntry) { processEntries.push(processEntry); } @@ -180,8 +180,8 @@ function execChildProcess(process: string, workingDirectory?: string): Promise= 0) { - let key: string = line.slice(0, line.indexOf('=')).trim(); + const key: string = line.slice(0, line.indexOf('=')).trim(); let value: string = line.slice(line.indexOf('=') + 1).trim(); if (key === WmicProcessParser.wmicNameTitle) { process.name = value; diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index bf21d5cf66..03922e75cc 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -30,9 +30,9 @@ import { getCustomConfigProviders, CustomConfigurationProvider1, isSameProviderE import { ABTestSettings, getABTestSettings } from '../abTesting'; import * as fs from 'fs'; import * as os from 'os'; -import { TokenKind, ColorizationSettings, ColorizationState } from './colorization'; import * as refs from './references'; import * as nls from 'vscode-nls'; +import { lookupString, localizedStringCount } from '../nativeStrings'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -45,7 +45,7 @@ const configProviderTimeout: number = 2000; // Data shared by all clients. let languageClient: LanguageClient; let languageClientCrashedNeedsRestart: boolean = false; -let languageClientCrashTimes: number[] = []; +const languageClientCrashTimes: number[] = []; let clientCollection: ClientCollection; let pendingTask: util.BlockingTask | undefined; let compilerDefaults: configs.CompilerDefaults; @@ -53,17 +53,12 @@ let diagnosticsChannel: vscode.OutputChannel; let outputChannel: vscode.OutputChannel; let debugChannel: vscode.OutputChannel; let diagnosticsCollection: vscode.DiagnosticCollection; -let workspaceColorizationState: Map = new Map(); let workspaceDisposables: vscode.Disposable[] = []; let workspaceReferences: refs.ReferencesManager; export function disposeWorkspaceData(): void { workspaceDisposables.forEach((d) => d.dispose()); workspaceDisposables = []; - - workspaceColorizationState.forEach(colorizationState => { - colorizationState.dispose(); - }); } function logTelemetry(notificationBody: TelemetryPayload): void { @@ -98,12 +93,12 @@ function log(output: string): void { } function logLocalized(params: LocalizeStringParams): void { - let output: string = util.getLocalizedString(params); + const output: string = util.getLocalizedString(params); log(output); } function showMessageWindow(params: ShowMessageWindowParams): void { - let message: string = util.getLocalizedString(params.localizeStringParams); + const message: string = util.getLocalizedString(params.localizeStringParams); switch (params.type) { case 1: // Error vscode.window.showErrorMessage(message); @@ -126,42 +121,20 @@ function publishDiagnostics(params: PublishDiagnosticsParams): void { } // Convert from our Diagnostic objects to vscode Diagnostic objects - let diagnostics: vscode.Diagnostic[] = []; + const diagnostics: vscode.Diagnostic[] = []; params.diagnostics.forEach((d) => { - let message: string = util.getLocalizedString(d.localizeStringParams); - let r: vscode.Range = new vscode.Range(d.range.start.line, d.range.start.character, d.range.end.line, d.range.end.character); - let diagnostic: vscode.Diagnostic = new vscode.Diagnostic(r, message, d.severity); + const message: string = util.getLocalizedString(d.localizeStringParams); + const r: vscode.Range = new vscode.Range(d.range.start.line, d.range.start.character, d.range.end.line, d.range.end.character); + const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(r, message, d.severity); diagnostic.code = d.code; diagnostic.source = d.source; diagnostics.push(diagnostic); }); - let realUri: vscode.Uri = vscode.Uri.parse(params.uri); + const realUri: vscode.Uri = vscode.Uri.parse(params.uri); diagnosticsCollection.set(realUri, diagnostics); } -function updateSemanticColorizationRegions(params: SemanticColorizationRegionsParams): void { - let colorizationState: ColorizationState | undefined = workspaceColorizationState.get(params.uri); - if (colorizationState) { - // Convert the params to vscode.Range's before passing to colorizationState.updateSemantic() - let semanticRanges: vscode.Range[][] = new Array(TokenKind.Count); - for (let i: number = 0; i < TokenKind.Count; i++) { - semanticRanges[i] = []; - } - params.regions.forEach(element => { - let newRange: vscode.Range = new vscode.Range(element.range.start.line, element.range.start.character, element.range.end.line, element.range.end.character); - semanticRanges[element.kind].push(newRange); - }); - let inactiveRanges: vscode.Range[] = []; - params.inactiveRegions.forEach(element => { - let newRange: vscode.Range = new vscode.Range(element.startLine, 0, element.endLine, 0); - inactiveRanges.push(newRange); - }); - colorizationState.updateSemantic(params.uri, semanticRanges, inactiveRanges, params.editVersion); - languageClient.sendNotification(SemanticColorizationRegionsReceiptNotification, { uri: params.uri }); - } -} - interface WorkspaceFolderParams { workspaceFolderUri?: string; } @@ -203,21 +176,20 @@ interface FileChangedParams extends WorkspaceFolderParams { uri: string; } -interface SemanticColorizationRegionsParams { - uri: string; - regions: InputColorizationRegion[]; - inactiveRegions: InputRegion[]; - editVersion: number; -} - interface InputRegion { startLine: number; endLine: number; } -interface InputColorizationRegion { - range: Range; - kind: number; +interface DecorationRangesPair { + decoration: vscode.TextEditorDecorationType; + ranges: vscode.Range[]; +} + +interface InactiveRegionParams { + uri: string; + fileVersion: number; + regions: InputRegion[]; } // Need to convert vscode.Uri to a string before sending it to the language server. @@ -250,19 +222,6 @@ interface GetDiagnosticsResult { diagnostics: string; } -interface DidChangeVisibleRangesParams { - uri: string; - ranges: Range[]; -} - -interface SemanticColorizationRegionsReceiptParams { - uri: string; -} - -interface ColorThemeChangedParams { - name: string; -} - interface Diagnostic { range: Range; code?: number | string; @@ -342,7 +301,7 @@ interface GetFoldingRangesParams { id: number; } -export enum FoldingRangeKind { +enum FoldingRangeKind { None = 0, Comment = 1, Imports = 2, @@ -352,7 +311,7 @@ export enum FoldingRangeKind { interface FoldingRange { kind: FoldingRangeKind; range: Range; -}; +} interface GetFoldingRangesResult { canceled: boolean; @@ -363,6 +322,62 @@ interface AbortRequestParams { id: number; } +interface GetSemanticTokensParams { + uri: string; + id: number; +} + +interface SemanticToken { + line: number; + character: number; + length: number; + type: number; + modifiers?: number; +} + +interface GetSemanticTokensResult { + fileVersion: number; + canceled: boolean; + tokens: SemanticToken[]; +} + +enum SemanticTokenTypes { + // These are camelCase as the enum names are used directly as strings in our legend. + macro = 0, + enumMember = 1, + variable = 2, + parameter = 3, + type = 4, + referenceType = 5, + valueType = 6, + function = 7, + member = 8, + property = 9, + cliProperty = 10, + event = 11, + genericType = 12, + templateFunction = 13, + templateType = 14, + namespace = 15, + label = 16, + customLiteral = 17, + numberLiteral = 18, + stringLiteral = 19, + operatorOverload = 20, + memberOperatorOverload = 21, + newOperator = 22 +} + +enum SemanticTokenModifiers { + // These are camelCase as the enum names are used directly as strings in our legend. + // eslint-disable-next-line no-bitwise + static = (1 << 0), + // eslint-disable-next-line no-bitwise + global = (1 << 1), + // eslint-disable-next-line no-bitwise + local = (1 << 2) +} + // Requests const QueryCompilerDefaultsRequest: RequestType = new RequestType('cpptools/queryCompilerDefaults'); const QueryTranslationUnitSourceRequest: RequestType = new RequestType('cpptools/queryTranslationUnitSource'); @@ -372,6 +387,7 @@ const GetCodeActionsRequest: RequestType = new RequestType('cpptools/getDocumentSymbols'); const GetSymbolInfoRequest: RequestType = new RequestType('cpptools/getWorkspaceSymbols'); const GetFoldingRangesRequest: RequestType = new RequestType('cpptools/getFoldingRanges'); +const GetSemanticTokensRequest: RequestType = new RequestType('cpptools/getSemanticTokens'); // Notifications to the server const DidOpenNotification: NotificationType = new NotificationType('textDocument/didOpen'); @@ -392,9 +408,6 @@ const CustomBrowseConfigurationNotification: NotificationType = new NotificationType('cpptools/clearCustomConfigurations'); const ClearCustomBrowseConfigurationNotification: NotificationType = new NotificationType('cpptools/clearCustomBrowseConfiguration'); const RescanFolderNotification: NotificationType = new NotificationType('cpptools/rescanFolder'); -const DidChangeVisibleRangesNotification: NotificationType = new NotificationType('cpptools/didChangeVisibleRanges'); -const SemanticColorizationRegionsReceiptNotification: NotificationType = new NotificationType('cpptools/semanticColorizationRegionsReceipt'); -const ColorThemeChangedNotification: NotificationType = new NotificationType('cpptools/colorThemeChanged'); const RequestReferencesNotification: NotificationType = new NotificationType('cpptools/requestReferences'); const CancelReferencesNotification: NotificationType = new NotificationType('cpptools/cancelReferences'); const FinishedRequestCustomConfig: NotificationType = new NotificationType('cpptools/finishedRequestCustomConfig'); @@ -410,7 +423,7 @@ const ReportTagParseStatusNotification: NotificationType = new NotificationType('cpptools/reportStatus'); const DebugProtocolNotification: NotificationType = new NotificationType('cpptools/debugProtocol'); const DebugLogNotification: NotificationType = new NotificationType('cpptools/debugLog'); -const SemanticColorizationRegionsNotification: NotificationType = new NotificationType('cpptools/semanticColorizationRegions'); +const InactiveRegionNotification: NotificationType = new NotificationType('cpptools/inactiveRegions'); const CompileCommandsPathsNotification: NotificationType = new NotificationType('cpptools/compileCommandsPaths'); const ReferencesNotification: NotificationType = new NotificationType('cpptools/references'); const ReportReferencesProgressNotification: NotificationType = new NotificationType('cpptools/reportReferencesProgress'); @@ -418,6 +431,7 @@ const RequestCustomConfig: NotificationType = new NotificationType const PublishDiagnosticsNotification: NotificationType = new NotificationType('cpptools/publishDiagnostics'); const ShowMessageWindowNotification: NotificationType = new NotificationType('cpptools/showMessageWindow'); const ReportTextDocumentLanguage: NotificationType = new NotificationType('cpptools/reportTextDocumentLanguage'); +const SemanticTokensChanged: NotificationType = new NotificationType('cpptools/semanticTokensChanged'); let failureMessageShown: boolean = false; @@ -431,7 +445,7 @@ interface ReferencesCancellationState { callback(): void; } -let referencesPendingCancellations: ReferencesCancellationState[] = []; +const referencesPendingCancellations: ReferencesCancellationState[] = []; let abortRequestId: number = 0; @@ -490,7 +504,6 @@ export interface Client { onDidCloseTextDocument(document: vscode.TextDocument): void; onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void; onDidChangeTextDocument(textDocumentChangeEvent: vscode.TextDocumentChangeEvent): void; - onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void; onRegisterCustomConfigurationProvider(provider: CustomConfigurationProvider1): Thenable; updateCustomConfigurations(requestingProvider?: CustomConfigurationProvider1): Thenable; updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable; @@ -528,6 +541,7 @@ export interface Client { onInterval(): void; dispose(): Thenable; addFileAssociations(fileAssociations: string, is_c: boolean): void; + sendDidChangeSettings(settings: any): void; } export function createClient(allClients: ClientCollection, workspaceFolder?: vscode.WorkspaceFolder): Client { @@ -545,8 +559,8 @@ class FoldingRangeProvider implements vscode.FoldingRangeProvider { } provideFoldingRanges(document: vscode.TextDocument, context: vscode.FoldingContext, token: vscode.CancellationToken): Promise { - let id: number = ++abortRequestId; - let params: GetFoldingRangesParams = { + const id: number = ++abortRequestId; + const params: GetFoldingRangesParams = { id: id, uri: document.uri.toString() }; @@ -557,9 +571,9 @@ class FoldingRangeProvider implements vscode.FoldingRangeProvider { if (ranges.canceled) { reject(); } else { - let result: vscode.FoldingRange[] = []; + const result: vscode.FoldingRange[] = []; ranges.ranges.forEach((r) => { - let foldingRange: vscode.FoldingRange = { + const foldingRange: vscode.FoldingRange = { start: r.range.start.line, end: r.range.end.line }; @@ -587,25 +601,68 @@ class FoldingRangeProvider implements vscode.FoldingRangeProvider { } } +class SemanticTokensProvider implements vscode.DocumentSemanticTokensProvider { + private client: DefaultClient; + public onDidChangeSemanticTokensEvent = new vscode.EventEmitter(); + public onDidChangeSemanticTokens?: vscode.Event; + + constructor(client: DefaultClient) { + this.client = client; + this.onDidChangeSemanticTokens = this.onDidChangeSemanticTokensEvent.event; + } + + public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise { + return new Promise((resolve, reject) => { + this.client.notifyWhenReady(() => { + const uriString: string = document.uri.toString(); + const id: number = ++abortRequestId; + const params: GetSemanticTokensParams = { + id: id, + uri: uriString + }; + this.client.languageClient.sendRequest(GetSemanticTokensRequest, params) + .then((tokensResult) => { + if (tokensResult.canceled) { + reject(); + } else { + if (tokensResult.fileVersion !== this.client.openFileVersions.get(uriString)) { + reject(); + } else { + const builder: vscode.SemanticTokensBuilder = new vscode.SemanticTokensBuilder(this.client.semanticTokensLegend); + tokensResult.tokens.forEach((token) => { + builder.push(token.line, token.character, token.length, token.type, token.modifiers); + }); + resolve(builder.build()); + } + } + }); + token.onCancellationRequested(e => this.client.abortRequest(id)); + }); + }); + } +} + export class DefaultClient implements Client { private innerLanguageClient?: LanguageClient; // The "client" that launches and communicates with our language "server" process. private disposables: vscode.Disposable[] = []; private codeFoldingProviderDisposable: vscode.Disposable | undefined; + private semanticTokensProvider: SemanticTokensProvider | undefined; + private semanticTokensProviderDisposable: vscode.Disposable | undefined; private innerConfiguration?: configs.CppProperties; private rootPathFileWatcher?: vscode.FileSystemWatcher; private rootFolder?: vscode.WorkspaceFolder; private storagePath: string; private trackedDocuments = new Set(); private isSupported: boolean = true; - private colorizationSettings: ColorizationSettings; - private openFileVersions = new Map(); - private visibleRanges = new Map(); + private inactiveRegionsDecorations = new Map(); + public openFileVersions = new Map(); private settingsTracker: SettingsTracker; private configurationProvider?: string; private documentSelector: DocumentFilter[] = [ { scheme: 'file', language: 'cpp' }, { scheme: 'file', language: 'c' } ]; + public semanticTokensLegend: vscode.SemanticTokensLegend | undefined; // The "model" that is displayed via the UI (status bar). private model: ClientModel = new ClientModel(); @@ -674,7 +731,7 @@ export class DefaultClient implements Client { this.rootFolder = workspaceFolder; let storagePath: string | undefined; if (util.extensionContext) { - let path: string | undefined = util.extensionContext.storagePath; + const path: string | undefined = util.extensionContext.storagePath; if (path) { storagePath = path; } @@ -689,7 +746,6 @@ export class DefaultClient implements Client { this.storagePath = storagePath; const rootUri: vscode.Uri | undefined = this.RootUri; this.settingsTracker = getTracker(rootUri); - this.colorizationSettings = new ColorizationSettings(rootUri); try { let firstClient: boolean = false; if (!languageClient || languageClientCrashedNeedsRestart) { @@ -709,7 +765,7 @@ export class DefaultClient implements Client { // requests/notifications are deferred until this.languageClient is set. this.queueBlockingTask(() => languageClient.onReady().then( () => { - let workspaceFolder: vscode.WorkspaceFolder | undefined = this.rootFolder; + const workspaceFolder: vscode.WorkspaceFolder | undefined = this.rootFolder; this.innerConfiguration = new configs.CppProperties(rootUri, workspaceFolder); this.innerConfiguration.ConfigurationsChanged((e) => this.onConfigurationsChanged(e)); this.innerConfiguration.SelectionChanged((e) => this.onSelectedConfigurationChanged(e)); @@ -739,19 +795,19 @@ export class DefaultClient implements Client { r = Range.create(Position.create(range.start.line, range.start.character), Position.create(range.end.line, range.end.character)); } - let params: GetCodeActionsRequestParams = { + const params: GetCodeActionsRequestParams = { range: r, uri: document.uri.toString() }; return this.client.languageClient.sendRequest(GetCodeActionsRequest, params) .then((commands) => { - let resultCodeActions: vscode.CodeAction[] = []; + const resultCodeActions: vscode.CodeAction[] = []; // Convert to vscode.CodeAction array commands.forEach((command) => { - let title: string = util.getLocalizedString(command.localizeStringParams); - let vscodeCodeAction: vscode.CodeAction = { + const title: string = util.getLocalizedString(command.localizeStringParams); + const vscodeCodeAction: vscode.CodeAction = { title: title, command: { title: title, @@ -774,13 +830,13 @@ export class DefaultClient implements Client { this.client = client; } private getChildrenSymbols(symbols: LocalizeDocumentSymbol[]): vscode.DocumentSymbol[] { - let documentSymbols: vscode.DocumentSymbol[] = []; + const documentSymbols: vscode.DocumentSymbol[] = []; if (symbols) { symbols.forEach((symbol) => { - let detail: string = util.getLocalizedString(symbol.detail); - let r: vscode.Range= new vscode.Range(symbol.range.start.line, symbol.range.start.character, symbol.range.end.line, symbol.range.end.character); - let sr: vscode.Range= new vscode.Range(symbol.selectionRange.start.line, symbol.selectionRange.start.character, symbol.selectionRange.end.line, symbol.selectionRange.end.character); - let vscodeSymbol: vscode.DocumentSymbol = new vscode.DocumentSymbol (symbol.name, detail, symbol.kind, r, sr); + const detail: string = util.getLocalizedString(symbol.detail); + const r: vscode.Range= new vscode.Range(symbol.range.start.line, symbol.range.start.character, symbol.range.end.line, symbol.range.end.character); + const sr: vscode.Range= new vscode.Range(symbol.selectionRange.start.line, symbol.selectionRange.start.character, symbol.selectionRange.end.line, symbol.selectionRange.end.character); + const vscodeSymbol: vscode.DocumentSymbol = new vscode.DocumentSymbol (symbol.name, detail, symbol.kind, r, sr); vscodeSymbol.children = this.getChildrenSymbols(symbol.children); documentSymbols.push(vscodeSymbol); }); @@ -789,12 +845,12 @@ export class DefaultClient implements Client { } public async provideDocumentSymbols(document: vscode.TextDocument): Promise { return this.client.requestWhenReady(() => { - let params: GetDocumentSymbolRequestParams = { + const params: GetDocumentSymbolRequestParams = { uri: document.uri.toString() }; return this.client.languageClient.sendRequest(GetDocumentSymbolRequest, params) .then((symbols) => { - let resultSymbols: vscode.DocumentSymbol[] = this.getChildrenSymbols(symbols); + const resultSymbols: vscode.DocumentSymbol[] = this.getChildrenSymbols(symbols); return resultSymbols; }); }); @@ -808,25 +864,25 @@ export class DefaultClient implements Client { } public async provideWorkspaceSymbols(query: string, token: vscode.CancellationToken): Promise { - let params: WorkspaceSymbolParams = { + const params: WorkspaceSymbolParams = { query: query, workspaceFolderUri: this.client.RootPath }; return this.client.languageClient.sendRequest(GetSymbolInfoRequest, params) .then((symbols) => { - let resultSymbols: vscode.SymbolInformation[] = []; + const resultSymbols: vscode.SymbolInformation[] = []; // Convert to vscode.Command array symbols.forEach((symbol) => { - let suffix: string = util.getLocalizedString(symbol.suffix); + const suffix: string = util.getLocalizedString(symbol.suffix); let name: string = symbol.name; - let range: vscode.Range = new vscode.Range(symbol.location.range.start.line, symbol.location.range.start.character, symbol.location.range.end.line, symbol.location.range.end.character); - let uri: vscode.Uri = vscode.Uri.parse(symbol.location.uri.toString()); + const range: vscode.Range = new vscode.Range(symbol.location.range.start.line, symbol.location.range.start.character, symbol.location.range.end.line, symbol.location.range.end.character); + const uri: vscode.Uri = vscode.Uri.parse(symbol.location.uri.toString()); if (suffix.length) { name = name + ' (' + suffix + ')'; } - let vscodeSymbol: vscode.SymbolInformation = new vscode.SymbolInformation( + const vscodeSymbol: vscode.SymbolInformation = new vscode.SymbolInformation( name, symbol.kind, range, @@ -847,8 +903,8 @@ export class DefaultClient implements Client { } public async provideReferences(document: vscode.TextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Promise { return new Promise((resolve, reject) => { - let callback: () => void = () => { - let params: FindAllReferencesParams = { + const callback: () => void = () => { + const params: FindAllReferencesParams = { position: Position.create(position.line, position.character), textDocument: this.client.languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document) }; @@ -858,20 +914,20 @@ export class DefaultClient implements Client { // referencesParams does not match the object used when creating the request, abort it. if (params !== referencesParams) { // Complete with nothing instead of rejecting, to avoid an error message from VS Code - let locations: vscode.Location[] = []; + const locations: vscode.Location[] = []; resolve(locations); return; } referencesRequestPending = true; // Register a single-fire handler for the reply. - let resultCallback: refs.ReferencesResultCallback = (result: refs.ReferencesResult | null, doResolve: boolean) => { + const resultCallback: refs.ReferencesResultCallback = (result: refs.ReferencesResult | null, doResolve: boolean) => { referencesRequestPending = false; - let locations: vscode.Location[] = []; + const locations: vscode.Location[] = []; if (result) { result.referenceInfos.forEach((referenceInfo: refs.ReferenceInfo) => { if (referenceInfo.type === refs.ReferenceType.Confirmed) { - let uri: vscode.Uri = vscode.Uri.file(referenceInfo.file); - let range: vscode.Range = new vscode.Range(referenceInfo.position.line, referenceInfo.position.character, referenceInfo.position.line, referenceInfo.position.character + result.text.length); + 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 + result.text.length); locations.push(new vscode.Location(uri, range)); } }); @@ -882,11 +938,11 @@ export class DefaultClient implements Client { } if (referencesPendingCancellations.length > 0) { while (referencesPendingCancellations.length > 1) { - let pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; + const pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; referencesPendingCancellations.pop(); pendingCancel.reject(); } - let pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; + const pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; referencesPendingCancellations.pop(); pendingCancel.callback(); } @@ -899,7 +955,7 @@ export class DefaultClient implements Client { workspaceReferences.referencesRefreshPending = false; if (workspaceReferences.lastResults) { // This is a final result - let lastResults: refs.ReferencesResult = workspaceReferences.lastResults; + const lastResults: refs.ReferencesResult = workspaceReferences.lastResults; workspaceReferences.lastResults = null; resultCallback(lastResults, true); } else { @@ -918,10 +974,10 @@ export class DefaultClient implements Client { }; if (referencesRequestPending || (workspaceReferences.symbolSearchInProgress && !workspaceReferences.referencesRefreshPending)) { - let cancelling: boolean = referencesPendingCancellations.length > 0; + const cancelling: boolean = referencesPendingCancellations.length > 0; referencesPendingCancellations.push({ reject: () => { // Complete with nothing instead of rejecting, to avoid an error message from VS Code - let locations: vscode.Location[] = []; + const locations: vscode.Location[] = []; resolve(locations); }, callback }); if (!cancelling) { @@ -945,10 +1001,10 @@ export class DefaultClient implements Client { this.client = client; } public async provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string, token: vscode.CancellationToken): Promise { - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.renameRequiresIdentifier && !util.isValidIdentifier(newName)) { vscode.window.showErrorMessage(localize("invalid.identifier.for.rename", "Invalid identifier provided for the Rename Symbol operation.")); - let workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); return Promise.resolve(workspaceEdit); } // Normally, VS Code considers rename to be an atomic operation. @@ -959,8 +1015,8 @@ export class DefaultClient implements Client { renamePending = true; ++renameRequestsPending; return new Promise((resolve, reject) => { - let callback: () => void = () => { - let params: RenameParams = { + const callback: () => void = () => { + const params: RenameParams = { newName: newName, position: Position.create(position.line, position.character), textDocument: this.client.languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document) @@ -975,7 +1031,7 @@ export class DefaultClient implements Client { } // Complete with nothing instead of rejecting, to avoid an error message from VS Code - let workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); resolve(workspaceEdit); return; } @@ -983,15 +1039,15 @@ export class DefaultClient implements Client { workspaceReferences.setResultsCallback((referencesResult: refs.ReferencesResult | null, doResolve: boolean) => { referencesRequestPending = false; --renameRequestsPending; - let workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); - let cancelling: boolean = referencesPendingCancellations.length > 0; + const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const cancelling: boolean = referencesPendingCancellations.length > 0; if (cancelling) { while (referencesPendingCancellations.length > 1) { - let pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; + const pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; referencesPendingCancellations.pop(); pendingCancel.reject(); } - let pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; + const pendingCancel: ReferencesCancellationState = referencesPendingCancellations[0]; referencesPendingCancellations.pop(); pendingCancel.callback(); } else { @@ -1001,10 +1057,10 @@ export class DefaultClient implements Client { // If rename UI was canceled, we will get a null result. // If null, return an empty list to avoid Rename failure dialog. if (referencesResult) { - for (let reference of referencesResult.referenceInfos) { - let uri: vscode.Uri = vscode.Uri.file(reference.file); - let range: vscode.Range = new vscode.Range(reference.position.line, reference.position.character, reference.position.line, reference.position.character + referencesResult.text.length); - let metadata: vscode.WorkspaceEditEntryMetadata = { + for (const reference of referencesResult.referenceInfos) { + const uri: vscode.Uri = vscode.Uri.file(reference.file); + const range: vscode.Range = new vscode.Range(reference.position.line, reference.position.character, reference.position.line, reference.position.character + referencesResult.text.length); + const metadata: vscode.WorkspaceEditEntryMetadata = { needsConfirmation: reference.type !== refs.ReferenceType.Confirmed, label: refs.getReferenceTagString(reference.type, false, true), iconPath: refs.getReferenceItemIconPath(reference.type, false) @@ -1023,11 +1079,11 @@ export class DefaultClient implements Client { }; if (referencesRequestPending || workspaceReferences.symbolSearchInProgress) { - let cancelling: boolean = referencesPendingCancellations.length > 0; + const cancelling: boolean = referencesPendingCancellations.length > 0; referencesPendingCancellations.push({ reject: () => { --renameRequestsPending; // Complete with nothing instead of rejecting, to avoid an error message from VS Code - let workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const workspaceEdit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); resolve(workspaceEdit); }, callback }); if (!cancelling) { @@ -1044,6 +1100,24 @@ export class DefaultClient implements Client { } } + // Semantic token types are identified by indexes in this list of types, in the legend. + const tokenTypesLegend: string[] = []; + for (const e in SemanticTokenTypes) { + // An enum is actually a set of mappings from key <=> value. Enumerate over only the names. + // This allow us to represent the constants using an enum, which we can match in native code. + if (isNaN(Number(e))) { + tokenTypesLegend.push(e); + } + } + // Semantic token modifiers are bit indexes corresponding to the indexes in this list of modifiers in the legend. + const tokenModifiersLegend: string[] = []; + for (const e in SemanticTokenModifiers) { + if (isNaN(Number(e))) { + tokenModifiersLegend.push(e); + } + } + this.semanticTokensLegend = new vscode.SemanticTokensLegend(tokenTypesLegend, tokenModifiersLegend); + if (firstClient) { workspaceReferences = new refs.ReferencesManager(this); @@ -1064,10 +1138,14 @@ export class DefaultClient implements Client { this.disposables.push(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(this))); this.disposables.push(vscode.languages.registerDocumentSymbolProvider(this.documentSelector, new DocumentSymbolProvider(this), undefined)); this.disposables.push(vscode.languages.registerCodeActionsProvider(this.documentSelector, new CodeActionProvider(this), undefined)); - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.codeFolding) { this.codeFoldingProviderDisposable = vscode.languages.registerFoldingRangeProvider(this.documentSelector, new FoldingRangeProvider(this)); } + if (settings.enhancedColorization && this.semanticTokensLegend) { + this.semanticTokensProvider = new SemanticTokensProvider(this); + this.semanticTokensProviderDisposable = vscode.languages.registerDocumentSemanticTokensProvider(this.documentSelector, this.semanticTokensProvider, this.semanticTokensLegend); + } // Listen for messages from the language server. this.registerNotifications(); @@ -1083,7 +1161,6 @@ export class DefaultClient implements Client { vscode.window.showErrorMessage(localize("unable.to.start", "Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: {0}", String(err))); } })); - this.colorizationSettings.reload(); } catch (err) { this.isSupported = false; // Running on an OS we don't support yet. if (!failureMessageShown) { @@ -1108,14 +1185,14 @@ export class DefaultClient implements Client { } private createLanguageClient(allClients: ClientCollection): LanguageClient { - let serverModule: string = getLanguageServerFileName(); - let exeExists: boolean = fs.existsSync(serverModule); + const serverModule: string = getLanguageServerFileName(); + const exeExists: boolean = fs.existsSync(serverModule); if (!exeExists) { telemetry.logLanguageServerEvent("missingLanguageServerBinary"); throw String('Missing binary at ' + serverModule); } - let serverName: string = this.getName(this.rootFolder); - let serverOptions: ServerOptions = { + const serverName: string = this.getName(this.rootFolder); + const serverOptions: ServerOptions = { run: { command: serverModule }, debug: { command: serverModule, args: [ serverName ] } }; @@ -1124,34 +1201,34 @@ export class DefaultClient implements Client { // They're sent as individual arrays to make it easier to process on the server, // so don't refactor this to an array of settings objects unless a good method is // found for processing data in that format on the server. - let settings_clangFormatPath: (string | undefined)[] = []; - let settings_clangFormatStyle: (string | undefined)[] = []; - let settings_clangFormatFallbackStyle: (string | undefined)[] = []; - let settings_clangFormatSortIncludes: (string | undefined)[] = []; - let settings_filesExclude: (vscode.WorkspaceConfiguration | undefined)[] = []; - let settings_searchExclude: (vscode.WorkspaceConfiguration | undefined)[] = []; - let settings_editorTabSize: (number | undefined)[] = []; - let settings_intelliSenseEngine: (string | undefined)[] = []; - let settings_intelliSenseEngineFallback: (string | undefined)[] = []; - let settings_errorSquiggles: (string | undefined)[] = []; - let settings_dimInactiveRegions: boolean[] = []; - let settings_enhancedColorization: string[] = []; - let settings_suggestSnippets: (boolean | undefined)[] = []; - let settings_exclusionPolicy: (string | undefined)[] = []; - let settings_preferredPathSeparator: (string | undefined)[] = []; - let settings_defaultSystemIncludePath: (string[] | undefined)[] = []; - let settings_intelliSenseCachePath: (string | undefined)[] = []; - let settings_intelliSenseCacheSize: (number | undefined)[] = []; - let settings_autoComplete: (string | undefined)[] = []; - let settings_formatting: (string | undefined)[] = []; - let workspaceSettings: CppSettings = new CppSettings(); - let workspaceOtherSettings: OtherSettings = new OtherSettings(); + const settings_clangFormatPath: (string | undefined)[] = []; + const settings_clangFormatStyle: (string | undefined)[] = []; + const settings_clangFormatFallbackStyle: (string | undefined)[] = []; + const settings_clangFormatSortIncludes: (string | undefined)[] = []; + const settings_filesExclude: (vscode.WorkspaceConfiguration | undefined)[] = []; + const settings_searchExclude: (vscode.WorkspaceConfiguration | undefined)[] = []; + const settings_editorTabSize: (number | undefined)[] = []; + const settings_intelliSenseEngine: (string | undefined)[] = []; + const settings_intelliSenseEngineFallback: (string | undefined)[] = []; + const settings_errorSquiggles: (string | undefined)[] = []; + const settings_dimInactiveRegions: boolean[] = []; + const settings_enhancedColorization: string[] = []; + const settings_suggestSnippets: (boolean | undefined)[] = []; + const settings_exclusionPolicy: (string | undefined)[] = []; + const settings_preferredPathSeparator: (string | undefined)[] = []; + const settings_defaultSystemIncludePath: (string[] | undefined)[] = []; + const settings_intelliSenseCachePath: (string | undefined)[] = []; + const settings_intelliSenseCacheSize: (number | undefined)[] = []; + const settings_autoComplete: (string | undefined)[] = []; + const settings_formatting: (string | undefined)[] = []; + const workspaceSettings: CppSettings = new CppSettings(); + const workspaceOtherSettings: OtherSettings = new OtherSettings(); { - let settings: CppSettings[] = []; - let otherSettings: OtherSettings[] = []; + const settings: CppSettings[] = []; + const otherSettings: OtherSettings[] = []; if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { - for (let workspaceFolder of vscode.workspace.workspaceFolders) { + for (const workspaceFolder of vscode.workspace.workspaceFolders) { settings.push(new CppSettings(workspaceFolder.uri)); otherSettings.push(new OtherSettings(workspaceFolder.uri)); } @@ -1160,7 +1237,7 @@ export class DefaultClient implements Client { otherSettings.push(workspaceOtherSettings); } - for (let setting of settings) { + for (const setting of settings) { settings_clangFormatPath.push(util.resolveVariables(setting.clangFormatPath, this.AdditionalEnvironment)); settings_clangFormatStyle.push(setting.clangFormatStyle); settings_clangFormatFallbackStyle.push(setting.clangFormatFallbackStyle); @@ -1180,14 +1257,14 @@ export class DefaultClient implements Client { settings_formatting.push(setting.formatting); } - for (let otherSetting of otherSettings) { + for (const otherSetting of otherSettings) { settings_filesExclude.push(otherSetting.filesExclude); settings_searchExclude.push(otherSetting.searchExclude); settings_editorTabSize.push(otherSetting.editorTabSize); } } - let abTestSettings: ABTestSettings = getABTestSettings(); + const abTestSettings: ABTestSettings = getABTestSettings(); let intelliSenseCacheDisabled: boolean = false; if (os.platform() === "darwin") { @@ -1198,7 +1275,12 @@ export class DefaultClient implements Client { } } - let clientOptions: LanguageClientOptions = { + const localizedStrings: string[] = []; + for (let i: number = 0; i < localizedStringCount; i++) { + localizedStrings.push(lookupString(i)); + } + + const clientOptions: LanguageClientOptions = { documentSelector: [ { scheme: 'file', language: 'cpp' }, { scheme: 'file', language: 'c' } @@ -1225,6 +1307,7 @@ export class DefaultClient implements Client { dimInactiveRegions: settings_dimInactiveRegions, enhancedColorization: settings_enhancedColorization, suggestSnippets: settings_suggestSnippets, + simplifyStructuredComments: workspaceSettings.simplifyStructuredComments, loggingLevel: workspaceSettings.loggingLevel, workspaceParsingPriority: workspaceSettings.workspaceParsingPriority, workspaceSymbols: workspaceSettings.workspaceSymbols, @@ -1236,7 +1319,8 @@ export class DefaultClient implements Client { vcpkg_root: util.getVcpkgRoot(), gotoDefIntelliSense: abTestSettings.UseGoToDefIntelliSense, experimentalFeatures: workspaceSettings.experimentalFeatures, - edgeMessagesDirectory: path.join(util.getExtensionFilePath("bin"), "messages", util.getLocaleId()) + edgeMessagesDirectory: path.join(util.getExtensionFilePath("bin"), "messages", util.getLocaleId()), + localizedStrings: localizedStrings }, middleware: createProtocolFilter(allClients), errorHandler: { @@ -1248,7 +1332,7 @@ export class DefaultClient implements Client { if (languageClientCrashTimes.length < 5) { allClients.forEach(client => { allClients.replace(client, true); }); } else { - let elapsed: number = languageClientCrashTimes[languageClientCrashTimes.length - 1] - languageClientCrashTimes[0]; + const elapsed: number = languageClientCrashTimes[languageClientCrashTimes.length - 1] - languageClientCrashTimes[0]; if (elapsed <= 3 * 60 * 1000) { vscode.window.showErrorMessage(localize('server.crashed2', "The language server crashed 5 times in the last 3 minutes. It will not be restarted.")); allClients.forEach(client => { allClients.replace(client, false); }); @@ -1268,19 +1352,19 @@ export class DefaultClient implements Client { return new LanguageClient(`cpptools`, serverOptions, clientOptions); } - public sendDidChangeSettings(): void { - let cppSettingsScoped: { [key: string]: any } = {}; + public sendAllSettings(): void { + const cppSettingsScoped: { [key: string]: any } = {}; // Gather the C_Cpp settings { - let cppSettingsResourceScoped: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", this.RootUri); - let cppSettingsNonScoped: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp"); + const cppSettingsResourceScoped: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", this.RootUri); + const cppSettingsNonScoped: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp"); - for (let key in cppSettingsResourceScoped) { - let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key]; + for (const key in cppSettingsResourceScoped) { + const curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key]; if (curSetting === undefined) { continue; } - let settings: vscode.WorkspaceConfiguration = (curSetting.scope === "resource" || curSetting.scope === "machine-overridable") ? cppSettingsResourceScoped : cppSettingsNonScoped; + const settings: vscode.WorkspaceConfiguration = (curSetting.scope === "resource" || curSetting.scope === "machine-overridable") ? cppSettingsResourceScoped : cppSettingsNonScoped; cppSettingsScoped[key] = settings.get(key); } cppSettingsScoped["default"] = { systemIncludePath: cppSettingsResourceScoped.get("default.systemIncludePath") }; @@ -1288,19 +1372,24 @@ export class DefaultClient implements Client { // Unlike the LSP message, the event does not contain all settings as a payload, so we need to // build a new JSON object with everything we need on the native side. - let settings: any = { + const settings: any = { C_Cpp: { ...cppSettingsScoped, tabSize: vscode.workspace.getConfiguration("editor.tabSize", this.RootUri) }, files: { - exclude: vscode.workspace.getConfiguration("files.exclude", this.RootUri) + exclude: vscode.workspace.getConfiguration("files.exclude", this.RootUri), + associations: new OtherSettings().filesAssociations }, search: { exclude: vscode.workspace.getConfiguration("search.exclude", this.RootUri) } }; + this.sendDidChangeSettings(settings); + } + + public sendDidChangeSettings(settings: any): void { // Send settings json to native side this.notifyWhenReady(() => { this.languageClient.sendNotification(DidChangeSettingsNotification, {settings, workspaceFolderUri: this.RootPath}); @@ -1308,54 +1397,15 @@ export class DefaultClient implements Client { } public onDidChangeSettings(event: vscode.ConfigurationChangeEvent, isFirstClient: boolean): { [key: string]: string } { - this.sendDidChangeSettings(); - let changedSettings: { [key: string]: string }; - changedSettings = this.settingsTracker.getChangedSettings(); + this.sendAllSettings(); + const changedSettings: { [key: string]: string } = this.settingsTracker.getChangedSettings(); this.notifyWhenReady(() => { - let colorizationNeedsReload: boolean = isFirstClient && (event.affectsConfiguration("workbench.colorTheme") - || event.affectsConfiguration("editor.tokenColorCustomizations")); - - let colorizationNeedsRefresh: boolean = colorizationNeedsReload - || event.affectsConfiguration("C_Cpp.enhancedColorization", this.RootUri) - || event.affectsConfiguration("C_Cpp.dimInactiveRegions", this.RootUri) - || event.affectsConfiguration("C_Cpp.inactiveRegionOpacity", this.RootUri) - || event.affectsConfiguration("C_Cpp.inactiveRegionForegroundColor", this.RootUri) - || event.affectsConfiguration("C_Cpp.inactiveRegionBackgroundColor", this.RootUri); - - if (isFirstClient) { - let colorThemeChanged: boolean = event.affectsConfiguration("workbench.colorTheme"); - if (colorThemeChanged) { - let otherSettings: OtherSettings = new OtherSettings(); - this.languageClient.sendNotification(ColorThemeChangedNotification, { name: otherSettings.colorTheme }); - } - } - - if (colorizationNeedsReload) { - this.colorizationSettings.reload(); - } - if (colorizationNeedsRefresh) { - let processedUris: vscode.Uri[] = []; - for (let e of vscode.window.visibleTextEditors) { - let uri: vscode.Uri = e.document.uri; - - // Make sure we don't process the same file multiple times. - // colorizationState.onSettingsChanged ensures all visible text editors for that file get - // refreshed, after it creates a set of decorators to be shared by all visible instances of the file. - if (!processedUris.find(e => e === uri)) { - processedUris.push(uri); - let colorizationState: ColorizationState | undefined = workspaceColorizationState.get(uri.toString()); - if (colorizationState) { - colorizationState.onSettingsChanged(uri); - } - } - } - } if (Object.keys(changedSettings).length > 0) { if (changedSettings["commentContinuationPatterns"]) { updateLanguageConfigurations(); } if (changedSettings["codeFolding"]) { - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.codeFolding) { this.codeFoldingProviderDisposable = vscode.languages.registerFoldingRangeProvider(this.documentSelector, new FoldingRangeProvider(this)); } else if (this.codeFoldingProviderDisposable) { @@ -1363,6 +1413,17 @@ export class DefaultClient implements Client { this.codeFoldingProviderDisposable = undefined; } } + if (changedSettings["enhancedColorization"]) { + const settings: CppSettings = new CppSettings(); + if (settings.enhancedColorization && this.semanticTokensLegend) { + this.semanticTokensProvider = new SemanticTokensProvider(this); + this.semanticTokensProviderDisposable = vscode.languages.registerDocumentSemanticTokensProvider(this.documentSelector, new SemanticTokensProvider(this), this.semanticTokensLegend); ; + } else if (this.semanticTokensProviderDisposable) { + this.semanticTokensProviderDisposable.dispose(); + this.semanticTokensProviderDisposable = undefined; + this.semanticTokensProvider = undefined; + } + } this.configuration.onDidChangeSettings(); telemetry.logLanguageServerEvent("CppSettingsChange", changedSettings, undefined); } @@ -1370,33 +1431,31 @@ export class DefaultClient implements Client { return changedSettings; } - private editVersion: number = 0; + public onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void { + const settings: CppSettings = new CppSettings(this.RootUri); + if (settings.dimInactiveRegions) { + // Apply text decorations to inactive regions + for (const e of editors) { + const valuePair: DecorationRangesPair | undefined = this.inactiveRegionsDecorations.get(e.document.uri.toString()); + if (valuePair) { + e.setDecorations(valuePair.decoration, valuePair.ranges); // VSCode clears the decorations when the text editor becomes invisible + } + } + } + } public onDidChangeTextDocument(textDocumentChangeEvent: vscode.TextDocumentChangeEvent): void { - // Increment editVersion for every call to onDidChangeTextDocument, regardless of whether the file is handled - this.editVersion++; if (textDocumentChangeEvent.document.uri.scheme === "file") { if (textDocumentChangeEvent.document.languageId === "cpp" || textDocumentChangeEvent.document.languageId === "c") { - // If any file has changed, we need to abort the current rename operation if (renamePending) { this.cancelReferences(); } - let oldVersion: number | undefined = this.openFileVersions.get(textDocumentChangeEvent.document.uri.toString()); - let newVersion: number = textDocumentChangeEvent.document.version; + const oldVersion: number | undefined = this.openFileVersions.get(textDocumentChangeEvent.document.uri.toString()); + const newVersion: number = textDocumentChangeEvent.document.version; if (oldVersion === undefined || newVersion > oldVersion) { this.openFileVersions.set(textDocumentChangeEvent.document.uri.toString(), newVersion); - try { - let colorizationState: ColorizationState | undefined = workspaceColorizationState.get(textDocumentChangeEvent.document.uri.toString()); - if (colorizationState) { - // Adjust colorization ranges after this edit. (i.e. if a line was added, push decorations after it down one line) - colorizationState.addEdits(textDocumentChangeEvent.contentChanges, this.editVersion); - } - } catch (e) { - // Ensure an exception does not prevent pass-through to native handler, or editVersion could become inconsistent - console.log(e.toString()); - } } } } @@ -1405,83 +1464,16 @@ export class DefaultClient implements Client { public onDidOpenTextDocument(document: vscode.TextDocument): void { if (document.uri.scheme === "file") { this.openFileVersions.set(document.uri.toString(), document.version); - workspaceColorizationState.set(document.uri.toString(), new ColorizationState(document.uri, this.colorizationSettings)); - this.sendVisibleRanges(document.uri); } } public onDidCloseTextDocument(document: vscode.TextDocument): void { - workspaceColorizationState.delete(document.uri.toString()); this.openFileVersions.delete(document.uri.toString()); } - public onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void { - let processedUris: vscode.Uri[] = []; - editors.forEach(editor => { - if (editor.document.uri.scheme === "file") { - let colorizationState: ColorizationState | undefined = workspaceColorizationState.get(editor.document.uri.toString()); - if (colorizationState) { - colorizationState.refresh(editor); - if (!processedUris.find(uri => uri === editor.document.uri)) { - processedUris.push(editor.document.uri); - this.sendVisibleRanges(editor.document.uri); - } - } - } - }); - } - - public sendVisibleRanges(uri: vscode.Uri): void { - let ranges: Range[] = []; - // Get ranges from all editors matching this URI - let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri === uri); - for (let e of editors) { - e.visibleRanges.forEach(range => ranges.push(Range.create(range.start.line, range.start.character, range.end.line, range.end.character))); - } - - // Only send ranges if they have actually changed. - let isSame: boolean = false; - let savedRanges: Range[] | undefined = this.visibleRanges.get(uri.toString()); - if (savedRanges) { - if (ranges.length === savedRanges.length) { - isSame = true; - for (let i: number = 0; i < ranges.length; i++) { - if (ranges[i] !== savedRanges[i]) { - isSame = false; - break; - } - } - } - } else { - isSame = ranges.length === 0; - } - if (!isSame) { - this.visibleRanges.set(uri.toString(), ranges); - let params: DidChangeVisibleRangesParams = { - uri: uri.toString(), - ranges: ranges - }; - this.notifyWhenReady(() => this.languageClient.sendNotification(DidChangeVisibleRangesNotification, params)); - } - } - - public onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void { - this.notifyWhenReady(() => { - if (textEditorVisibleRangesChangeEvent.textEditor.document.uri.scheme === "file") { - if (vscode.window.activeTextEditor === textEditorVisibleRangesChangeEvent.textEditor) { - if (textEditorVisibleRangesChangeEvent.visibleRanges.length === 1) { - let visibleRangesLength: number = textEditorVisibleRangesChangeEvent.visibleRanges[0].end.line - textEditorVisibleRangesChangeEvent.visibleRanges[0].start.line; - workspaceReferences.updateVisibleRange(visibleRangesLength); - } - } - this.sendVisibleRanges(textEditorVisibleRangesChangeEvent.textEditor.document.uri); - } - }); - } - private registeredProviders: CustomConfigurationProvider1[] = []; public onRegisterCustomConfigurationProvider(provider: CustomConfigurationProvider1): Thenable { - let onRegistered: () => void = () => { + const onRegistered: () => void = () => { // version 2 providers control the browse.path. Avoid thrashing the tag parser database by pausing parsing until // the provider has sent the correct browse.path value. if (provider.version >= Version.v2) { @@ -1493,13 +1485,13 @@ export class DefaultClient implements Client { return; // Prevent duplicate processing. } this.registeredProviders.push(provider); - let rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; + const rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; if (!rootFolder) { return; // There is no c_cpp_properties.json to edit because there is no folder open. } - let selectedProvider: string | undefined = this.configuration.CurrentConfigurationProvider; + const selectedProvider: string | undefined = this.configuration.CurrentConfigurationProvider; if (!selectedProvider) { - let ask: PersistentFolderState = new PersistentFolderState("Client.registerProvider", true, rootFolder); + const ask: PersistentFolderState = new PersistentFolderState("Client.registerProvider", true, rootFolder); // If c_cpp_properties.json and settings.json are both missing, reset our prompt if (!fs.existsSync(`${this.RootPath}/.vscode/c_cpp_properties.json`) && !fs.existsSync(`${this.RootPath}/.vscode/settings.json`)) { ask.Value = true; @@ -1552,7 +1544,7 @@ export class DefaultClient implements Client { this.clearCustomConfigurations(); return; } - let currentProvider: CustomConfigurationProvider1 | undefined = getCustomConfigProviders().get(this.configurationProvider); + const currentProvider: CustomConfigurationProvider1 | undefined = getCustomConfigProviders().get(this.configurationProvider); if (!currentProvider) { this.clearCustomConfigurations(); return; @@ -1580,8 +1572,8 @@ export class DefaultClient implements Client { return; } - let tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); - let task: () => Thenable = async () => { + const tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); + const task: () => Thenable = async () => { if (this.RootUri && await currentProvider.canProvideBrowseConfigurationsPerFolder(tokenSource.token)) { return (currentProvider.provideFolderBrowseConfiguration(this.RootUri, tokenSource.token)); } @@ -1603,7 +1595,7 @@ export class DefaultClient implements Client { } if (currentProvider.version < Version.v3) { // This is to get around the (fixed) CMake Tools bug: https://github.com/microsoft/vscode-cmake-tools/issues/1073 - for (let c of config.browsePath) { + for (const c of config.browsePath) { if (vscode.workspace.getWorkspaceFolder(vscode.Uri.file(c)) === this.RootFolder) { this.sendCustomBrowseConfiguration(config, currentProvider.extensionId); break; @@ -1646,19 +1638,46 @@ export class DefaultClient implements Client { } public async logDiagnostics(): Promise { - let response: GetDiagnosticsResult = await this.requestWhenReady(() => this.languageClient.sendRequest(GetDiagnosticsRequest, null)); + const response: GetDiagnosticsResult = await this.requestWhenReady(() => this.languageClient.sendRequest(GetDiagnosticsRequest, null)); if (!diagnosticsChannel) { diagnosticsChannel = vscode.window.createOutputChannel(localize("c.cpp.diagnostics", "C/C++ Diagnostics")); workspaceDisposables.push(diagnosticsChannel); + } else { + diagnosticsChannel.clear(); } - let header: string = `-------- Diagnostics - ${new Date().toLocaleString()}\n`; - let version: string = `Version: ${util.packageJson.version}\n`; + const header: string = `-------- Diagnostics - ${new Date().toLocaleString()}\n`; + const version: string = `Version: ${util.packageJson.version}\n`; let configJson: string = ""; if (this.configuration.CurrentConfiguration) { configJson = `Current Configuration:\n${JSON.stringify(this.configuration.CurrentConfiguration, null, 4)}\n`; } - diagnosticsChannel.appendLine(`${header}${version}${configJson}${response.diagnostics}`); + + // Get diagnotics for configuration provider info. + let configurationLoggingStr: string = ""; + const tuSearchStart: number = response.diagnostics.indexOf("Translation Unit Mappings:"); + if (tuSearchStart >= 0) { + const tuSearchEnd: number = response.diagnostics.indexOf("Translation Unit Configurations:"); + if (tuSearchEnd >= 0 && tuSearchEnd > tuSearchStart) { + let tuSearchString: string = response.diagnostics.substr(tuSearchStart, tuSearchEnd - tuSearchStart); + let tuSearchIndex: number = tuSearchString.indexOf("["); + while (tuSearchIndex >= 0) { + const tuMatch: RegExpMatchArray | null = tuSearchString.match(/\[\s(.*)\s\]/); + if (tuMatch && tuMatch.length > 1) { + const tuPath: string = vscode.Uri.file(tuMatch[1]).toString(); + if (this.configurationLogging.has(tuPath)) { + if (configurationLoggingStr.length === 0) { + configurationLoggingStr += "Custom configurations:\n"; + } + configurationLoggingStr += `[ ${tuMatch[1]} ]\n${this.configurationLogging.get(tuPath)}\n`; + } + } + tuSearchString = tuSearchString.substr(tuSearchIndex + 1); + tuSearchIndex = tuSearchString.indexOf("["); + } + } + } + diagnosticsChannel.appendLine(`${header}${version}${configJson}${this.browseConfigurationLogging}${configurationLoggingStr}${response.diagnostics}`); diagnosticsChannel.show(false); } @@ -1667,12 +1686,12 @@ export class DefaultClient implements Client { } public async provideCustomConfiguration(docUri: vscode.Uri, requestFile?: string): Promise { - let onFinished: () => void = () => { + const onFinished: () => void = () => { if (requestFile) { this.languageClient.sendNotification(FinishedRequestCustomConfig, requestFile); } }; - let providerId: string | undefined = this.configurationProvider; + const providerId: string | undefined = this.configurationProvider; if (!providerId) { onFinished(); return Promise.resolve(); @@ -1687,16 +1706,16 @@ export class DefaultClient implements Client { return Promise.reject(`${this.configurationProvider} is not ready`); } return this.queueBlockingTask(async () => { - let tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); + const tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); console.log("provideCustomConfiguration"); - let providerName: string = provider.name; + const providerName: string = provider.name; - let params: QueryTranslationUnitSourceParams = { + const params: QueryTranslationUnitSourceParams = { uri: docUri.toString(), workspaceFolderUri: this.RootPath }; - let response: QueryTranslationUnitSourceResult = await this.languageClient.sendRequest(QueryTranslationUnitSourceRequest, params); + const response: QueryTranslationUnitSourceResult = await this.languageClient.sendRequest(QueryTranslationUnitSourceRequest, params); if (!response.candidates || response.candidates.length === 0) { // If we didn't receive any candidates, no configuration is needed. onFinished(); @@ -1705,14 +1724,14 @@ export class DefaultClient implements Client { // Need to loop through candidates, to see if we can get a custom configuration from any of them. // Wrap all lookups in a single task, so we can apply a timeout to the entire duration. - let provideConfigurationAsync: () => Thenable = async () => { + const provideConfigurationAsync: () => Thenable = async () => { if (provider) { for (let i: number = 0; i < response.candidates.length; ++i) { try { - let candidate: string = response.candidates[i]; - let tuUri: vscode.Uri = vscode.Uri.parse(candidate); + const candidate: string = response.candidates[i]; + const tuUri: vscode.Uri = vscode.Uri.parse(candidate); if (await provider.canProvideConfiguration(tuUri, tokenSource.token)) { - let configs: SourceFileConfigurationItem[] = await provider.provideConfigurations([tuUri], tokenSource.token); + const configs: SourceFileConfigurationItem[] = await provider.provideConfigurations([tuUri], tokenSource.token); if (configs && configs.length > 0 && configs[0]) { return configs; } @@ -1738,11 +1757,11 @@ export class DefaultClient implements Client { onFinished(); return; } - let settings: CppSettings = new CppSettings(this.RootUri); + const settings: CppSettings = new CppSettings(this.RootUri); if (settings.configurationWarnings === "Enabled" && !this.isExternalHeader(docUri) && !vscode.debug.activeDebugSession) { const dismiss: string = localize("dismiss.button", "Dismiss"); const disable: string = localize("diable.warnings.button", "Disable Warnings"); - let configName: string | undefined = this.configuration.CurrentConfiguration?.name; + const configName: string | undefined = this.configuration.CurrentConfiguration?.name; if (!configName) { return; } @@ -1771,7 +1790,7 @@ export class DefaultClient implements Client { } private isExternalHeader(uri: vscode.Uri): boolean { - let rootUri: vscode.Uri | undefined = this.RootUri; + const rootUri: vscode.Uri | undefined = this.RootUri; return !rootUri || (util.isHeader(uri) && !uri.toString().startsWith(rootUri.toString())); } @@ -1785,8 +1804,8 @@ export class DefaultClient implements Client { public setCurrentConfigName(configurationName: string): Thenable { return this.queueTask(() => new Promise((resolve, reject) => { - let configurations: configs.Configuration[] = this.configuration.Configurations || []; - let configurationIndex: number = configurations.findIndex((config) => config.name === configurationName); + const configurations: configs.Configuration[] = this.configuration.Configurations || []; + const configurationIndex: number = configurations.findIndex((config) => config.name === configurationName); if (configurationIndex !== -1) { this.configuration.select(configurationIndex); @@ -1825,7 +1844,7 @@ export class DefaultClient implements Client { * tracked documents. */ public takeOwnership(document: vscode.TextDocument): void { - let params: DidOpenTextDocumentParams = { + const params: DidOpenTextDocumentParams = { textDocument: { uri: document.uri.toString(), languageId: document.languageId, @@ -1844,7 +1863,7 @@ export class DefaultClient implements Client { public queueTask(task: () => Thenable): Thenable { if (this.isSupported) { - let nextTask: () => Thenable = async () => { + const nextTask: () => Thenable = async () => { try { return await task(); } catch (err) { @@ -1882,7 +1901,7 @@ export class DefaultClient implements Client { private callTaskWithTimeout(task: () => Thenable, ms: number, cancelToken?: vscode.CancellationTokenSource): Thenable { let timer: NodeJS.Timer; // Create a promise that rejects in milliseconds - let timeout: () => Promise = () => new Promise((resolve, reject) => { + const timeout: () => Promise = () => new Promise((resolve, reject) => { timer = global.setTimeout(() => { clearTimeout(timer); if (cancelToken) { @@ -1909,7 +1928,7 @@ export class DefaultClient implements Client { } public notifyWhenReady(notify: () => T): Thenable { - let task: () => Thenable = () => new Promise(resolve => { + const task: () => Thenable = () => new Promise(resolve => { resolve(notify()); }); return this.queueTask(task); @@ -1925,22 +1944,23 @@ export class DefaultClient implements Client { this.languageClient.onNotification(LogTelemetryNotification, logTelemetry); this.languageClient.onNotification(ReportStatusNotification, (e) => this.updateStatus(e)); this.languageClient.onNotification(ReportTagParseStatusNotification, (e) => this.updateTagParseStatus(e)); - this.languageClient.onNotification(SemanticColorizationRegionsNotification, updateSemanticColorizationRegions); + this.languageClient.onNotification(InactiveRegionNotification, (e) => this.updateInactiveRegions(e)); this.languageClient.onNotification(CompileCommandsPathsNotification, (e) => this.promptCompileCommands(e)); this.languageClient.onNotification(ReferencesNotification, (e) => this.processReferencesResult(e.referencesResult)); this.languageClient.onNotification(ReportReferencesProgressNotification, (e) => this.handleReferencesProgress(e)); this.languageClient.onNotification(RequestCustomConfig, (requestFile: string) => { - let client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(requestFile)); + const client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(requestFile)); client.handleRequestCustomConfig(requestFile); }); this.languageClient.onNotification(PublishDiagnosticsNotification, publishDiagnostics); this.languageClient.onNotification(ShowMessageWindowNotification, showMessageWindow); this.languageClient.onNotification(ReportTextDocumentLanguage, (e) => this.setTextDocumentLanguage(e)); + this.languageClient.onNotification(SemanticTokensChanged, (e) => this.semanticTokensProvider?.onDidChangeSemanticTokensEvent.fire()); setupOutputHandlers(); } private setTextDocumentLanguage(languageStr: string): void { - let cppSettings: CppSettings = new CppSettings(); + const cppSettings: CppSettings = new CppSettings(); if (cppSettings.autoAddFileAssociations) { const is_c: boolean = languageStr.startsWith("c;"); languageStr = languageStr.substr(is_c ? 2 : 1); @@ -1970,25 +1990,24 @@ export class DefaultClient implements Client { // TODO: Handle new associations without a reload. this.associations_for_did_change = new Set(["c", "i", "cpp", "cc", "cxx", "c++", "cp", "hpp", "hh", "hxx", "h++", "hp", "h", "ii", "ino", "inl", "ipp", "tcc", "idl"]); - let settings: OtherSettings = new OtherSettings(this.RootUri); - let assocs: any = settings.filesAssociations; - for (let assoc in assocs) { - let dotIndex: number = assoc.lastIndexOf('.'); + const assocs: any = new OtherSettings().filesAssociations; + for (const assoc in assocs) { + const dotIndex: number = assoc.lastIndexOf('.'); if (dotIndex !== -1) { - let ext: string = assoc.substr(dotIndex + 1); + const ext: string = assoc.substr(dotIndex + 1); this.associations_for_did_change.add(ext); } } this.rootPathFileWatcher.onDidChange((uri) => { - let dotIndex: number = uri.fsPath.lastIndexOf('.'); + const dotIndex: number = uri.fsPath.lastIndexOf('.'); if (dotIndex !== -1) { - let ext: string = uri.fsPath.substr(dotIndex + 1); + const ext: string = uri.fsPath.substr(dotIndex + 1); if (this.associations_for_did_change?.has(ext)) { // VS Code has a bug that causes onDidChange events to happen to files that aren't changed, // which causes a large backlog of "files to parse" to accumulate. // We workaround this via only sending the change message if the modified time is within 10 seconds. - let mtime: Date = fs.statSync(uri.fsPath).mtime; - let duration: number = Date.now() - mtime.getTime(); + const mtime: Date = fs.statSync(uri.fsPath).mtime; + const duration: number = Date.now() - mtime.getTime(); if (duration < 10000) { this.languageClient.sendNotification(FileChangedNotification, { uri: uri.toString() }); } @@ -2011,29 +2030,29 @@ export class DefaultClient implements Client { */ public addFileAssociations(fileAssociations: string, is_c: boolean): void { - let settings: OtherSettings = new OtherSettings(); - let assocs: any = settings.filesAssociations; + const settings: OtherSettings = new OtherSettings(); + const assocs: any = settings.filesAssociations; - let filesAndPaths: string[] = fileAssociations.split(";"); + const filesAndPaths: string[] = fileAssociations.split(";"); let foundNewAssociation: boolean = false; for (let i: number = 0; i < filesAndPaths.length; ++i) { - let fileAndPath: string[] = filesAndPaths[i].split("@"); + const fileAndPath: string[] = filesAndPaths[i].split("@"); // Skip empty or malformed if (fileAndPath.length === 2) { - let file: string = fileAndPath[0]; - let filePath: string = fileAndPath[1]; + const file: string = fileAndPath[0]; + const filePath: string = fileAndPath[1]; if ((file in assocs) || (("**/" + file) in assocs)) { continue; // File already has an association. } - let j: number = file.lastIndexOf('.'); + const j: number = file.lastIndexOf('.'); if (j !== -1) { - let ext: string = file.substr(j); + const ext: string = file.substr(j); if ((("*" + ext) in assocs) || (("**/*" + ext) in assocs)) { continue; // Extension already has an association. } } let foundGlobMatch: boolean = false; - for (let assoc in assocs) { + for (const assoc in assocs) { if (minimatch(filePath, assoc)) { foundGlobMatch = true; break; // Assoc matched a glob pattern. @@ -2052,51 +2071,51 @@ export class DefaultClient implements Client { } private updateStatus(notificationBody: ReportStatusNotificationBody): void { - let message: string = notificationBody.status; + const message: string = notificationBody.status; util.setProgress(util.getProgressExecutableSuccess()); - let testHook: TestHook = getTestHook(); + const testHook: TestHook = getTestHook(); if (message.endsWith("Indexing...")) { this.model.isTagParsing.Value = true; - let status: IntelliSenseStatus = { status: Status.TagParsingBegun }; + const status: IntelliSenseStatus = { status: Status.TagParsingBegun }; testHook.updateStatus(status); } else if (message.endsWith("Updating IntelliSense...")) { timeStamp = Date.now(); this.model.isUpdatingIntelliSense.Value = true; - let status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling }; + const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling }; testHook.updateStatus(status); } else if (message.endsWith("IntelliSense Ready")) { - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.loggingLevel === "Debug") { - let out: logger.Logger = logger.getOutputChannelLogger(); - let duration: number = Date.now() - timeStamp; + const out: logger.Logger = logger.getOutputChannelLogger(); + const duration: number = Date.now() - timeStamp; out.appendLine(localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", duration / 1000)); } this.model.isUpdatingIntelliSense.Value = false; - let status: IntelliSenseStatus = { status: Status.IntelliSenseReady }; + const status: IntelliSenseStatus = { status: Status.IntelliSenseReady }; testHook.updateStatus(status); } else if (message.endsWith("Ready")) { // Tag Parser Ready this.model.isTagParsing.Value = false; - let status: IntelliSenseStatus = { status: Status.TagParsingDone }; + const status: IntelliSenseStatus = { status: Status.TagParsingDone }; testHook.updateStatus(status); util.setProgress(util.getProgressParseRootSuccess()); } else if (message.includes("Squiggles Finished - File name:")) { - let index: number = message.lastIndexOf(":"); - let name: string = message.substring(index + 2); - let status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name }; + const index: number = message.lastIndexOf(":"); + const name: string = message.substring(index + 2); + const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name }; testHook.updateStatus(status); } else if (message.endsWith("No Squiggles")) { util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles()); } else if (message.endsWith("Unresolved Headers")) { if (notificationBody.workspaceFolderUri) { - let client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(notificationBody.workspaceFolderUri)); + const client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(notificationBody.workspaceFolderUri)); if (!client.configuration.CurrentConfiguration?.configurationProvider) { - let showIntelliSenseFallbackMessage: PersistentState = new PersistentState("CPP.showIntelliSenseFallbackMessage", true); + const showIntelliSenseFallbackMessage: PersistentState = new PersistentState("CPP.showIntelliSenseFallbackMessage", true); if (showIntelliSenseFallbackMessage.Value) { ui.showConfigureIncludePathMessage(() => { - let configJSON: string = localize("configure.json.button", "Configure (JSON)"); - let configUI: string = localize("configure.ui.button", "Configure (UI)"); - let dontShowAgain: string = localize("dont.show.again", "Don't Show Again"); - let fallbackMsg: string = client.configuration.VcpkgInstalled ? + const configJSON: string = localize("configure.json.button", "Configure (JSON)"); + const configUI: string = localize("configure.ui.button", "Configure (UI)"); + const dontShowAgain: string = localize("dont.show.again", "Don't Show Again"); + const fallbackMsg: string = client.configuration.VcpkgInstalled ? localize("update.your.intellisense.settings", "Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers.") : localize("configure.your.intellisense.settings", "Configure your IntelliSense settings to help find missing headers."); return vscode.window.showInformationMessage(fallbackMsg, configJSON, configUI, dontShowAgain).then((value) => { @@ -2137,26 +2156,75 @@ export class DefaultClient implements Client { this.model.tagParserStatus.Value = util.getLocalizedString(notificationBody); } + private updateInactiveRegions(params: InactiveRegionParams): void { + const settings: CppSettings = new CppSettings(this.RootUri); + const opacity: number | undefined = settings.inactiveRegionOpacity; + if (opacity !== null && opacity !== undefined) { + let backgroundColor: string | undefined = settings.inactiveRegionBackgroundColor; + if (backgroundColor === "") { + backgroundColor = undefined; + } + let color: string | undefined = settings.inactiveRegionForegroundColor; + if (color === "") { + color = undefined; + } + const decoration: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType({ + opacity: opacity.toString(), + backgroundColor: backgroundColor, + color: color, + rangeBehavior: vscode.DecorationRangeBehavior.OpenOpen + }); + // We must convert to vscode.Ranges in order to make use of the API's + const ranges: vscode.Range[] = []; + params.regions.forEach(element => { + const newRange: vscode.Range = new vscode.Range(element.startLine, 0, element.endLine, 0); + ranges.push(newRange); + }); + // Find entry for cached file and act accordingly + const valuePair: DecorationRangesPair | undefined = this.inactiveRegionsDecorations.get(params.uri); + if (valuePair) { + // Disposing of and resetting the decoration will undo previously applied text decorations + valuePair.decoration.dispose(); + valuePair.decoration = decoration; + // As vscode.TextEditor.setDecorations only applies to visible editors, we must cache the range for when another editor becomes visible + valuePair.ranges = ranges; + } else { // The entry does not exist. Make a new one + const toInsert: DecorationRangesPair = { + decoration: decoration, + ranges: ranges + }; + this.inactiveRegionsDecorations.set(params.uri, toInsert); + } + if (settings.dimInactiveRegions && params.fileVersion === this.openFileVersions.get(params.uri)) { + // Apply the decorations to all *visible* text editors + const editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === params.uri); + for (const e of editors) { + e.setDecorations(decoration, ranges); + } + } + } + } + private promptCompileCommands(params: CompileCommandsPaths): void { if (!params.workspaceFolderUri) { return; } - let client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(params.workspaceFolderUri)); + const client: DefaultClient = clientCollection.getClientFor(vscode.Uri.file(params.workspaceFolderUri)); if (client.configuration.CurrentConfiguration?.compileCommands || client.configuration.CurrentConfiguration?.configurationProvider) { return; } - let rootFolder: vscode.WorkspaceFolder | undefined = client.RootFolder; + const rootFolder: vscode.WorkspaceFolder | undefined = client.RootFolder; if (!rootFolder) { return; } - let ask: PersistentFolderState = new PersistentFolderState("CPP.showCompileCommandsSelection", true, rootFolder); + const ask: PersistentFolderState = new PersistentFolderState("CPP.showCompileCommandsSelection", true, rootFolder); if (!ask.Value) { return; } - let aCompileCommandsFile: string = localize("a.compile.commands.file", "a compile_commands.json file"); - let compileCommandStr: string = params.paths.length > 1 ? aCompileCommandsFile : params.paths[0]; + const aCompileCommandsFile: string = localize("a.compile.commands.file", "a compile_commands.json file"); + const compileCommandStr: string = params.paths.length > 1 ? aCompileCommandsFile : params.paths[0]; const message: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? localize("auto-configure.intellisense.folder", "Would you like to use {0} to auto-configure IntelliSense for the '{1}' folder?", compileCommandStr, client.Name) : localize("auto-configure.intellisense.this.folder", "Would you like to use {0} to auto-configure IntelliSense for this folder?", compileCommandStr); @@ -2169,7 +2237,7 @@ export class DefaultClient implements Client { switch (value) { case yes: if (params.paths.length > 1) { - let index: number = await ui.showCompileCommands(params.paths); + const index: number = await ui.showCompileCommands(params.paths); if (index < 0) { return false; } @@ -2194,7 +2262,7 @@ export class DefaultClient implements Client { * requests to the language server */ public requestSwitchHeaderSource(rootPath: string, fileName: string): Thenable { - let params: SwitchHeaderSourceParams = { + const params: SwitchHeaderSourceParams = { switchHeaderSourceFileName: fileName, workspaceFolderUri: rootPath }; @@ -2246,7 +2314,7 @@ export class DefaultClient implements Client { private doneInitialCustomBrowseConfigurationCheck: Boolean = false; private onConfigurationsChanged(configurations: configs.Configuration[]): void { - let params: CppPropertiesParams = { + const params: CppPropertiesParams = { configurations: configurations, currentConfiguration: this.configuration.CurrentConfigurationIndex, workspaceFolderUri: this.RootPath, @@ -2254,18 +2322,18 @@ export class DefaultClient implements Client { }; // Separate compiler path and args before sending to language client params.configurations.forEach((c: configs.Configuration) => { - let compilerPathAndArgs: util.CompilerPathAndArgs = + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(c.compilerPath, c.compilerArgs); c.compilerPath = compilerPathAndArgs.compilerPath; c.compilerArgs = compilerPathAndArgs.additionalArgs; }); let sendLastCustomBrowseConfiguration: boolean = false; - let rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; + const rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; if (!rootFolder) { this.languageClient.sendNotification(ChangeCppPropertiesNotification, params); } else { - let lastCustomBrowseConfigurationProviderId: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfigurationProviderId", undefined, rootFolder); - let lastCustomBrowseConfiguration: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfiguration", undefined, rootFolder); + const lastCustomBrowseConfigurationProviderId: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfigurationProviderId", undefined, rootFolder); + const lastCustomBrowseConfiguration: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfiguration", undefined, rootFolder); if (!this.doneInitialCustomBrowseConfigurationCheck) { // Send the last custom browse configuration we received from this provider. // This ensures we don't start tag parsing without it, and undo'ing work we have to re-do when the (likely same) browse config arrives @@ -2283,9 +2351,9 @@ export class DefaultClient implements Client { this.sendCustomBrowseConfiguration(lastCustomBrowseConfiguration.Value, lastCustomBrowseConfigurationProviderId.Value); } } - let configName: string | undefined = configurations[params.currentConfiguration].name ?? ""; + const configName: string | undefined = configurations[params.currentConfiguration].name ?? ""; this.model.activeConfigName.setValueIfActive(configName); - let newProvider: string | undefined = this.configuration.CurrentConfigurationProvider; + const newProvider: string | undefined = this.configuration.CurrentConfigurationProvider; if (!isSameProviderExtensionId(newProvider, this.configurationProvider)) { if (this.configurationProvider) { this.clearCustomBrowseConfiguration(); @@ -2297,7 +2365,7 @@ export class DefaultClient implements Client { } private onSelectedConfigurationChanged(index: number): void { - let params: FolderSelectedSettingParams = { + const params: FolderSelectedSettingParams = { currentConfiguration: index, workspaceFolderUri: this.RootPath }; @@ -2313,7 +2381,7 @@ export class DefaultClient implements Client { } private onCompileCommandsChanged(path: string): void { - let params: FileChangedParams = { + const params: FileChangedParams = { uri: vscode.Uri.file(path).toString(), workspaceFolderUri: this.RootPath }; @@ -2339,14 +2407,15 @@ export class DefaultClient implements Client { return; } - let settings: CppSettings = new CppSettings(); - let out: logger.Logger = logger.getOutputChannelLogger(); + const settings: CppSettings = new CppSettings(); + const out: logger.Logger = logger.getOutputChannelLogger(); if (settings.loggingLevel === "Debug") { out.appendLine(localize("configurations.received", "Custom configurations received:")); } - let sanitized: SourceFileConfigurationItemAdapter[] = []; + const sanitized: SourceFileConfigurationItemAdapter[] = []; configs.forEach(item => { if (this.isSourceFileConfigurationItem(item)) { + this.configurationLogging.set(item.uri.toString(), JSON.stringify(item.configuration, null, 4)); if (settings.loggingLevel === "Debug") { out.appendLine(` uri: ${item.uri.toString()}`); out.appendLine(` config: ${JSON.stringify(item.configuration, null, 2)}`); @@ -2355,9 +2424,9 @@ export class DefaultClient implements Client { console.warn("custom include paths should not use recursive includes ('**')"); } // Separate compiler path and args before sending to language client - let itemConfig: util.Mutable = {...item.configuration}; + const itemConfig: util.Mutable = {...item.configuration}; if (util.isString(itemConfig.compilerPath)) { - let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs( + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs( itemConfig.compilerPath, util.isArrayOfString(itemConfig.compilerArgs) ? itemConfig.compilerArgs : undefined); itemConfig.compilerPath = compilerPathAndArgs.compilerPath; @@ -2376,7 +2445,7 @@ export class DefaultClient implements Client { return; } - let params: CustomConfigurationParams = { + const params: CustomConfigurationParams = { configurationItems: sanitized, workspaceFolderUri: this.RootPath }; @@ -2384,15 +2453,20 @@ export class DefaultClient implements Client { this.languageClient.sendNotification(CustomConfigurationNotification, params); } + private browseConfigurationLogging: string = ""; + private configurationLogging: Map = new Map(); + private sendCustomBrowseConfiguration(config: any, providerId?: string, timeoutOccured?: boolean): void { - let rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; + const rootFolder: vscode.WorkspaceFolder | undefined = this.RootFolder; if (!rootFolder) { return; } - let lastCustomBrowseConfiguration: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfiguration", undefined, rootFolder); - let lastCustomBrowseConfigurationProviderId: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfigurationProviderId", undefined, rootFolder); + const lastCustomBrowseConfiguration: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfiguration", undefined, rootFolder); + const lastCustomBrowseConfigurationProviderId: PersistentFolderState = new PersistentFolderState("CPP.lastCustomBrowseConfigurationProviderId", undefined, rootFolder); let sanitized: util.Mutable; + this.browseConfigurationLogging = ""; + // This while (true) is here just so we can break out early if the config is set on error while (true) { // config is marked as 'any' because it is untrusted data coming from a 3rd-party. We need to sanitize it before sending it to the language server. @@ -2400,7 +2474,7 @@ export class DefaultClient implements Client { if (!timeoutOccured) { console.log("Received an invalid browse configuration from configuration provider."); } - let configValue: WorkspaceBrowseConfiguration | undefined = lastCustomBrowseConfiguration.Value; + const configValue: WorkspaceBrowseConfiguration | undefined = lastCustomBrowseConfiguration.Value; if (configValue) { sanitized = configValue; console.log("Falling back to last received browse configuration: ", JSON.stringify(sanitized, null, 2)); @@ -2417,7 +2491,7 @@ export class DefaultClient implements Client { !util.isOptionalString(sanitized.standard) || !util.isOptionalString(sanitized.windowsSdkVersion)) { console.log("Received an invalid browse configuration from configuration provider."); - let configValue: WorkspaceBrowseConfiguration | undefined = lastCustomBrowseConfiguration.Value; + const configValue: WorkspaceBrowseConfiguration | undefined = lastCustomBrowseConfiguration.Value; if (configValue) { sanitized = configValue; console.log("Falling back to last received browse configuration: ", JSON.stringify(sanitized, null, 2)); @@ -2426,15 +2500,15 @@ export class DefaultClient implements Client { return; } - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.loggingLevel === "Debug") { - let out: logger.Logger = logger.getOutputChannelLogger(); + const out: logger.Logger = logger.getOutputChannelLogger(); out.appendLine(localize("browse.configuration.received", "Custom browse configuration received: {0}", JSON.stringify(sanitized, null, 2))); } // Separate compiler path and args before sending to language client if (util.isString(sanitized.compilerPath)) { - let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs( + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs( sanitized.compilerPath, util.isArrayOfString(sanitized.compilerArgs) ? sanitized.compilerArgs : undefined); sanitized.compilerPath = compilerPathAndArgs.compilerPath; @@ -2450,7 +2524,9 @@ export class DefaultClient implements Client { break; } - let params: CustomBrowseConfigurationParams = { + this.browseConfigurationLogging = localize("browse.configuration", "Custom browse configuration: {0}", `\n${JSON.stringify(sanitized, null, 4)}\n`); + + const params: CustomBrowseConfigurationParams = { browseConfiguration: sanitized, workspaceFolderUri: this.RootPath }; @@ -2459,14 +2535,16 @@ export class DefaultClient implements Client { } private clearCustomConfigurations(): void { - let params: WorkspaceFolderParams = { + this.configurationLogging.clear(); + const params: WorkspaceFolderParams = { workspaceFolderUri: this.RootPath }; this.notifyWhenReady(() => this.languageClient.sendNotification(ClearCustomConfigurationsNotification, params)); } private clearCustomBrowseConfiguration(): void { - let params: WorkspaceFolderParams = { + this.browseConfigurationLogging = ""; + const params: WorkspaceFolderParams = { workspaceFolderUri: this.RootPath }; this.notifyWhenReady(() => this.languageClient.sendNotification(ClearCustomBrowseConfigurationNotification, params)); @@ -2477,7 +2555,7 @@ export class DefaultClient implements Client { */ public handleConfigurationSelectCommand(): void { this.notifyWhenReady(() => { - let configNames: string[] | undefined = this.configuration.ConfigurationNames; + const configNames: string[] | undefined = this.configuration.ConfigurationNames; if (configNames) { ui.showConfigurations(configNames) .then((index: number) => { @@ -2501,7 +2579,7 @@ export class DefaultClient implements Client { this.configuration.updateCustomConfigurationProvider(extensionId) .then(() => { if (extensionId) { - let provider: CustomConfigurationProvider1 | undefined = getCustomConfigProviders().get(extensionId); + const provider: CustomConfigurationProvider1 | undefined = getCustomConfigProviders().get(extensionId); this.updateCustomBrowseConfiguration(provider); this.updateCustomConfigurations(provider); telemetry.logLanguageServerEvent("customConfigurationProvider", { "providerId": extensionId }); @@ -2553,7 +2631,7 @@ export class DefaultClient implements Client { } public dispose(): Thenable { - let promise: Thenable = (this.languageClient && clientCollection.Count === 0) ? this.languageClient.stop() : Promise.resolve(); + const promise: Thenable = (this.languageClient && clientCollection.Count === 0) ? this.languageClient.stop() : Promise.resolve(); return promise.then(() => { this.disposables.forEach((d) => d.dispose()); this.disposables = []; @@ -2561,13 +2639,17 @@ export class DefaultClient implements Client { this.codeFoldingProviderDisposable.dispose(); this.codeFoldingProviderDisposable = undefined; } + if (this.semanticTokensProviderDisposable) { + this.semanticTokensProviderDisposable.dispose(); + this.semanticTokensProviderDisposable = undefined; + } this.model.dispose(); }); } public handleReferencesIcon(): void { this.notifyWhenReady(() => { - let cancelling: boolean = referencesPendingCancellations.length > 0; + const cancelling: boolean = referencesPendingCancellations.length > 0; if (!cancelling) { workspaceReferences.UpdateProgressUICounter(this.model.referencesCommandMode.Value); if (this.ReferencesCommandMode === refs.ReferencesCommandMode.Find) { @@ -2594,7 +2676,7 @@ export class DefaultClient implements Client { referencesParams = undefined; renamePending = false; if (referencesRequestPending || workspaceReferences.symbolSearchInProgress) { - let cancelling: boolean = referencesPendingCancellations.length > 0; + const cancelling: boolean = referencesPendingCancellations.length > 0; referencesPendingCancellations.push({ reject: () => {}, callback: () => {} }); if (!cancelling) { workspaceReferences.referencesCanceled = true; @@ -2616,7 +2698,7 @@ export class DefaultClient implements Client { } public abortRequest(id: number): void { - let params: AbortRequestParams = { + const params: AbortRequestParams = { id: id }; languageClient.sendNotification(AbortRequestNotification, params); @@ -2625,7 +2707,7 @@ export class DefaultClient implements Client { function getLanguageServerFileName(): string { let extensionProcessName: string = 'cpptools'; - let plat: NodeJS.Platform = process.platform; + const plat: NodeJS.Platform = process.platform; if (plat === 'win32') { extensionProcessName += '.exe'; } else if (plat !== 'linux' && plat !== 'darwin') { @@ -2653,7 +2735,6 @@ class NullClient implements Client { onDidCloseTextDocument(document: vscode.TextDocument): void {} onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {} onDidChangeTextDocument(textDocumentChangeEvent: vscode.TextDocumentChangeEvent): void {} - onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void {} onRegisterCustomConfigurationProvider(provider: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } updateCustomConfigurations(requestingProvider?: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } updateCustomBrowseConfiguration(requestingProvider?: CustomConfigurationProvider1): Thenable { return Promise.resolve(); } @@ -2695,4 +2776,5 @@ class NullClient implements Client { return Promise.resolve(); } addFileAssociations(fileAssociations: string, is_c: boolean): void {} + sendDidChangeSettings(settings: any): void {} } diff --git a/Extension/src/LanguageServer/clientCollection.ts b/Extension/src/LanguageServer/clientCollection.ts index 4bf633ee97..11a21305f9 100644 --- a/Extension/src/LanguageServer/clientCollection.ts +++ b/Extension/src/LanguageServer/clientCollection.ts @@ -25,7 +25,7 @@ export class ClientCollection { public get ActiveClient(): cpptools.Client { return this.activeClient; } public get Names(): ClientKey[] { - let result: ClientKey[] = []; + const result: ClientKey[] = []; this.languageClients.forEach((client, key) => { result.push({ name: client.Name, key: key }); }); @@ -38,7 +38,7 @@ export class ClientCollection { if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { let isFirstWorkspaceFolder: boolean = true; vscode.workspace.workspaceFolders.forEach(folder => { - let newClient: cpptools.Client = cpptools.createClient(this, folder); + const newClient: cpptools.Client = cpptools.createClient(this, folder); this.languageClients.set(util.asFolder(folder.uri), newClient); if (isFirstWorkspaceFolder) { isFirstWorkspaceFolder = false; @@ -47,7 +47,7 @@ export class ClientCollection { } }); key = util.asFolder(vscode.workspace.workspaceFolders[0].uri); - let client: cpptools.Client | undefined = this.languageClients.get(key); + const client: cpptools.Client | undefined = this.languageClients.get(key); if (!client) { throw new Error("Failed to construct default client"); } @@ -64,7 +64,7 @@ export class ClientCollection { public activeDocumentChanged(document: vscode.TextDocument): void { this.activeDocument = document; - let activeClient: cpptools.Client = this.getClientFor(document.uri); + const activeClient: cpptools.Client = this.getClientFor(document.uri); // Notify the active client that the document has changed. activeClient.activeDocumentChanged(document); @@ -81,7 +81,7 @@ export class ClientCollection { * get a handle to a language client. returns undefined if the client was not found. */ public get(key: string): cpptools.Client | undefined { - let client: cpptools.Client | undefined = this.languageClients.get(key); + const client: cpptools.Client | undefined = this.languageClients.get(key); console.assert(client, "key not found"); return client; } @@ -100,7 +100,7 @@ export class ClientCollection { */ public replace(client: cpptools.Client, transferFileOwnership: boolean): cpptools.Client | undefined { let key: string | undefined; - for (let pair of this.languageClients) { + for (const pair of this.languageClients) { if (pair[1] === client) { key = pair[0]; break; @@ -133,14 +133,14 @@ export class ClientCollection { } private onDidChangeWorkspaceFolders(e?: vscode.WorkspaceFoldersChangeEvent): void { - let folderCount: number = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0; + const folderCount: number = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0; if (folderCount > 1) { telemetry.logLanguageServerEvent("workspaceFoldersChange", { "count": folderCount.toString() }); } if (e !== undefined) { e.removed.forEach(folder => { - let path: string = util.asFolder(folder.uri); + const path: string = util.asFolder(folder.uri); const client: cpptools.Client | undefined = this.languageClients.get(path); if (client) { this.languageClients.delete(path); // Do this first so that we don't iterate on it during the ownership transfer process. @@ -162,41 +162,41 @@ export class ClientCollection { } }); e.added.forEach(folder => { - let path: string = util.asFolder(folder.uri); - let client: cpptools.Client | undefined = this.languageClients.get(path); + const path: string = util.asFolder(folder.uri); + const client: cpptools.Client | undefined = this.languageClients.get(path); if (!client) { - let newClient: cpptools.Client = cpptools.createClient(this, folder); + const newClient: cpptools.Client = cpptools.createClient(this, folder); this.languageClients.set(path, newClient); newClient.deactivate(); // e.g. prevent the current config from switching. - let defaultClient: cpptools.DefaultClient = newClient; - defaultClient.sendDidChangeSettings(); + const defaultClient: cpptools.DefaultClient = newClient; + defaultClient.sendAllSettings(); } }); } } private transferOwnership(document: vscode.TextDocument, oldOwner: cpptools.Client): void { - let newOwner: cpptools.Client = this.getClientFor(document.uri); + const newOwner: cpptools.Client = this.getClientFor(document.uri); if (newOwner !== oldOwner) { newOwner.takeOwnership(document); } } public getClientFor(uri: vscode.Uri): cpptools.Client { - let folder: vscode.WorkspaceFolder | undefined = uri ? vscode.workspace.getWorkspaceFolder(uri) : undefined; + const folder: vscode.WorkspaceFolder | undefined = uri ? vscode.workspace.getWorkspaceFolder(uri) : undefined; if (!folder) { return this.defaultClient; } else { - let key: string = util.asFolder(folder.uri); - let client: cpptools.Client | undefined = this.languageClients.get(key); + const key: string = util.asFolder(folder.uri); + const client: cpptools.Client | undefined = this.languageClients.get(key); if (client) { return client; } - let newClient: cpptools.Client = cpptools.createClient(this, folder); + const newClient: cpptools.Client = cpptools.createClient(this, folder); this.languageClients.set(key, newClient); getCustomConfigProviders().forEach(provider => newClient.onRegisterCustomConfigurationProvider(provider)); - let defaultClient: cpptools.DefaultClient = newClient; - defaultClient.sendDidChangeSettings(); + const defaultClient: cpptools.DefaultClient = newClient; + defaultClient.sendAllSettings(); return newClient; } } @@ -206,7 +206,7 @@ export class ClientCollection { } public dispose(): Thenable { - let promises: Thenable[] = []; + const promises: Thenable[] = []; this.disposables.forEach((d: vscode.Disposable) => d.dispose()); // this.defaultClient is already in this.languageClients, so do not call dispose() on it. diff --git a/Extension/src/LanguageServer/colorization.ts b/Extension/src/LanguageServer/colorization.ts deleted file mode 100644 index 2c5367825a..0000000000 --- a/Extension/src/LanguageServer/colorization.ts +++ /dev/null @@ -1,671 +0,0 @@ -/* -------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All Rights Reserved. - * See 'LICENSE' in the project root for license information. - * ------------------------------------------------------------------------------------------ */ -'use strict'; - -import * as path from 'path'; -import * as vscode from 'vscode'; -import * as util from '../common'; -import { CppSettings, OtherSettings, TextMateRule, TextMateRuleSettings } from './settings'; -import * as jsonc from 'jsonc-parser'; -import * as plist from 'plist'; - -export enum TokenKind { - // These need to match the token_kind enum in the server - - // Semantic tokens - Macro, - Enumerator, - GlobalVariable, - LocalVariable, - Parameter, - Type, - RefType, - ValueType, - Function, - MemberFunction, - MemberField, - StaticMemberFunction, - StaticMemberField, - Property, - Event, - ClassTemplate, - GenericType, - FunctionTemplate, - Namespace, - Label, - UdlRaw, - UdlNumber, - UdlString, - OperatorFunction, - MemberOperator, - NewDelete, - - Count -} - -interface VersionedEdits { - editVersion: number; - changes: readonly vscode.TextDocumentContentChangeEvent[]; -} - -class ThemeStyle { - foreground?: string; - background?: string; - fontStyle?: string; -} - -export class ColorizationSettings { - private uri: vscode.Uri | undefined; - private pendingTask?: util.BlockingTask; - private editorBackground?: string; - - public themeStyleCMap: ThemeStyle[] = []; - public themeStyleCppMap: ThemeStyle[] = []; - - private static readonly scopeToTokenColorNameMap = new Map([ - ["comment", "comments"], - ["string", "strings"], - ["keyword.operator", "keywords"], - ["keyword.control", "keywords"], - ["constant.numeric", "numbers"], - ["entity.name.type", "types"], - ["entity.name.class", "types"], - ["entity.name.function", "functions"], - ["variable", "variables"] - ]); - - constructor(uri: vscode.Uri | undefined) { - this.uri = uri; - } - - // Given a TextMate rule 'settings' node, update a ThemeStyle to include any color or style information - private updateStyleFromTextMateRuleSettings(baseStyle: ThemeStyle, textMateRuleSettings: TextMateRuleSettings): void { - if (textMateRuleSettings.foreground) { - baseStyle.foreground = textMateRuleSettings.foreground; - } - if (!this.editorBackground || textMateRuleSettings.background && textMateRuleSettings.background.toUpperCase() !== this.editorBackground.toUpperCase()) { - baseStyle.background = textMateRuleSettings.background; - } - // Any (even empty) string for fontStyle removes inherited value - if (textMateRuleSettings.fontStyle) { - baseStyle.fontStyle = textMateRuleSettings.fontStyle; - } else if (textMateRuleSettings.fontStyle === "") { - baseStyle.fontStyle = undefined; - } - } - - // If the scope can be found in a set of TextMate rules, apply it to both C and Cpp ThemeStyle's - private findThemeStyleForScope(baseCStyle: ThemeStyle | undefined, baseCppStyle: ThemeStyle | undefined, scope: string, textMateRules: TextMateRule[] | undefined): void { - if (textMateRules) { - let match: TextMateRule | undefined = textMateRules.find(e => e.settings && (e.scope === scope || ((e.scope instanceof Array) && e.scope.indexOf(scope) > -1))); - if (match) { - if (baseCStyle) { - this.updateStyleFromTextMateRuleSettings(baseCStyle, match.settings); - } - if (baseCppStyle) { - this.updateStyleFromTextMateRuleSettings(baseCppStyle, match.settings); - } - } - - match = textMateRules.find(e => e.settings && (e.scope === "source " + scope || ((e.scope instanceof Array) && e.scope.indexOf("source " + scope) > -1))); - if (match) { - if (baseCStyle) { - this.updateStyleFromTextMateRuleSettings(baseCStyle, match.settings); - } - if (baseCppStyle) { - this.updateStyleFromTextMateRuleSettings(baseCppStyle, match.settings); - } - } - - if (baseCStyle) { - match = textMateRules.find(e => e.settings && (e.scope === "source.c " + scope || ((e.scope instanceof Array) && e.scope.indexOf("source.c " + scope) > -1))); - if (match) { - this.updateStyleFromTextMateRuleSettings(baseCStyle, match.settings); - } - } - - if (baseCppStyle) { - match = textMateRules.find(e => e.settings && (e.scope === "source.cpp " + scope || ((e.scope instanceof Array) && e.scope.indexOf("source.cpp " + scope) > -1))); - if (match) { - this.updateStyleFromTextMateRuleSettings(baseCppStyle, match.settings); - } - } - } - } - - // For a specific scope cascase all potential sources of style information to create a final ThemeStyle - private calculateThemeStyleForScope(baseCStyle: ThemeStyle | undefined, baseCppStyle: ThemeStyle | undefined, scope: string, themeName: string, themeTextMateRules: TextMateRule[][]): void { - // Search for settings with this scope in current theme - themeTextMateRules.forEach((rules) => { - this.findThemeStyleForScope(baseCStyle, baseCppStyle, scope, rules); - }); - - let otherSettings: OtherSettings = new OtherSettings(this.uri); - - // Next in priority would be a global user override of token color of the equivilent scope - let colorTokenName: string | undefined = ColorizationSettings.scopeToTokenColorNameMap.get(scope); - if (colorTokenName) { - let settingValue: string | undefined = otherSettings.getCustomColorToken(colorTokenName); - if (settingValue) { - if (baseCStyle) { - baseCStyle.foreground = settingValue; - } - if (baseCppStyle) { - baseCppStyle.foreground = settingValue; - } - } - } - - // Next in priority would be a global user override of this scope in textMateRules - this.findThemeStyleForScope(baseCStyle, baseCppStyle, scope, otherSettings.customTextMateRules); - - // Next in priority would be a theme-specific user override of token color of the equivilent scope - if (colorTokenName) { - let settingValue: string | undefined = otherSettings.getCustomThemeSpecificColorToken(colorTokenName, themeName); - if (settingValue) { - if (baseCStyle) { - baseCStyle.foreground = settingValue; - } - if (baseCppStyle) { - baseCppStyle.foreground = settingValue; - } - } - } - - // Next in priority would be a theme-specific user override of this scope in textMateRules - let textMateRules: TextMateRule[] | undefined = otherSettings.getCustomThemeSpecificTextMateRules(themeName); - this.findThemeStyleForScope(baseCStyle, baseCppStyle, scope, textMateRules); - } - - // For each level of the scope, look of style information - private calculateStyleForToken(tokenKind: TokenKind, scope: string, themeName: string, themeTextMateRules: TextMateRule[][]): void { - // Try scopes, from most general to most specific, apply style in cascading manner - let parts: string[] = scope.split("."); - let accumulatedScope: string = ""; - for (let i: number = 0; i < parts.length; i++) { - accumulatedScope += parts[i]; - this.calculateThemeStyleForScope(this.themeStyleCMap[tokenKind], this.themeStyleCppMap[tokenKind], accumulatedScope, themeName, themeTextMateRules); - this.calculateThemeStyleForScope(this.themeStyleCMap[tokenKind], undefined, accumulatedScope + ".c", themeName, themeTextMateRules); - this.calculateThemeStyleForScope(undefined, this.themeStyleCppMap[tokenKind], accumulatedScope + ".cpp", themeName, themeTextMateRules); - accumulatedScope += "."; - } - } - - public syncWithLoadingSettings(f: () => any): void { - this.pendingTask = new util.BlockingTask(f, this.pendingTask); - } - - public updateStyles(themeName: string, defaultStyle: ThemeStyle, textMateRules: TextMateRule[][]): void { - this.themeStyleCMap = new Array(TokenKind.Count); - this.themeStyleCppMap = new Array(TokenKind.Count); - - // Populate with unique objects, as they will be individual modified in place - for (let i: number = 0; i < TokenKind.Count; i++) { - this.themeStyleCMap[i] = {...defaultStyle}; - this.themeStyleCppMap[i] = {...defaultStyle}; - } - - this.calculateStyleForToken(TokenKind.Macro, "entity.name.function.preprocessor", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Enumerator, "variable.other.enummember", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.GlobalVariable, "variable.other.global", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.LocalVariable, "variable.other.local", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Parameter, "variable.parameter", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Type, "entity.name.type.class", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.RefType, "entity.name.type.class.reference", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.ValueType, "entity.name.type.class.value", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Function, "entity.name.function", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.MemberFunction, "entity.name.function.member", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.MemberField, "variable.other.property", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.StaticMemberFunction, "entity.name.function.member.static", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.StaticMemberField, "variable.other.property.static", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Property, "variable.other.property.cli", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Event, "variable.other.event", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.ClassTemplate, "entity.name.type.class.templated", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.GenericType, "entity.name.type.class.generic", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.FunctionTemplate, "entity.name.function.templated", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Namespace, "entity.name.namespace", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Label, "entity.name.label", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlRaw, "entity.name.operator.custom-literal", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlNumber, "entity.name.operator.custom-literal.number", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.UdlString, "entity.name.operator.custom-literal.string", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.OperatorFunction, "entity.name.function.operator", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.MemberOperator, "entity.name.function.operator.member", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.NewDelete, "keyword.operator.new", themeName, textMateRules); - } - - public async loadTheme(themePath: string, defaultStyle: ThemeStyle): Promise { - let rules: TextMateRule[][] = []; - if (await util.checkFileExists(themePath)) { - let themeContentText: string = await util.readFileText(themePath); - let themeContent: any; - let textMateRules: TextMateRule[] | undefined; - if (themePath.endsWith("tmTheme")) { - themeContent = plist.parse(themeContentText); - if (themeContent) { - textMateRules = themeContent.settings; - } - } else { - themeContent = jsonc.parse(themeContentText); - if (themeContent) { - textMateRules = themeContent.tokenColors; - if (themeContent.include) { - // parse included theme file - let includedThemePath: string = path.join(path.dirname(themePath), themeContent.include); - rules = await this.loadTheme(includedThemePath, defaultStyle); - } - - if (themeContent.colors && themeContent.colors["editor.background"]) { - this.editorBackground = themeContent.colors["editor.background"]; - } - } - } - - if (textMateRules) { - // Convert comma delimited scopes into an array - textMateRules.forEach(e => { - if (e.scope && e.scope.includes(',')) { - e.scope = e.scope.split(',').map((s: string) => s.trim()); - } - }); - - let scopelessSetting: any = textMateRules.find(e => e.settings && !e.scope); - if (scopelessSetting) { - if (scopelessSetting.settings.background) { - this.editorBackground = scopelessSetting.settings.background; - } - this.updateStyleFromTextMateRuleSettings(defaultStyle, scopelessSetting.settings); - } - rules.push(textMateRules); - } - } - - return rules; - } - - public reload(): void { - let f: () => void = async () => { - let otherSettings: OtherSettings = new OtherSettings(this.uri); - let themeName: string | undefined = otherSettings.colorTheme; - if (themeName) { - // Enumerate through all extensions, looking for this theme. (Themes are implemented as extensions - even the default ones) - // Open each package.json to check for a theme path - for (let i: number = 0; i < vscode.extensions.all.length; i++) { - let extensionPath: string = vscode.extensions.all[i].extensionPath; - let extensionPackageJsonPath: string = path.join(extensionPath, "package.json"); - if (!await util.checkFileExists(extensionPackageJsonPath)) { - continue; - } - let packageJsonText: string = await util.readFileText(extensionPackageJsonPath); - let packageJson: any = jsonc.parse(packageJsonText); - if (packageJson.contributes && packageJson.contributes.themes) { - let foundTheme: any = packageJson.contributes.themes.find((e: any) => e.id === themeName || e.label === themeName); - if (foundTheme) { - let themeRelativePath: string = foundTheme.path; - let themeFullPath: string = path.join(extensionPath, themeRelativePath); - let defaultStyle: ThemeStyle = new ThemeStyle(); - let rulesSet: TextMateRule[][] = await this.loadTheme(themeFullPath, defaultStyle); - this.updateStyles(themeName, defaultStyle, rulesSet); - return; - } - } - } - } - }; - this.syncWithLoadingSettings(f); - } - - public static createDecorationFromThemeStyle(themeStyle: ThemeStyle): vscode.TextEditorDecorationType | undefined { - if (themeStyle && (themeStyle.foreground || themeStyle.background || themeStyle.fontStyle)) { - let options: vscode.DecorationRenderOptions = {}; - options.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen; - if (themeStyle.foreground) { - options.color = themeStyle.foreground; - } - if (themeStyle.background) { - options.backgroundColor = themeStyle.background; - } - if (themeStyle.fontStyle) { - let parts: string[] = themeStyle.fontStyle.split(" "); - parts.forEach((part) => { - switch (part) { - case "italic": - options.fontStyle = "italic"; - break; - case "bold": - options.fontWeight = "bold"; - break; - case "underline": - options.textDecoration = "underline"; - break; - default: - break; - } - }); - } - return vscode.window.createTextEditorDecorationType(options); - } - - return undefined; - } -} - -export class ColorizationState { - private uri: vscode.Uri; - private colorizationSettings: ColorizationSettings; - private decorations: (vscode.TextEditorDecorationType | undefined)[] = new Array(TokenKind.Count); - private semanticRanges: vscode.Range[][] = new Array(TokenKind.Count); - private inactiveDecoration: vscode.TextEditorDecorationType | undefined; - private inactiveRanges: vscode.Range[] = []; - private versionedEdits: VersionedEdits[] = []; - private currentSemanticVersion: number = 0; - private lastReceivedSemanticVersion: number = 0; - - public constructor(uri: vscode.Uri, colorizationSettings: ColorizationSettings) { - this.uri = uri; - this.colorizationSettings = colorizationSettings; - } - - private createColorizationDecorations(isCpp: boolean): void { - let settings: CppSettings = new CppSettings(this.uri); - if (settings.enhancedColorization) { - // Create new decorators - // The first decorator created takes precedence, so these need to be created in reverse order - for (let i: number = TokenKind.Count; i > 0;) { - i--; - let themeStyleMap: any; - if (isCpp) { - themeStyleMap = this.colorizationSettings.themeStyleCppMap; - } else { - themeStyleMap = this.colorizationSettings.themeStyleCMap; - } - this.decorations[i] = ColorizationSettings.createDecorationFromThemeStyle(themeStyleMap[i]); - } - } - if (settings.dimInactiveRegions) { - let opacity: number | undefined = settings.inactiveRegionOpacity; - if (opacity !== null && opacity !== undefined) { - let backgroundColor: string | undefined = settings.inactiveRegionBackgroundColor; - if (backgroundColor === "") { - backgroundColor = undefined; - } - let color: string | undefined = settings.inactiveRegionForegroundColor; - if (color === "") { - color = undefined; - } - this.inactiveDecoration = vscode.window.createTextEditorDecorationType({ - opacity: opacity.toString(), - backgroundColor: backgroundColor, - color: color, - rangeBehavior: vscode.DecorationRangeBehavior.OpenOpen - }); - } - } - } - - private disposeColorizationDecorations(): void { - // Dispose of all old decorations - if (this.inactiveDecoration) { - this.inactiveDecoration.dispose(); - this.inactiveDecoration = undefined; - } - for (let i: number = 0; i < TokenKind.Count; i++) { - let decoration: vscode.TextEditorDecorationType | undefined = this.decorations[i]; - if (decoration) { - decoration.dispose(); - this.decorations[i] = undefined; - } - } - } - - public dispose(): void { - this.disposeColorizationDecorations(); - } - - private refreshInner(e: vscode.TextEditor): void { - let settings: CppSettings = new CppSettings(this.uri); - if (settings.enhancedColorization) { - for (let i: number = 0; i < TokenKind.Count; i++) { - let decoration: vscode.TextEditorDecorationType | undefined = this.decorations[i]; - if (decoration) { - let ranges: vscode.Range[] = this.semanticRanges[i]; - if (ranges && ranges.length > 0) { - e.setDecorations(decoration, ranges); - } - } - } - } - - // Normally, decorators are honored in the order in which they were created, not the - // order in which they were applied. Decorators with opacity appear to be handled - // differently, in that the opacity is applied to overlapping decorators even if - // created afterwards. - if (settings.dimInactiveRegions && this.inactiveDecoration && this.inactiveRanges) { - e.setDecorations(this.inactiveDecoration, this.inactiveRanges); - } - } - - public refresh(e: vscode.TextEditor): void { - this.applyEdits(); - let f: () => void = async () => { - this.refreshInner(e); - }; - this.colorizationSettings.syncWithLoadingSettings(f); - } - - public onSettingsChanged(uri: vscode.Uri): void { - let f: () => void = async () => { - this.applyEdits(); - this.disposeColorizationDecorations(); - let isCpp: boolean = util.isEditorFileCpp(uri.toString()); - this.createColorizationDecorations(isCpp); - let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri === uri); - for (let e of editors) { - this.refreshInner(e); - } - }; - this.colorizationSettings.syncWithLoadingSettings(f); - } - - // Utility function to convert a string and a start Position into a Range - private textToRange(text: string, startPosition: vscode.Position): vscode.Range { - let parts: string[] = text.split("\n"); - let addedLines: number = parts.length - 1; - let newStartLine: number = startPosition.line; - let newStartCharacter: number = startPosition.character; - let newEndLine: number = newStartLine + addedLines; - let newEndCharacter: number = parts[parts.length - 1].length; - if (newStartLine === newEndLine) { - newEndCharacter += newStartCharacter; - } - return new vscode.Range(newStartLine, newStartCharacter, newEndLine, newEndCharacter); - } - - // Utility function to shift a range back after removing content before it - private shiftRangeAfterRemove(range: vscode.Range, removeStartPosition: vscode.Position, removeEndPosition: vscode.Position): vscode.Range { - let lineDelta: number = removeStartPosition.line - removeEndPosition.line; - let startCharacterDelta: number = 0; - let endCharacterDelta: number = 0; - if (range.start.line === removeEndPosition.line) { - startCharacterDelta = removeStartPosition.character - removeEndPosition.character; - if (range.end.line === removeEndPosition.line) { - endCharacterDelta = startCharacterDelta; - } - } - let newStart: vscode.Position = range.start.translate(lineDelta, startCharacterDelta); - let newEnd: vscode.Position = range.end.translate(lineDelta, endCharacterDelta); - return new vscode.Range(newStart, newEnd); - } - - // Utility function to shift a range forward after inserting content before it - private shiftRangeAfterInsert(range: vscode.Range, insertStartPosition: vscode.Position, insertEndPosition: vscode.Position): vscode.Range { - let addedLines: number = insertEndPosition.line - insertStartPosition.line; - let newStartLine: number = range.start.line + addedLines; - let newEndLine: number = range.end.line + addedLines; - let newStartCharacter: number = range.start.character; - let newEndCharacter: number = range.end.character; - // If starts on the same line as replacement ended - if (insertEndPosition.line === newStartLine) { - let endOffsetLength: number = insertEndPosition.character; - // If insertRange starts and ends on the same line, only offset by it's length - if (insertEndPosition.line === insertStartPosition.line) { - endOffsetLength -= insertStartPosition.character; - } - newStartCharacter += endOffsetLength; - if (insertEndPosition.line === newEndLine) { - newEndCharacter += endOffsetLength; - } - } - return new vscode.Range(newStartLine, newStartCharacter, newEndLine, newEndCharacter); - } - - // Utility function to adjust a range to account for an insert and/or replace - private fixRange(range: vscode.Range, removeInsertStartPosition: vscode.Position, removeEndPosition: vscode.Position, insertEndPosition: vscode.Position): vscode.Range | undefined { - // If the replace/insert starts after this range ends, no adjustment is needed. - if (removeInsertStartPosition.isAfterOrEqual(range.end)) { - return range; - } - // Else, replace/insert range starts before this range ends. - - // If replace/insert starts before/where this range starts, we don't need to extend the existing range, but need to shift it - if (removeInsertStartPosition.isBeforeOrEqual(range.start)) { - - // If replace consumes the entire range, remove it - if (removeEndPosition.isAfterOrEqual(range.end)) { - return undefined; - } - - // If replace ends within this range, we need to trim it before we shift it - let newRange: vscode.Range; - if (removeEndPosition.isAfterOrEqual(range.start)) { - newRange = new vscode.Range(removeEndPosition, range.end); - } else { - newRange = range; - } - // Else, if replace ends before this range starts, we just need to shift it. - - newRange = this.shiftRangeAfterRemove(newRange, removeInsertStartPosition, removeEndPosition); - return this.shiftRangeAfterInsert(newRange, removeInsertStartPosition, insertEndPosition); - } - // Else, if replace/insert starts within (not before or after) range, extend it. - - // If there replace/insert overlaps past the end of the original range, just extend existing range to the insert end position - if (removeEndPosition.isAfterOrEqual(range.end)) { - return new vscode.Range(range.start.line, range.start.character, insertEndPosition.line, insertEndPosition.character); - } - // Else, range has some left over at the end, which needs to be shifted after insertEndPosition. - - // If the trailing segment is on the last line replace, we just need to extend by the remaining number of characters - if (removeEndPosition.line === range.end.line) { - return new vscode.Range(range.start.line, range.start.character, insertEndPosition.line, insertEndPosition.character + (range.end.character - removeEndPosition.character)); - } - // Else, the trailing segment ends on another line, so the character position should remain the same. Just adjust based on added/removed lined. - let removedLines: number = removeEndPosition.line - removeInsertStartPosition.line; - let addedLines: number = insertEndPosition.line - removeInsertStartPosition.line; - let deltaLines: number = addedLines - removedLines; - return new vscode.Range(range.start.line, range.start.character, range.end.line + deltaLines, range.end.character); - } - - private fixRanges(originalRanges: vscode.Range[], changes: readonly vscode.TextDocumentContentChangeEvent[]): vscode.Range[] { - // outer loop needs to be the versioned edits, then changes within that edit, then ranges - let ranges: vscode.Range[] = originalRanges; - if (ranges && ranges.length > 0) { - changes.forEach((change) => { - let newRanges: vscode.Range[] = []; - let insertRange: vscode.Range = this.textToRange(change.text, change.range.start); - for (let i: number = 0; i < ranges.length; i++) { - let newRange: vscode.Range | undefined = this.fixRange(ranges[i], change.range.start, change.range.end, insertRange.end); - if (newRange) { - newRanges.push(newRange); - } - } - ranges = newRanges; - }); - } - return ranges; - } - - // Add edits to be applied when/if cached tokens need to be reapplied. - public addEdits(changes: readonly vscode.TextDocumentContentChangeEvent[], editVersion: number): void { - let edits: VersionedEdits = { - editVersion: editVersion, - changes: changes - }; - this.versionedEdits.push(edits); - } - - // Apply any pending edits to the currently cached tokens - private applyEdits(): void { - this.versionedEdits.forEach((edit) => { - if (edit.editVersion > this.currentSemanticVersion) { - for (let i: number = 0; i < TokenKind.Count; i++) { - this.semanticRanges[i] = this.fixRanges(this.semanticRanges[i], edit.changes); - } - this.inactiveRanges = this.fixRanges(this.inactiveRanges, edit.changes); - this.currentSemanticVersion = edit.editVersion; - } - }); - } - - // Remove any edits from the list if we will never receive tokens that old. - private purgeOldVersionedEdits(): void { - let minVersion: number = this.lastReceivedSemanticVersion; - let index: number = this.versionedEdits.findIndex((edit) => edit.editVersion > minVersion); - if (index === -1) { - this.versionedEdits = []; - } else if (index > 0) { - this.versionedEdits = this.versionedEdits.slice(index); - } - } - - private updateColorizationRanges(uri: string): void { - let f: () => void = async () => { - this.applyEdits(); - this.purgeOldVersionedEdits(); - - // The only way to un-apply decorators is to dispose them. - // If we dispose old decorators before applying new decorators, we see a flicker on Mac, - // likely due to a race with UI updates. Here we set aside the existing decorators to be - // disposed of after the new decorators have been applied, so there is not a gap - // in which decorators are not applied. - let oldInactiveDecoration: vscode.TextEditorDecorationType | undefined = this.inactiveDecoration; - let oldDecorations: (vscode.TextEditorDecorationType | undefined)[] = this.decorations; - this.inactiveDecoration = undefined; - this.decorations = new Array(TokenKind.Count); - - let isCpp: boolean = util.isEditorFileCpp(uri); - this.createColorizationDecorations(isCpp); - - // Apply the decorations to all *visible* text editors - let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === uri); - for (let e of editors) { - this.refreshInner(e); - } - - // Dispose of the old decorators only after the new ones have been applied. - if (oldInactiveDecoration) { - oldInactiveDecoration.dispose(); - } - if (oldDecorations) { - for (let i: number = 0; i < TokenKind.Count; i++) { - let oldDecoration: vscode.TextEditorDecorationType | undefined = oldDecorations[i]; - if (oldDecoration) { - oldDecoration.dispose(); - } - } - } - }; - this.colorizationSettings.syncWithLoadingSettings(f); - } - - public updateSemantic(uri: string, semanticRanges: vscode.Range[][], inactiveRanges: vscode.Range[], editVersion: number): void { - this.inactiveRanges = inactiveRanges; - for (let i: number = 0; i < TokenKind.Count; i++) { - this.semanticRanges[i] = semanticRanges[i]; - } - this.currentSemanticVersion = editVersion; - this.lastReceivedSemanticVersion = editVersion; - this.updateColorizationRanges(uri); - } -} diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 06f805ea02..a1c927d08b 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -141,7 +141,7 @@ export class CppProperties { constructor(rootUri?: vscode.Uri, workspaceFolder?: vscode.WorkspaceFolder) { this.rootUri = rootUri; - let rootPath: string = rootUri ? rootUri.fsPath : ""; + const rootPath: string = rootUri ? rootUri.fsPath : ""; if (workspaceFolder) { this.currentConfigurationIndex = new PersistentFolderState("CppProperties.currentConfigurationIndex", -1, workspaceFolder); } @@ -167,7 +167,7 @@ export class CppProperties { } public get ConfigurationNames(): string[] | undefined { - let result: string[] = []; + const result: string[] = []; if (this.configurationJson) { this.configurationJson.configurations.forEach((config: Configuration) => { result.push(config.name); @@ -189,14 +189,14 @@ export class CppProperties { // defaultPaths is only used when there isn't a c_cpp_properties.json, but we don't send the configuration changed event // to the language server until the default include paths and frameworks have been sent. - let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json"); + const configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json"); if (this.rootUri !== null && fs.existsSync(configFilePath)) { this.propertiesFile = vscode.Uri.file(configFilePath); } else { this.propertiesFile = null; } - let settingsPath: string = path.join(this.configFolder, this.configurationGlobPattern); + const settingsPath: string = path.join(this.configFolder, this.configurationGlobPattern); this.configFileWatcher = vscode.workspace.createFileSystemWatcher(settingsPath); this.disposables.push(this.configFileWatcher); this.configFileWatcher.onDidCreate((uri) => { @@ -266,7 +266,7 @@ export class CppProperties { this.configurationJson = getDefaultCppProperties(); if (resetIndex || this.CurrentConfigurationIndex < 0 || this.CurrentConfigurationIndex >= this.configurationJson.configurations.length) { - let index: number | undefined = this.getConfigIndexForPlatform(this.configurationJson); + const index: number | undefined = this.getConfigIndexForPlatform(this.configurationJson); if (this.currentConfigurationIndex !== undefined) { if (index === undefined) { this.currentConfigurationIndex.setDefault(); @@ -280,7 +280,7 @@ export class CppProperties { private applyDefaultIncludePathsAndFrameworks(): void { if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks && this.vcpkgPathReady) { - let configuration: Configuration | undefined = this.CurrentConfiguration; + const configuration: Configuration | undefined = this.CurrentConfiguration; if (configuration) { this.applyDefaultConfigurationValues(configuration); this.configurationIncomplete = false; @@ -289,9 +289,9 @@ export class CppProperties { } private applyDefaultConfigurationValues(configuration: Configuration): void { - let settings: CppSettings = new CppSettings(this.rootUri); + const settings: CppSettings = new CppSettings(this.rootUri); // default values for "default" config settings is null. - let isUnset: (input: any) => boolean = (input: any) => input === null || input === undefined; + const isUnset: (input: any) => boolean = (input: any) => input === null || input === undefined; // Anything that has a vscode setting for it will be resolved in updateServerOnFolderSettingsChange. // So if a property is currently unset, but has a vscode setting, don't set it yet, otherwise the linkage @@ -299,11 +299,14 @@ export class CppProperties { // Only add settings from the default compiler if user hasn't explicitly set the corresponding VS Code setting. + const abTestSettings: ABTestSettings = getABTestSettings(); + const rootFolder: string = abTestSettings.UseRecursiveIncludes ? "${workspaceFolder}/**" : "${workspaceFolder}"; + const defaultFolder: string = "${default}"; + // We don't add system includes to the includePath anymore. The language server has this information. if (isUnset(settings.defaultIncludePath)) { - // We don't add system includes to the includePath anymore. The language server has this information. - let abTestSettings: ABTestSettings = getABTestSettings(); - let rootFolder: string = abTestSettings.UseRecursiveIncludes ? "${workspaceFolder}/**" : "${workspaceFolder}"; configuration.includePath = [rootFolder].concat(this.vcpkgIncludes); + } else { + configuration.includePath = [rootFolder].concat(this.vcpkgIncludes).concat([defaultFolder]); } // browse.path is not set by default anymore. When it is not set, the includePath will be used instead. if (isUnset(settings.defaultDefines)) { @@ -336,7 +339,7 @@ export class CppProperties { } private get ExtendedEnvironment(): Environment { - let result: Environment = {}; + const result: Environment = {}; if (this.configurationJson?.env) { Object.assign(result, this.configurationJson.env); } @@ -348,14 +351,14 @@ export class CppProperties { private async buildVcpkgIncludePath(): Promise { try { // Check for vcpkgRoot and include relevent paths if found. - let vcpkgRoot: string = util.getVcpkgRoot(); + const vcpkgRoot: string = util.getVcpkgRoot(); if (vcpkgRoot) { - let list: string[] = await util.readDir(vcpkgRoot); + const list: string[] = await util.readDir(vcpkgRoot); if (list !== undefined) { // For every *directory* in the list (non-recursive). Each directory is basically a platform. list.forEach((entry) => { if (entry !== "vcpkg") { - let pathToCheck: string = path.join(vcpkgRoot, entry); + const pathToCheck: string = path.join(vcpkgRoot, entry); if (fs.existsSync(pathToCheck)) { let p: string = path.join(pathToCheck, "include"); if (fs.existsSync(p)) { @@ -423,13 +426,13 @@ export class CppProperties { configuration.intelliSenseMode === "${default}") { return ""; } - let resolvedCompilerPath: string = this.resolvePath(configuration.compilerPath, true); - let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedCompilerPath); + const resolvedCompilerPath: string = this.resolvePath(configuration.compilerPath, true); + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedCompilerPath); // Valid compiler + IntelliSenseMode combinations: // 1. compiler is cl/clang-cl and IntelliSenseMode is MSVC // 2. compiler is not cl/clang-cl and IntelliSenseMode is not MSVC - let isValid: boolean = compilerPathAndArgs.compilerName.endsWith("cl.exe") === configuration.intelliSenseMode.startsWith("msvc"); + const isValid: boolean = compilerPathAndArgs.compilerName.endsWith("cl.exe") === configuration.intelliSenseMode.startsWith("msvc"); if (isValid) { return ""; } else { @@ -440,7 +443,7 @@ export class CppProperties { public addToIncludePathCommand(path: string): void { this.handleConfigurationEditCommand(() => { this.parsePropertiesFile(); // Clear out any modifications we may have made internally. - let config: Configuration | undefined = this.CurrentConfiguration; + const config: Configuration | undefined = this.CurrentConfiguration; if (config) { telemetry.logLanguageServerEvent("addToIncludePath"); if (config.includePath === undefined) { @@ -458,7 +461,7 @@ export class CppProperties { if (this.propertiesFile) { this.handleConfigurationEditJSONCommand(() => { this.parsePropertiesFile(); // Clear out any modifications we may have made internally. - let config: Configuration | undefined = this.CurrentConfiguration; + const config: Configuration | undefined = this.CurrentConfiguration; if (config) { if (providerId) { config.configurationProvider = providerId; @@ -471,13 +474,13 @@ export class CppProperties { resolve(); }, () => {}); } else { - let settings: CppSettings = new CppSettings(this.rootUri); + const settings: CppSettings = new CppSettings(this.rootUri); if (providerId) { settings.update("default.configurationProvider", providerId); } else { settings.update("default.configurationProvider", undefined); // delete the setting } - let config: Configuration | undefined = this.CurrentConfiguration; + const config: Configuration | undefined = this.CurrentConfiguration; if (config) { config.configurationProvider = providerId; } @@ -489,7 +492,7 @@ export class CppProperties { public setCompileCommands(path: string): void { this.handleConfigurationEditJSONCommand(() => { this.parsePropertiesFile(); // Clear out any modifications we may have made internally. - let config: Configuration | undefined = this.CurrentConfiguration; + const config: Configuration | undefined = this.CurrentConfiguration; if (config) { config.compileCommands = path; this.writeToJson(); @@ -532,14 +535,13 @@ export class CppProperties { return result; } - private resolveDefaultsDictionary(entries: { [key: string] : string }, defaultValue: { [key: string] : string } | undefined, env: Environment): { [key: string] : string } { - let result: { [key: string] : string } = {}; + private resolveDefaultsDictionary(entries: { [key: string]: string }, defaultValue: { [key: string]: string } | undefined, env: Environment): { [key: string]: string } { + const result: { [key: string]: string } = {}; for (const property in entries) { if (property === "${default}") { if (defaultValue) { for (const defaultProperty in defaultValue) { - if (!(defaultProperty in entries)) - { + if (!(defaultProperty in entries)) { result[defaultProperty] = util.resolveVariables(defaultValue[defaultProperty], env); } } @@ -556,7 +558,7 @@ export class CppProperties { if (paths) { paths = this.resolveDefaults(paths, defaultValue); paths.forEach(entry => { - let entries: string[] = util.resolveVariables(entry, env).split(util.envDelimiter).filter(e => e); + const entries: string[] = util.resolveVariables(entry, env).split(util.envDelimiter).filter(e => e); result = result.concat(entries); }); } @@ -610,10 +612,10 @@ export class CppProperties { if (!this.configurationJson) { return; } - let settings: CppSettings = new CppSettings(this.rootUri); - let env: Environment = this.ExtendedEnvironment; + const settings: CppSettings = new CppSettings(this.rootUri); + const env: Environment = this.ExtendedEnvironment; for (let i: number = 0; i < this.configurationJson.configurations.length; i++) { - let configuration: Configuration = this.configurationJson.configurations[i]; + const configuration: Configuration = this.configurationJson.configurations[i]; configuration.includePath = this.updateConfigurationStringArray(configuration.includePath, settings.defaultIncludePath, env); configuration.defines = this.updateConfigurationStringArray(configuration.defines, settings.defaultDefines, env); @@ -668,10 +670,10 @@ export class CppProperties { if (this.configurationJson) { this.compileCommandFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close()); this.compileCommandFileWatchers = []; // reset it - let filePaths: Set = new Set(); + const filePaths: Set = new Set(); this.configurationJson.configurations.forEach(c => { if (c.compileCommands) { - let fileSystemCompileCommandsPath: string = this.resolvePath(c.compileCommands, os.platform() === "win32"); + const fileSystemCompileCommandsPath: string = this.resolvePath(c.compileCommands, os.platform() === "win32"); if (fs.existsSync(fileSystemCompileCommandsPath)) { filePaths.add(fileSystemCompileCommandsPath); } @@ -680,9 +682,6 @@ export class CppProperties { try { filePaths.forEach((path: string) => { this.compileCommandFileWatchers.push(fs.watch(path, (event: string, filename: string) => { - if (event === "rename") { - return; - } // Wait 1 second after a change to allow time for the write to finish. if (this.compileCommandsFileWatcherTimer) { clearInterval(this.compileCommandsFileWatcherTimer); @@ -709,7 +708,7 @@ export class CppProperties { // onBeforeOpen will be called after c_cpp_properties.json have been created (if it did not exist), but before the document is opened. public handleConfigurationEditCommand(onBeforeOpen: (() => void) | undefined, showDocument: (document: vscode.TextDocument) => void): void { - let otherSettings: OtherSettings = new OtherSettings(this.rootUri); + const otherSettings: OtherSettings = new OtherSettings(this.rootUri); if (otherSettings.settingsEditor === "ui") { this.handleConfigurationEditUICommand(onBeforeOpen, showDocument); } else { @@ -737,7 +736,7 @@ export class CppProperties { private ensureSettingsPanelInitlialized(): void { if (this.settingsPanel === undefined) { - let settings: CppSettings = new CppSettings(this.rootUri); + const settings: CppSettings = new CppSettings(this.rootUri); this.settingsPanel = new SettingsPanel(); this.settingsPanel.setKnownCompilers(this.knownCompilers, settings.preferredPathSeparator); this.settingsPanel.SettingsPanelActivated(() => this.onSettingsPanelActivated()); @@ -758,7 +757,7 @@ export class CppProperties { if (this.parsePropertiesFile()) { this.ensureSettingsPanelInitlialized(); if (this.settingsPanel) { - let configNames: string[] | undefined = this.ConfigurationNames; + const configNames: string[] | undefined = this.ConfigurationNames; if (configNames && this.configurationJson) { // Use the active configuration as the default selected configuration to load on UI editor this.settingsPanel.selectedConfigIndex = this.CurrentConfigurationIndex; @@ -784,7 +783,7 @@ export class CppProperties { this.ensurePropertiesFile().then(() => { if (this.propertiesFile) { if (this.parsePropertiesFile()) { - let configNames: string[] | undefined = this.ConfigurationNames; + const configNames: string[] | undefined = this.ConfigurationNames; if (configNames && this.settingsPanel && this.configurationJson) { // The settings UI became visible or active. // Ensure settingsPanel has copy of latest current configuration @@ -807,7 +806,7 @@ export class CppProperties { private saveConfigurationUI(): void { this.parsePropertiesFile(); // Clear out any modifications we may have made internally. if (this.settingsPanel && this.configurationJson) { - let config: Configuration = this.settingsPanel.getLastValuesFromConfigUI(); + const config: Configuration = this.settingsPanel.getLastValuesFromConfigUI(); this.configurationJson.configurations[this.settingsPanel.selectedConfigIndex] = config; this.settingsPanel.updateErrors(this.getErrorsForConfigUI(this.settingsPanel.selectedConfigIndex)); this.writeToJson(); @@ -815,7 +814,7 @@ export class CppProperties { } private onConfigSelectionChanged(): void { - let configNames: string[] | undefined = this.ConfigurationNames; + const configNames: string[] | undefined = this.ConfigurationNames; if (configNames && this.settingsPanel && this.configurationJson) { this.settingsPanel.updateConfigUI(configNames, this.configurationJson.configurations[this.settingsPanel.selectedConfigIndex], @@ -827,9 +826,9 @@ export class CppProperties { this.parsePropertiesFile(); // Clear out any modifications we may have made internally. // Create default config and add to list of configurations - let newConfig: Configuration = { name: configName }; + const newConfig: Configuration = { name: configName }; this.applyDefaultConfigurationValues(newConfig); - let configNames: string[] | undefined = this.ConfigurationNames; + const configNames: string[] | undefined = this.ConfigurationNames; if (configNames && this.settingsPanel && this.configurationJson) { this.configurationJson.configurations.push(newConfig); @@ -857,7 +856,7 @@ export class CppProperties { if (this.CurrentConfigurationIndex < 0 || this.CurrentConfigurationIndex >= this.configurationJson.configurations.length) { // If the index is out of bounds (during initialization or due to removal of configs), fix it. - let index: number | undefined = this.getConfigIndexForPlatform(this.configurationJson); + const index: number | undefined = this.getConfigIndexForPlatform(this.configurationJson); if (this.currentConfigurationIndex !== undefined) { if (!index) { this.currentConfigurationIndex.setDefault(); @@ -886,12 +885,12 @@ export class CppProperties { fs.mkdirSync(this.configFolder); } - let fullPathToFile: string = path.join(this.configFolder, "c_cpp_properties.json"); + const fullPathToFile: string = path.join(this.configFolder, "c_cpp_properties.json"); if (this.configurationJson) { this.resetToDefaultSettings(true); } this.applyDefaultIncludePathsAndFrameworks(); - let settings: CppSettings = new CppSettings(this.rootUri); + const settings: CppSettings = new CppSettings(this.rootUri); if (settings.defaultConfigurationProvider) { if (this.configurationJson) { this.configurationJson.configurations.forEach(config => { @@ -906,7 +905,7 @@ export class CppProperties { this.propertiesFile = vscode.Uri.file(path.join(this.configFolder, "c_cpp_properties.json")); } catch (err) { - let failedToCreate: string = localize("failed.to.create.config.folder", 'Failed to create "{0}"', this.configFolder); + const failedToCreate: string = localize("failed.to.create.config.folder", 'Failed to create "{0}"', this.configFolder); vscode.window.showErrorMessage(`${failedToCreate}: ${err.message}`); } } @@ -919,13 +918,13 @@ export class CppProperties { } let success: boolean = true; try { - let readResults: string = fs.readFileSync(this.propertiesFile.fsPath, 'utf8'); + const readResults: string = fs.readFileSync(this.propertiesFile.fsPath, 'utf8'); if (readResults === "") { return false; // Repros randomly when the file is initially created. The parse will get called again after the file is written. } // Try to use the same configuration as before the change. - let newJson: ConfigurationJson = JSON.parse(readResults); + const newJson: ConfigurationJson = JSON.parse(readResults); if (!newJson || !newJson.configurations || newJson.configurations.length === 0) { throw { message: localize("invalid.configuration.file", "Invalid configuration file. There must be at least one configuration present in the array.") }; } @@ -942,7 +941,7 @@ export class CppProperties { } this.configurationJson = newJson; if (this.CurrentConfigurationIndex < 0 || this.CurrentConfigurationIndex >= newJson.configurations.length) { - let index: number | undefined = this.getConfigIndexForPlatform(newJson); + const index: number | undefined = this.getConfigIndexForPlatform(newJson); if (this.currentConfigurationIndex !== undefined) { if (index === undefined) { this.currentConfigurationIndex.setDefault(); @@ -954,7 +953,7 @@ export class CppProperties { let dirty: boolean = false; for (let i: number = 0; i < this.configurationJson.configurations.length; i++) { - let newId: string | undefined = getCustomConfigProviders().checkId(this.configurationJson.configurations[i].configurationProvider); + const newId: string | undefined = getCustomConfigProviders().checkId(this.configurationJson.configurations[i].configurationProvider); if (newId !== this.configurationJson.configurations[i].configurationProvider) { dirty = true; this.configurationJson.configurations[i].configurationProvider = newId; @@ -1009,7 +1008,7 @@ export class CppProperties { } } catch (err) { - let failedToParse: string = localize("failed.to.parse.properties", 'Failed to parse "{0}"', this.propertiesFile.fsPath); + const failedToParse: string = localize("failed.to.parse.properties", 'Failed to parse "{0}"', this.propertiesFile.fsPath); vscode.window.showErrorMessage(`${failedToParse}: ${err.message}`); success = false; } @@ -1061,16 +1060,16 @@ export class CppProperties { } private getErrorsForConfigUI(configIndex: number): ConfigurationErrors { - let errors: ConfigurationErrors = {}; + const errors: ConfigurationErrors = {}; if (!this.configurationJson) { return errors; } const isWindows: boolean = os.platform() === 'win32'; - let config: Configuration = this.configurationJson.configurations[configIndex]; + const config: Configuration = this.configurationJson.configurations[configIndex]; // Validate compilerPath let resolvedCompilerPath: string | undefined = this.resolvePath(config.compilerPath, isWindows); - let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedCompilerPath); + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedCompilerPath); if (resolvedCompilerPath && // Don't error cl.exe paths because it could be for an older preview build. !(isWindows && compilerPathAndArgs.compilerName === "cl.exe")) { @@ -1078,13 +1077,13 @@ export class CppProperties { // Error when the compiler's path has spaces without quotes but args are used. // Except, exclude cl.exe paths because it could be for an older preview build. - let compilerPathNeedsQuotes: boolean = + const compilerPathNeedsQuotes: boolean = (compilerPathAndArgs.additionalArgs && compilerPathAndArgs.additionalArgs.length > 0) && !resolvedCompilerPath.startsWith('"') && compilerPathAndArgs.compilerPath !== undefined && compilerPathAndArgs.compilerPath.includes(" "); - let compilerPathErrors: string[] = []; + const compilerPathErrors: string[] = []; if (compilerPathNeedsQuotes) { compilerPathErrors.push(localize("path.with.spaces", 'Compiler path with spaces and arguments is missing double quotes " around the path.')); } @@ -1093,7 +1092,7 @@ export class CppProperties { resolvedCompilerPath = compilerPathAndArgs.compilerPath; if (resolvedCompilerPath) { let pathExists: boolean = true; - let existsWithExeAdded: (path: string) => boolean = (path: string) => isWindows && !path.startsWith("/") && fs.existsSync(path + ".exe"); + const existsWithExeAdded: (path: string) => boolean = (path: string) => isWindows && !path.startsWith("/") && fs.existsSync(path + ".exe"); if (!fs.existsSync(resolvedCompilerPath)) { if (existsWithExeAdded(resolvedCompilerPath)) { resolvedCompilerPath += ".exe"; @@ -1115,13 +1114,13 @@ export class CppProperties { } if (!pathExists) { - let message: string = localize('cannot.find', "Cannot find: {0}", resolvedCompilerPath); + const message: string = localize('cannot.find', "Cannot find: {0}", resolvedCompilerPath); compilerPathErrors.push(message); } else if (compilerPathAndArgs.compilerPath === "") { - let message: string = localize("cannot.resolve.compiler.path", "Invalid input, cannot resolve compiler path"); + const message: string = localize("cannot.resolve.compiler.path", "Invalid input, cannot resolve compiler path"); compilerPathErrors.push(message); } else if (!util.checkFileExistsSync(resolvedCompilerPath)) { - let message: string = localize("path.is.not.a.file", "Path is not a file: {0}", resolvedCompilerPath); + const message: string = localize("path.is.not.a.file", "Path is not a file: {0}", resolvedCompilerPath); compilerPathErrors.push(message); } @@ -1143,7 +1142,7 @@ export class CppProperties { // Validate intelliSenseMode if (isWindows) { - let intelliSenesModeError: string = this.validateIntelliSenseMode(config); + const intelliSenesModeError: string = this.validateIntelliSenseMode(config); if (intelliSenesModeError.length > 0) { errors.intelliSenseMode = intelliSenesModeError; } @@ -1159,7 +1158,7 @@ export class CppProperties { const isWindows: boolean = os.platform() === 'win32'; let errorMsg: string | undefined; - let errors: string[] = []; + const errors: string[] = []; let paths: string[] = []; if (util.isString(input)) { @@ -1171,7 +1170,7 @@ export class CppProperties { // Resolve and split any environment variables paths = this.resolveAndSplit(paths, undefined, this.ExtendedEnvironment); - for (let p of paths) { + for (const p of paths) { let pathExists: boolean = true; let resolvedPath: string = this.resolvePath(p, isWindows); if (!resolvedPath) { @@ -1194,17 +1193,17 @@ export class CppProperties { } if (!pathExists) { - let message: string = localize('cannot.find', "Cannot find: {0}", resolvedPath); + const message: string = localize('cannot.find', "Cannot find: {0}", resolvedPath); errors.push(message); continue; } // Check if path is a directory or file if (isDirectory && !util.checkDirectoryExistsSync(resolvedPath)) { - let message: string = localize("path.is.not.a.directory", "Path is not a directory: {0}", resolvedPath); + const message: string = localize("path.is.not.a.directory", "Path is not a directory: {0}", resolvedPath); errors.push(message); } else if (!isDirectory && !util.checkFileExistsSync(resolvedPath)) { - let message: string = localize("path.is.not.a.file", "Path is not a file: {0}", resolvedPath); + const message: string = localize("path.is.not.a.file", "Path is not a file: {0}", resolvedPath); errors.push(message); } } @@ -1234,16 +1233,16 @@ export class CppProperties { return; } vscode.workspace.openTextDocument(this.propertiesFile).then((document: vscode.TextDocument) => { - let diagnostics: vscode.Diagnostic[] = new Array(); + const diagnostics: vscode.Diagnostic[] = new Array(); // Get the text of the current configuration. let curText: string = document.getText(); // Replace all \ with \\, except for \" // Otherwise, the JSON.parse result will have the \ missing. - let configurationsText: string = util.escapeForSquiggles(curText); - let configurations: ConfigurationJson = JSON.parse(configurationsText); - let currentConfiguration: Configuration = configurations.configurations[this.CurrentConfigurationIndex]; + const configurationsText: string = util.escapeForSquiggles(curText); + const configurations: ConfigurationJson = JSON.parse(configurationsText); + const currentConfiguration: Configuration = configurations.configurations[this.CurrentConfigurationIndex]; let curTextStartOffset: number = 0; if (!currentConfiguration.name) { @@ -1251,7 +1250,7 @@ export class CppProperties { } // Get env text - let envText: string; + let envText: string = ""; const envStart: number = curText.search(/\"env\"\s*:\s*\{/); const envEnd: number = envStart === -1 ? -1 : curText.indexOf("},", envStart); envText = curText.substr(envStart, envEnd); @@ -1281,7 +1280,7 @@ export class CppProperties { if (this.prevSquiggleMetrics.get(currentConfiguration.name) === undefined) { this.prevSquiggleMetrics.set(currentConfiguration.name, { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0 }); } - let newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0 }; + const newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0 }; const isWindows: boolean = os.platform() === 'win32'; // TODO: Add other squiggles. @@ -1294,10 +1293,10 @@ export class CppProperties { const intelliSenseModeValueStart: number = curText.indexOf('"', curText.indexOf(":", intelliSenseModeStart)); const intelliSenseModeValueEnd: number = intelliSenseModeStart === -1 ? -1 : curText.indexOf('"', intelliSenseModeValueStart + 1) + 1; - let intelliSenseModeError: string = this.validateIntelliSenseMode(currentConfiguration); + const intelliSenseModeError: string = this.validateIntelliSenseMode(currentConfiguration); if (intelliSenseModeError.length > 0) { - let message: string = intelliSenseModeError; - let diagnostic: vscode.Diagnostic = new vscode.Diagnostic( + const message: string = intelliSenseModeError; + const diagnostic: vscode.Diagnostic = new vscode.Diagnostic( new vscode.Range(document.positionAt(curTextStartOffset + intelliSenseModeValueStart), document.positionAt(curTextStartOffset + intelliSenseModeValueEnd)), message, vscode.DiagnosticSeverity.Warning); @@ -1309,10 +1308,10 @@ export class CppProperties { // Check for path-related squiggles. let paths: string[] = []; - for (let pathArray of [ (currentConfiguration.browse ? currentConfiguration.browse.path : undefined), + for (const pathArray of [ (currentConfiguration.browse ? currentConfiguration.browse.path : undefined), currentConfiguration.includePath, currentConfiguration.macFrameworkPath, currentConfiguration.forcedInclude ]) { if (pathArray) { - for (let curPath of pathArray) { + for (const curPath of pathArray) { paths.push(`${curPath}`); } } @@ -1337,10 +1336,10 @@ export class CppProperties { const compilerPathStart: number = curText.search(/\s*\"compilerPath\"\s*:\s*\"/); const compilerPathEnd: number = compilerPathStart === -1 ? -1 : curText.indexOf('"', curText.indexOf('"', curText.indexOf(":", compilerPathStart)) + 1) + 1; - let processedPaths: Set = new Set(); + const processedPaths: Set = new Set(); // Validate paths - for (let curPath of paths) { + for (const curPath of paths) { if (processedPaths.has(curPath)) { // Avoid duplicate squiggles for the same line. // Squiggles for the same path on different lines are already handled below. @@ -1362,7 +1361,7 @@ export class CppProperties { let compilerPathNeedsQuotes: boolean = false; if (isCompilerPath) { resolvedPath = resolvedPath.trim(); - let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedPath); + const compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(resolvedPath); if (isWindows && compilerPathAndArgs.compilerName === "cl.exe") { continue; // Don't squiggle invalid cl.exe paths because it could be for an older preview build. } @@ -1378,7 +1377,7 @@ export class CppProperties { const isWSL: boolean = isWindows && resolvedPath.startsWith("/"); let pathExists: boolean = true; - let existsWithExeAdded: (path: string) => boolean = (path: string) => isCompilerPath && isWindows && !isWSL && fs.existsSync(path + ".exe"); + const existsWithExeAdded: (path: string) => boolean = (path: string) => isCompilerPath && isWindows && !isWSL && fs.existsSync(path + ".exe"); if (!fs.existsSync(resolvedPath)) { if (existsWithExeAdded(resolvedPath)) { resolvedPath += ".exe"; @@ -1415,12 +1414,12 @@ export class CppProperties { // 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. - let pattern: RegExp = new RegExp(`"[^"]*?(?<="|;)${escapedPath}(?="|;).*?"`, "g"); - let configMatches: string[] | null = curText.match(pattern); + const pattern: RegExp = new RegExp(`"[^"]*?(?<="|;)${escapedPath}(?="|;).*?"`, "g"); + const configMatches: string[] | null = curText.match(pattern); if (configMatches) { let curOffset: number = 0; let endOffset: number = 0; - for (let curMatch of configMatches) { + for (const curMatch of configMatches) { curOffset = curText.substr(endOffset).search(pattern) + endOffset; endOffset = curOffset + curMatch.length; let message: string; @@ -1450,25 +1449,25 @@ export class CppProperties { newSquiggleMetrics.PathNotADirectory++; } } - let diagnostic: vscode.Diagnostic = new vscode.Diagnostic( + const diagnostic: vscode.Diagnostic = new vscode.Diagnostic( new vscode.Range(document.positionAt(curTextStartOffset + curOffset), document.positionAt(curTextStartOffset + endOffset)), message, vscode.DiagnosticSeverity.Warning); diagnostics.push(diagnostic); } } else if (envText) { - let envMatches: string[] | null = envText.match(pattern); + const envMatches: string[] | null = envText.match(pattern); if (envMatches) { let curOffset: number = 0; let endOffset: number = 0; - for (let curMatch of envMatches) { + for (const curMatch of envMatches) { curOffset = envText.substr(endOffset).search(pattern) + endOffset; endOffset = curOffset + curMatch.length; let message: string; if (!pathExists) { message = localize('cannot.find2', "Cannot find \"{0}\".", resolvedPath); newSquiggleMetrics.PathNonExistent++; - let diagnostic: vscode.Diagnostic = new vscode.Diagnostic( + const diagnostic: vscode.Diagnostic = new vscode.Diagnostic( new vscode.Range(document.positionAt(envTextStartOffSet + curOffset), document.positionAt(envTextStartOffSet + endOffset)), message, vscode.DiagnosticSeverity.Warning); @@ -1486,7 +1485,7 @@ export class CppProperties { } // Send telemetry on squiggle changes. - let changedSquiggleMetrics: { [key: string]: number } = {}; + const changedSquiggleMetrics: { [key: string]: number } = {}; if (newSquiggleMetrics.PathNonExistent !== this.prevSquiggleMetrics.get(currentConfiguration.name)?.PathNonExistent) { changedSquiggleMetrics.PathNonExistent = newSquiggleMetrics.PathNonExistent; } @@ -1521,7 +1520,7 @@ export class CppProperties { if (this.configurationJson) { this.configurationJson.version = 3; for (let i: number = 0; i < this.configurationJson.configurations.length; i++) { - let config: Configuration = this.configurationJson.configurations[i]; + const config: Configuration = this.configurationJson.configurations[i]; // Look for Mac configs and extra configs on Mac systems if (config.name === "Mac" || (process.platform === 'darwin' && config.name !== "Win32" && config.name !== "Linux")) { if (config.macFrameworkPath === undefined) { @@ -1540,9 +1539,9 @@ export class CppProperties { this.configurationJson.version = 4; // Update intelliSenseMode, compilerPath, cStandard, and cppStandard with the defaults if they're missing. // If VS Code settings exist for these properties, don't add them to c_cpp_properties.json - let settings: CppSettings = new CppSettings(this.rootUri); + const settings: CppSettings = new CppSettings(this.rootUri); for (let i: number = 0; i < this.configurationJson.configurations.length; i++) { - let config: Configuration = this.configurationJson.configurations[i]; + const config: Configuration = this.configurationJson.configurations[i]; if (config.intelliSenseMode === undefined && !settings.defaultIntelliSenseMode) { config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name); @@ -1570,7 +1569,7 @@ export class CppProperties { public checkCppProperties(): void { // Check for change properties in case of file watcher failure. - let propertiesFile: string = path.join(this.configFolder, "c_cpp_properties.json"); + const propertiesFile: string = path.join(this.configFolder, "c_cpp_properties.json"); fs.stat(propertiesFile, (err, stats) => { if (err) { if (err.code === "ENOENT" && this.propertiesFile) { diff --git a/Extension/src/LanguageServer/customProviders.ts b/Extension/src/LanguageServer/customProviders.ts index 40dd977147..d47d50e889 100644 --- a/Extension/src/LanguageServer/customProviders.ts +++ b/Extension/src/LanguageServer/customProviders.ts @@ -108,7 +108,7 @@ export class CustomConfigurationProviderCollection { private providers: Map = new Map(); private logProblems(provider: CustomConfigurationProvider, version: Version): void { - let missing: string[] = []; + const missing: string[] = []; if (!provider.name) { missing.push("'name'"); } @@ -162,14 +162,14 @@ export class CustomConfigurationProviderCollection { return false; } - let wrapper: CustomProviderWrapper = new CustomProviderWrapper(provider, version); + const wrapper: CustomProviderWrapper = new CustomProviderWrapper(provider, version); if (!wrapper.isValid) { this.logProblems(provider, version); return false; } let exists: boolean = false; - let existing: CustomProviderWrapper | undefined = this.providers.get(wrapper.extensionId); + const existing: CustomProviderWrapper | undefined = this.providers.get(wrapper.extensionId); if (existing) { exists = (existing.version === Version.v0 && wrapper.version === Version.v0); } @@ -208,7 +208,7 @@ export class CustomConfigurationProviderCollection { } public remove(provider: CustomConfigurationProvider): void { - let id: string = this.getId(provider); + const id: string = this.getId(provider); if (this.providers.has(id)) { this.providers.delete(id); } else { @@ -220,7 +220,7 @@ export class CustomConfigurationProviderCollection { if (!providerId) { return undefined; } - let found: CustomConfigurationProvider1[] = []; + const found: CustomConfigurationProvider1[] = []; let noUpdate: boolean = false; this.forEach(provider => { if (provider.extensionId === providerId) { @@ -241,7 +241,7 @@ export class CustomConfigurationProviderCollection { } } -let providerCollection: CustomConfigurationProviderCollection = new CustomConfigurationProviderCollection(); +const providerCollection: CustomConfigurationProviderCollection = new CustomConfigurationProviderCollection(); export function getCustomConfigProviders(): CustomConfigurationProviderCollection { return providerCollection; diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 2e06d811e5..4b8f2ebc8c 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -14,7 +14,7 @@ import { TreeNode, NodeType } from './referencesModel'; import { UI, getUI } from './ui'; import { Client } from './client'; import { ClientCollection } from './clientCollection'; -import { CppSettings } from './settings'; +import { CppSettings, OtherSettings } from './settings'; import { PersistentWorkspaceState, PersistentState } from './persistentState'; import { getLanguageConfig } from './languageConfig'; import { getCustomConfigProviders } from './customProviders'; @@ -37,7 +37,7 @@ let prevCrashFile: string; let clients: ClientCollection; let activeDocument: string; let ui: UI; -let disposables: vscode.Disposable[] = []; +const disposables: vscode.Disposable[] = []; let languageConfigurations: vscode.Disposable[] = []; let intervalTimer: NodeJS.Timer; let insiderUpdateEnabled: boolean = false; @@ -75,10 +75,10 @@ function initVcpkgDatabase(): Promise { resolve({}); return; } - let database: vcpkgDatabase = {}; - let reader: rd.ReadLine = rd.createInterface(stream); + const database: vcpkgDatabase = {}; + const reader: rd.ReadLine = rd.createInterface(stream); reader.on('line', (lineText: string) => { - let portFilePair: string[] = lineText.split(':'); + const portFilePair: string[] = lineText.split(':'); if (portFilePair.length !== 2) { return; } @@ -215,7 +215,7 @@ export function activate(activationEventOccurred: boolean): void { // handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event. if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { for (let i: number = 0; i < vscode.workspace.workspaceFolders.length; ++i) { - let config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json"); + const config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json"); if (fs.existsSync(config)) { onActivationEvent(); return; @@ -226,7 +226,7 @@ export function activate(activationEventOccurred: boolean): void { // handle "onLanguage:cpp" and "onLanguage:c" activation events. if (vscode.workspace.textDocuments !== undefined && vscode.workspace.textDocuments.length > 0) { for (let i: number = 0; i < vscode.workspace.textDocuments.length; ++i) { - let document: vscode.TextDocument = vscode.workspace.textDocuments[i]; + const document: vscode.TextDocument = vscode.workspace.textDocuments[i]; if (document.uri.scheme === "file") { if (document.languageId === "cpp" || document.languageId === "c") { onActivationEvent(); @@ -343,12 +343,13 @@ export async function getBuildTasks(returnCompilerPath: boolean, appendSourceToN return []; } - let createTask: (compilerPath: string, compilerArgs?: string []) => vscode.Task = (compilerPath: string, compilerArgs?: string []) => { + const createTask: (compilerPath: string, compilerArgs?: string []) => vscode.Task = (compilerPath: string, compilerArgs?: string []) => { const filePath: string = path.join('${fileDirname}', '${fileBasenameNoExtension}'); const compilerPathBase: string = path.basename(compilerPath); + const compilerPathDir: string = path.dirname(compilerPath); const taskName: string = (appendSourceToName ? taskSourceStr + ": " : "") + compilerPathBase + " build active file"; const isCl: boolean = compilerPathBase === "cl.exe"; - const cwd: string = "${workspaceFolder}"; + const cwd: string = isWindows && !isCl && !process.env.PATH?.includes(compilerPathDir) ? compilerPathDir : "${workspaceFolder}"; let args: string[] = isCl ? ['/Zi', '/EHsc', '/Fe:', filePath + '.exe', '${file}'] : ['-g', '${file}', '-o', filePath + (isWindows ? '.exe' : '')]; if (compilerArgs && compilerArgs.length > 0) { args = args.concat(compilerArgs); @@ -368,7 +369,7 @@ export async function getBuildTasks(returnCompilerPath: boolean, appendSourceToN } const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, [...args], { cwd: cwd }); - let uri: vscode.Uri | undefined = clients.ActiveClient.RootUri; + const uri: vscode.Uri | undefined = clients.ActiveClient.RootUri; if (!uri) { throw new Error("No client URI found in getBuildTasks()"); } @@ -376,7 +377,7 @@ export async function getBuildTasks(returnCompilerPath: boolean, appendSourceToN if (!target) { throw new Error("No target WorkspaceFolder found in getBuildTasks()"); } - let task: vscode.Task = new vscode.Task(kind, target, taskName, taskSourceStr, command, isCl ? '$msCompile' : '$gcc'); + const task: vscode.Task = new vscode.Task(kind, target, taskName, taskSourceStr, command, isCl ? '$msCompile' : '$gcc'); task.definition = kind; // The constructor for vscode.Task will consume the definition. Reset it by reassigning. task.group = vscode.TaskGroup.Build; @@ -393,7 +394,7 @@ export async function getBuildTasks(returnCompilerPath: boolean, appendSourceToN // Task for user compiler path setting if (userCompilerPath) { - let task: vscode.Task = createTask(userCompilerPath, userCompilerPathAndArgs?.additionalArgs); + const task: vscode.Task = createTask(userCompilerPath, userCompilerPathAndArgs?.additionalArgs); buildTasks.push(task); } @@ -427,10 +428,10 @@ function realActivation(): void { throw new Error(intelliSenseDisabledError); } else { console.log("activating extension"); - let checkForConflictingExtensions: PersistentState = new PersistentState("CPP." + util.packageJson.version + ".checkForConflictingExtensions", true); + const checkForConflictingExtensions: PersistentState = new PersistentState("CPP." + util.packageJson.version + ".checkForConflictingExtensions", true); if (checkForConflictingExtensions.Value) { checkForConflictingExtensions.Value = false; - let clangCommandAdapterActive: boolean = vscode.extensions.all.some((extension: vscode.Extension, index: number, array: Readonly[]>): boolean => + const clangCommandAdapterActive: boolean = vscode.extensions.all.some((extension: vscode.Extension, index: number, array: Readonly[]>): boolean => extension.isActive && extension.id === "mitaki28.vscode-clang"); if (clangCommandAdapterActive) { telemetry.logLanguageServerEvent("conflictingExtension"); @@ -453,7 +454,6 @@ function realActivation(): void { disposables.push(vscode.window.onDidChangeActiveTextEditor(onDidChangeActiveTextEditor)); disposables.push(vscode.window.onDidChangeTextEditorSelection(onDidChangeTextEditorSelection)); disposables.push(vscode.window.onDidChangeVisibleTextEditors(onDidChangeVisibleTextEditors)); - disposables.push(vscode.window.onDidChangeTextEditorVisibleRanges(onDidChangeTextEditorVisibleRanges)); updateLanguageConfigurations(); @@ -468,15 +468,20 @@ function realActivation(): void { if (info.platform !== "linux" || info.architecture === "x86_64") { // Skip Insiders processing for unsupported VS Code versions. // TODO: Change this to not require the hardcoded version to be updated. - let vscodeVersion: PackageVersion = new PackageVersion(vscode.version); - let minimumSupportedVersionForInsidersUpgrades: PackageVersion = new PackageVersion("1.43.2"); + const vscodeVersion: PackageVersion = new PackageVersion(vscode.version); + const minimumSupportedVersionForInsidersUpgrades: PackageVersion = new PackageVersion("1.43.2"); if (vscodeVersion.isGreaterThan(minimumSupportedVersionForInsidersUpgrades, "insider")) { insiderUpdateEnabled = true; if (settings.updateChannel === 'Default') { - suggestInsidersChannel(); + const userVersion: PackageVersion = new PackageVersion(util.packageJson.version); + if (userVersion.suffix === "insiders") { + checkAndApplyUpdate(settings.updateChannel, false); + } else { + suggestInsidersChannel(); + } } else if (settings.updateChannel === 'Insiders') { - insiderUpdateTimer = global.setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval, settings.updateChannel); - checkAndApplyUpdate(settings.updateChannel); + insiderUpdateTimer = global.setInterval(checkAndApplyUpdateOnTimer, insiderUpdateTimerInterval); + checkAndApplyUpdate(settings.updateChannel, false); } } } @@ -499,7 +504,7 @@ export function updateLanguageConfigurations(): void { * workspace events */ function onDidChangeSettings(event: vscode.ConfigurationChangeEvent): void { - let activeClient: Client = clients.ActiveClient; + const activeClient: Client = clients.ActiveClient; const changedActiveClientSettings: { [key: string]: string } = activeClient.onDidChangeSettings(event, true); clients.forEach(client => { if (client !== activeClient) { @@ -513,10 +518,10 @@ function onDidChangeSettings(event: vscode.ConfigurationChangeEvent): void { if (newUpdateChannel === 'Default') { clearInterval(insiderUpdateTimer); } else if (newUpdateChannel === 'Insiders') { - insiderUpdateTimer = global.setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval); + insiderUpdateTimer = global.setInterval(checkAndApplyUpdateOnTimer, insiderUpdateTimerInterval); } - checkAndApplyUpdate(newUpdateChannel); + checkAndApplyUpdate(newUpdateChannel, true); } } } @@ -528,7 +533,7 @@ export function onDidChangeActiveTextEditor(editor?: vscode.TextEditor): void { return; } - let activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; + const activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; if (!editor || !activeEditor || activeEditor.document.uri.scheme !== "file" || (activeEditor.document.languageId !== "cpp" && activeEditor.document.languageId !== "c")) { activeDocument = ""; } else { @@ -557,26 +562,37 @@ function onDidChangeTextEditorSelection(event: vscode.TextEditorSelectionChangeE } export function processDelayedDidOpen(document: vscode.TextDocument): void { - let client: Client = clients.getClientFor(document.uri); + const client: Client = clients.getClientFor(document.uri); if (client) { if (clients.checkOwnership(client, document)) { if (!client.TrackedDocuments.has(document)) { // If not yet tracked, process as a newly opened file. (didOpen is sent to server in client.takeOwnership()). client.TrackedDocuments.add(document); + const finishDidOpen = (doc: vscode.TextDocument) => { + client.provideCustomConfiguration(doc.uri, undefined); + client.notifyWhenReady(() => { + client.takeOwnership(doc); + client.onDidOpenTextDocument(doc); + }); + }; + let languageChanged: boolean = false; // Work around vscode treating ".C" or ".H" as c, by adding this file name to file associations as cpp if ((document.uri.path.endsWith(".C") || document.uri.path.endsWith(".H")) && document.languageId === "c") { - let cppSettings: CppSettings = new CppSettings(); + const cppSettings: CppSettings = new CppSettings(); if (cppSettings.autoAddFileAssociations) { const fileName: string = path.basename(document.uri.fsPath); const mappingString: string = fileName + "@" + document.uri.fsPath; client.addFileAssociations(mappingString, false); + client.sendDidChangeSettings({ files: { associations: new OtherSettings().filesAssociations }}); + vscode.languages.setTextDocumentLanguage(document, "cpp").then((newDoc: vscode.TextDocument) => { + finishDidOpen(newDoc); + }); + languageChanged = true; } } - client.provideCustomConfiguration(document.uri, undefined); - client.notifyWhenReady(() => { - client.takeOwnership(document); - client.onDidOpenTextDocument(document); - }); + if (!languageChanged) { + finishDidOpen(document); + } } } } @@ -589,32 +605,6 @@ function onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void { processDelayedDidOpen(editor.document); } }); - - clients.forEach(client => { - let editorsForThisClient: vscode.TextEditor[] = []; - editors.forEach(editor => { - if (editor.document.languageId === "c" || editor.document.languageId === "cpp" - || editor.document.languageId === "json" && editor.document.uri.fsPath.endsWith("c_cpp_properties.json")) { - if (clients.checkOwnership(client, editor.document)) { - editorsForThisClient.push(editor); - } - } - }); - if (editorsForThisClient.length > 0) { - client.onDidChangeVisibleTextEditors(editorsForThisClient); - } - }); -} - -function onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void { - let languageId: String = textEditorVisibleRangesChangeEvent.textEditor.document.languageId; - if (languageId === "c" || languageId === "cpp") { - clients.forEach(client => { - if (clients.checkOwnership(client, textEditorVisibleRangesChangeEvent.textEditor.document)) { - client.onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent); - } - }); - } } function onInterval(): void { @@ -627,10 +617,10 @@ function onInterval(): void { * @param updateChannel The user's updateChannel setting. */ function installVsix(vsixLocation: string): Thenable { - let userVersion: PackageVersion = new PackageVersion(vscode.version); + const userVersion: PackageVersion = new PackageVersion(vscode.version); // 1.33.0 introduces workbench.extensions.installExtension. 1.32.3 was immediately prior. - let lastVersionWithoutInstallExtensionCommand: PackageVersion = new PackageVersion('1.32.3'); + const lastVersionWithoutInstallExtensionCommand: PackageVersion = new PackageVersion('1.32.3'); if (userVersion.isGreaterThan(lastVersionWithoutInstallExtensionCommand, "insider")) { return vscode.commands.executeCommand('workbench.extensions.installExtension', vscode.Uri.file(vsixLocation)); } @@ -669,7 +659,7 @@ function installVsix(vsixLocation: string): Thenable { } // 1.28.0 changes the CLI for making installations. 1.27.2 was immediately prior. - let oldVersion: PackageVersion = new PackageVersion('1.27.2'); + const oldVersion: PackageVersion = new PackageVersion('1.27.2'); if (userVersion.isGreaterThan(oldVersion, "insider")) { return new Promise((resolve, reject) => { let process: ChildProcess; @@ -721,7 +711,7 @@ function installVsix(vsixLocation: string): Thenable { // If downgrading, the VS Code CLI will prompt whether the user is sure they would like to downgrade. // Respond to this by writing 0 to stdin (the option to override and install the VSIX package) let sentOverride: boolean = false; - let stdout: Readable | null = process.stdout; + const stdout: Readable | null = process.stdout; if (!stdout) { reject(new Error("Failed to communicate with VS Code script process for installation")); return; @@ -730,7 +720,7 @@ function installVsix(vsixLocation: string): Thenable { if (sentOverride) { return; } - let stdin: Writable | null = process.stdin; + const stdin: Writable | null = process.stdin; if (!stdin) { reject(new Error("Failed to communicate with VS Code script process for installation")); return; @@ -745,14 +735,14 @@ function installVsix(vsixLocation: string): Thenable { } async function suggestInsidersChannel(): Promise { - let suggestInsiders: PersistentState = new PersistentState("CPP.suggestInsiders", true); + const suggestInsiders: PersistentState = new PersistentState("CPP.suggestInsiders", true); if (!suggestInsiders.Value) { return; } let buildInfo: BuildInfo | undefined; try { - buildInfo = await getTargetBuildInfo("Insiders"); + buildInfo = await getTargetBuildInfo("Insiders", false); } catch (error) { console.log(`${cppInstallVsixStr}${error.message}`); if (error.message.indexOf('/') !== -1 || error.message.indexOf('\\') !== -1) { @@ -767,7 +757,7 @@ async function suggestInsidersChannel(): Promise { const yes: string = localize("yes.button", "Yes"); const askLater: string = localize("ask.me.later.button", "Ask Me Later"); const dontShowAgain: string = localize("dont.show.again.button", "Don't Show Again"); - let selection: string | undefined = await vscode.window.showInformationMessage(message, yes, askLater, dontShowAgain); + const selection: string | undefined = await vscode.window.showInformationMessage(message, yes, askLater, dontShowAgain); switch (selection) { case yes: // Cache buildInfo. @@ -791,8 +781,8 @@ async function applyUpdate(buildInfo: BuildInfo): Promise { tempVSIX = await util.createTempFileWithPostfix('.vsix'); // Try to download VSIX - let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); - let originalProxySupport: string | undefined = config.inspect('http.proxySupport')?.globalValue; + const config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); + const originalProxySupport: string | undefined = config.inspect('http.proxySupport')?.globalValue; while (true) { // Might need to try again with a different http.proxySupport setting. try { await util.downloadFileToDestination(buildInfo.downloadUrl, tempVSIX.name); @@ -844,12 +834,17 @@ async function applyUpdate(buildInfo: BuildInfo): Promise { } } +async function checkAndApplyUpdateOnTimer(): Promise { + return checkAndApplyUpdate('Insiders', false); +} + /** * Query package.json and the GitHub API to determine whether the user should update, if so then install the update. * The update can be an upgrade or downgrade depending on the the updateChannel setting. * @param updateChannel The user's updateChannel setting. + * @param isFromSettingsChange True if the invocation is the result of a settings change. */ -async function checkAndApplyUpdate(updateChannel: string): Promise { +async function checkAndApplyUpdate(updateChannel: string, isFromSettingsChange: boolean): Promise { // If we have buildInfo cache, we should use it. let buildInfo: BuildInfo | undefined = buildInfoCache; // clear buildInfo cache. @@ -857,7 +852,7 @@ async function checkAndApplyUpdate(updateChannel: string): Promise { if (!buildInfo) { try { - buildInfo = await getTargetBuildInfo(updateChannel); + buildInfo = await getTargetBuildInfo(updateChannel, isFromSettingsChange); } catch (error) { telemetry.logLanguageServerEvent('installVsix', { 'error': error.message, 'success': 'false' }); } @@ -912,7 +907,7 @@ export function registerCommands(): void { function onSwitchHeaderSource(): void { onActivationEvent(); - let activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; + const activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; if (!activeEditor || !activeEditor.document) { return; } @@ -922,7 +917,7 @@ function onSwitchHeaderSource(): void { } let rootPath: string = clients.ActiveClient.RootPath; - let fileName: string = activeEditor.document.fileName; + const fileName: string = activeEditor.document.fileName; if (!rootPath) { rootPath = path.dirname(fileName); // When switching without a folder open. @@ -961,7 +956,7 @@ function selectClient(): Thenable { } else { return ui.showWorkspaces(clients.Names).then(key => { if (key !== "") { - let client: Client | undefined = clients.get(key); + const client: Client | undefined = clients.get(key); if (client) { return client; } else { @@ -1040,28 +1035,28 @@ function onAddToIncludePath(path: string): void { function onEnableSquiggles(): void { onActivationEvent(); // This only applies to the active client. - let settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); + const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); settings.update("errorSquiggles", "Enabled"); } function onDisableSquiggles(): void { onActivationEvent(); // This only applies to the active client. - let settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); + const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); settings.update("errorSquiggles", "Disabled"); } function onToggleIncludeFallback(): void { onActivationEvent(); // This only applies to the active client. - let settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); + const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); settings.toggleSetting("intelliSenseEngineFallback", "Enabled", "Disabled"); } function onToggleDimInactiveRegions(): void { onActivationEvent(); // This only applies to the active client. - let settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); + const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri); settings.update("dimInactiveRegions", !settings.dimInactiveRegions); } @@ -1087,14 +1082,14 @@ function onShowReferencesProgress(): void { function onToggleRefGroupView(): void { // Set context to switch icons - let client: Client = getActiveClient(); + const client: Client = getActiveClient(); client.toggleReferenceResultsView(); } function onTakeSurvey(): void { onActivationEvent(); telemetry.logLanguageServerEvent("onTakeSurvey"); - let uri: vscode.Uri = vscode.Uri.parse(`https://www.research.net/r/VBVV6C6?o=${os.platform()}&m=${vscode.env.machineId}`); + const uri: vscode.Uri = vscode.Uri.parse(`https://www.research.net/r/VBVV6C6?o=${os.platform()}&m=${vscode.env.machineId}`); vscode.commands.executeCommand('vscode.open', uri); } @@ -1139,7 +1134,7 @@ async function onVcpkgClipboardInstallSuggested(ports?: string[]): Promise } // Queue look ups in the vcpkg database for missing ports; filter out duplicate results - let portsPromises: Promise[] = []; + const portsPromises: Promise[] = []; missingIncludeLocations.forEach(docAndLineNumbers => { docAndLineNumbers[1].forEach(async line => { portsPromises.push(lookupIncludeInVcpkg(docAndLineNumbers[0], line)); @@ -1149,7 +1144,7 @@ async function onVcpkgClipboardInstallSuggested(ports?: string[]): Promise if (!ports.length) { return; } - let ports2: string[] = ports; + const ports2: string[] = ports; ports = ports2.filter((port: string, index: number) => ports2.indexOf(port) === index); } @@ -1209,9 +1204,9 @@ function reportMacCrashes(): void { if (!home) { return; } - let crashFolder: string = path.resolve(home, "Library/Logs/DiagnosticReports"); + const crashFolder: string = path.resolve(home, "Library/Logs/DiagnosticReports"); fs.stat(crashFolder, (err, stats) => { - let crashObject: { [key: string]: string } = {}; + const crashObject: { [key: string]: string } = {}; if (err?.code) { // If the directory isn't there, we have a problem... crashObject["fs.stat: err.code"] = err.code; @@ -1252,7 +1247,7 @@ function reportMacCrashes(): void { } function logCrashTelemetry(data: string): void { - let crashObject: { [key: string]: string } = {}; + const crashObject: { [key: string]: string } = {}; crashObject["CrashingThreadCallStack"] = data; telemetry.logLanguageServerEvent("MacCrash", crashObject, undefined); } @@ -1265,7 +1260,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data // Extract the crashing process version, because the version might not match // if multiple VS Codes are running with different extension versions. let binaryVersion: string = ""; - let startVersion: number = data.indexOf("Version:"); + const startVersion: number = data.indexOf("Version:"); if (startVersion >= 0) { data = data.substr(startVersion); const binaryVersionMatches: string[] | null = data.match(/^Version:\s*(\d*\.\d*\.\d*\.\d*|\d)/); @@ -1307,7 +1302,7 @@ function handleCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data } // Remove runtime lines because they can be different on different machines. - let lines: string[] = data.split("\n"); + const lines: string[] = data.split("\n"); data = ""; lines.forEach((line: string) => { if (!line.includes(".dylib") && !line.includes("???")) { diff --git a/Extension/src/LanguageServer/languageConfig.ts b/Extension/src/LanguageServer/languageConfig.ts index 3c4e6b873e..b065c42239 100644 --- a/Extension/src/LanguageServer/languageConfig.ts +++ b/Extension/src/LanguageServer/languageConfig.ts @@ -23,7 +23,7 @@ const escapeChars: RegExp = /[\\\^\$\*\+\?\{\}\(\)\.\!\=\|\[\]\ \/]/; // charac // Insert '\\' in front of regexp escape chars. function escape(chars: string): string { let result: string = ""; - for (let char of chars) { + for (const char of chars) { if (char.match(escapeChars)) { result += `\\${char}`; } else { @@ -37,7 +37,7 @@ function escape(chars: string): string { function getMLBeginPattern(insert: string): string | undefined { if (insert.startsWith("/*")) { - let match: string = escape(insert.substr(2)); // trim the leading '/*' and escape any troublesome characters. + const match: string = escape(insert.substr(2)); // trim the leading '/*' and escape any troublesome characters. return `^\\s*\\/\\*${match}(?!\\/)([^\\*]|\\*(?!\\/))*$`; } return undefined; @@ -49,9 +49,9 @@ function getMLSplitAfterPattern(): string { function getMLContinuePattern(insert: string): string | undefined { if (insert) { - let match: string = escape(insert.trimRight()); + const match: string = escape(insert.trimRight()); if (match) { - let right: string = escape(insert.substr(insert.trimRight().length)); + const right: string = escape(insert.substr(insert.trimRight().length)); return `^\\s*${match}(${right}([^\\*]|\\*(?!\\/))*)?$`; } // else: if the continuation is just whitespace, vscode already does indentation preservation. @@ -60,7 +60,7 @@ function getMLContinuePattern(insert: string): string | undefined { } function getMLEndPattern(insert: string): string | undefined { - let match: string = escape(insert.trimRight().trimLeft()); + const match: string = escape(insert.trimRight().trimLeft()); if (match) { return `^\\s*${match}[^/]*\\*\\/\\s*$`; } @@ -75,7 +75,7 @@ function getMLEmptyEndPattern(insert: string): string | undefined { if (insert.endsWith('*')) { insert = insert.substr(0, insert.length - 1); } - let match: string = escape(insert.trimRight()); + const match: string = escape(insert.trimRight()); return `^\\s*${match}\\*\\/\\s*$`; } // else: if the continuation is just whitespace, don't mess with indentation @@ -84,18 +84,18 @@ function getMLEmptyEndPattern(insert: string): string | undefined { } function getSLBeginPattern(insert: string): string { - let match: string = escape(insert.trimRight()); + const match: string = escape(insert.trimRight()); return `^\\s*${match}.*$`; } function getSLContinuePattern(insert: string): string { - let match: string = escape(insert.trimRight()); + const match: string = escape(insert.trimRight()); return `^\\s*${match}.+$`; } function getSLEndPattern(insert: string): string { let match: string = escape(insert); - let trimmed: string = escape(insert.trimRight()); + const trimmed: string = escape(insert.trimRight()); if (match !== trimmed) { match = `(${match}|${trimmed})`; } @@ -104,7 +104,7 @@ function getSLEndPattern(insert: string): string { // When Enter is pressed while the cursor is between '/**' and '*/' on the same line. function getMLSplitRule(comment: CommentPattern): vscode.OnEnterRule | undefined { - let beforePattern: string | undefined = getMLBeginPattern(comment.begin); + const beforePattern: string | undefined = getMLBeginPattern(comment.begin); if (beforePattern) { return { beforeText: new RegExp(beforePattern), @@ -120,7 +120,7 @@ function getMLSplitRule(comment: CommentPattern): vscode.OnEnterRule | undefined // When Enter is pressed while the cursor is after '/**' and there is no '*/' on the same line after the cursor function getMLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule | undefined { - let beforePattern: string | undefined = getMLBeginPattern(comment.begin); + const beforePattern: string | undefined = getMLBeginPattern(comment.begin); if (beforePattern) { return { beforeText: new RegExp(beforePattern), @@ -135,7 +135,7 @@ function getMLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule | undef // When Enter is pressed while the cursor is after the continuation pattern function getMLContinuationRule(comment: CommentPattern): vscode.OnEnterRule | undefined { - let continuePattern: string | undefined = getMLContinuePattern(comment.continue); + const continuePattern: string | undefined = getMLContinuePattern(comment.continue); if (continuePattern) { return { beforeText: new RegExp(continuePattern), @@ -150,7 +150,7 @@ function getMLContinuationRule(comment: CommentPattern): vscode.OnEnterRule | un // When Enter is pressed while the cursor is after '*/' (and '*/' plus leading whitespace is all that is on the line) function getMLEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined { - let endPattern: string | undefined = getMLEndPattern(comment.continue); + const endPattern: string | undefined = getMLEndPattern(comment.continue); if (endPattern) { return { beforeText: new RegExp(endPattern), @@ -165,7 +165,7 @@ function getMLEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined { // When Enter is pressed while the cursor is after the continuation pattern and '*/' function getMLEmptyEndRule(comment: CommentPattern): vscode.OnEnterRule | undefined { - let endPattern: string | undefined = getMLEmptyEndPattern(comment.continue); + const endPattern: string | undefined = getMLEmptyEndPattern(comment.continue); if (endPattern) { return { beforeText: new RegExp(endPattern), @@ -180,7 +180,7 @@ function getMLEmptyEndRule(comment: CommentPattern): vscode.OnEnterRule | undefi // When the continue rule is different than the begin rule for single line comments function getSLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule { - let continuePattern: string = getSLBeginPattern(comment.begin); + const continuePattern: string = getSLBeginPattern(comment.begin); return { beforeText: new RegExp(continuePattern), action: { @@ -192,7 +192,7 @@ function getSLFirstLineRule(comment: CommentPattern): vscode.OnEnterRule { // When Enter is pressed while the cursor is after the continuation pattern plus at least one other character. function getSLContinuationRule(comment: CommentPattern): vscode.OnEnterRule { - let continuePattern: string = getSLContinuePattern(comment.continue); + const continuePattern: string = getSLContinuePattern(comment.continue); return { beforeText: new RegExp(continuePattern), action: { @@ -204,7 +204,7 @@ function getSLContinuationRule(comment: CommentPattern): vscode.OnEnterRule { // When Enter is pressed while the cursor is immediately after the continuation pattern function getSLEndRule(comment: CommentPattern): vscode.OnEnterRule { - let endPattern: string = getSLEndPattern(comment.continue); + const endPattern: string = getSLEndPattern(comment.continue); return { beforeText: new RegExp(endPattern), action: { @@ -221,14 +221,14 @@ interface Rules { } export function getLanguageConfig(languageId: string, resource?: vscode.Uri): vscode.LanguageConfiguration { - let settings: CppSettings = new CppSettings(resource); - let patterns: (string | CommentPattern)[] | undefined = settings.commentContinuationPatterns; + const settings: CppSettings = new CppSettings(resource); + const patterns: (string | CommentPattern)[] | undefined = settings.commentContinuationPatterns; return getLanguageConfigFromPatterns(languageId, patterns); } export function getLanguageConfigFromPatterns(languageId: string, patterns?: (string | CommentPattern)[]): vscode.LanguageConfiguration { - let beginPatterns: string[] = []; // avoid duplicate rules - let continuePatterns: string[] = []; // avoid duplicate rules + const beginPatterns: string[] = []; // avoid duplicate rules + const continuePatterns: string[] = []; // avoid duplicate rules let duplicates: boolean = false; let beginRules: vscode.OnEnterRule[] = []; let continueRules: vscode.OnEnterRule[] = []; @@ -237,8 +237,8 @@ export function getLanguageConfigFromPatterns(languageId: string, patterns?: (st patterns = [ "/**" ]; } patterns.forEach(pattern => { - let c: CommentPattern = isString(pattern) ? { begin: pattern, continue: pattern.startsWith('/*') ? " * " : pattern } : pattern; - let r: Rules = constructCommentRules(c, languageId); + const c: CommentPattern = isString(pattern) ? { begin: pattern, continue: pattern.startsWith('/*') ? " * " : pattern } : pattern; + const r: Rules = constructCommentRules(c, languageId); if (beginPatterns.indexOf(c.begin) < 0) { if (r.begin && r.begin.length > 0) { beginRules = beginRules.concat(r.begin); @@ -265,23 +265,23 @@ export function getLanguageConfigFromPatterns(languageId: string, patterns?: (st function constructCommentRules(comment: CommentPattern, languageId: string): Rules { if (comment?.begin?.startsWith('/*') && (languageId === 'c' || languageId === 'cpp')) { - let mlBegin1: vscode.OnEnterRule | undefined = getMLSplitRule(comment); + const mlBegin1: vscode.OnEnterRule | undefined = getMLSplitRule(comment); if (!mlBegin1) { throw new Error("Failure in constructCommentRules() - mlBegin1"); } - let mlBegin2: vscode.OnEnterRule | undefined = getMLFirstLineRule(comment); + const mlBegin2: vscode.OnEnterRule | undefined = getMLFirstLineRule(comment); if (!mlBegin2) { throw new Error("Failure in constructCommentRules() - mlBegin2"); } - let mlContinue: vscode.OnEnterRule | undefined = getMLContinuationRule(comment); + const mlContinue: vscode.OnEnterRule | undefined = getMLContinuationRule(comment); if (!mlContinue) { throw new Error("Failure in constructCommentRules() - mlContinue"); } - let mlEnd1: vscode.OnEnterRule | undefined = getMLEmptyEndRule(comment); + const mlEnd1: vscode.OnEnterRule | undefined = getMLEmptyEndRule(comment); if (!mlEnd1) { throw new Error("Failure in constructCommentRules() - mlEnd1"); } - let mlEnd2: vscode.OnEnterRule | undefined = getMLEndRule(comment); + const mlEnd2: vscode.OnEnterRule | undefined = getMLEndRule(comment); if (!mlEnd2) { throw new Error("Failure in constructCommentRules() = mlEnd2"); } @@ -291,10 +291,10 @@ function constructCommentRules(comment: CommentPattern, languageId: string): Rul end: [ mlEnd1, mlEnd2 ] }; } else if (comment?.begin?.startsWith('//') && languageId === 'cpp') { - let slContinue: vscode.OnEnterRule = getSLContinuationRule(comment); - let slEnd: vscode.OnEnterRule = getSLEndRule(comment); + const slContinue: vscode.OnEnterRule = getSLContinuationRule(comment); + const slEnd: vscode.OnEnterRule = getSLEndRule(comment); if (comment.begin !== comment.continue) { - let slBegin: vscode.OnEnterRule = getSLFirstLineRule(comment); + const slBegin: vscode.OnEnterRule = getSLFirstLineRule(comment); return { begin: (comment.begin === comment.continue) ? [] : [ slBegin ], continue: [ slContinue ], diff --git a/Extension/src/LanguageServer/persistentState.ts b/Extension/src/LanguageServer/persistentState.ts index 0cfc38a6c0..7d2d24d17c 100644 --- a/Extension/src/LanguageServer/persistentState.ts +++ b/Extension/src/LanguageServer/persistentState.ts @@ -61,7 +61,7 @@ export class PersistentWorkspaceState extends PersistentStateBase { export class PersistentFolderState extends PersistentWorkspaceState { constructor(key: string, defaultValue: T, folder: vscode.WorkspaceFolder) { // Check for the old key. If found, remove it and update the new key with the old value. - let old_key: string = key + (folder ? `-${path.basename(folder.uri.fsPath)}` : "-untitled"); + const old_key: string = key + (folder ? `-${path.basename(folder.uri.fsPath)}` : "-untitled"); let old_val: T | undefined; if (util.extensionContext) { old_val = util.extensionContext.workspaceState.get(old_key); @@ -69,7 +69,7 @@ export class PersistentFolderState extends PersistentWorkspaceState { util.extensionContext.workspaceState.update(old_key, undefined); } } - let newKey: string = key + (folder ? `-${folder.uri.fsPath}` : "-untitled"); + const newKey: string = key + (folder ? `-${folder.uri.fsPath}` : "-untitled"); super(newKey, defaultValue); if (old_val !== undefined) { this.Value = old_val; diff --git a/Extension/src/LanguageServer/protocolFilter.ts b/Extension/src/LanguageServer/protocolFilter.ts index 5aa1b10dde..3190872599 100644 --- a/Extension/src/LanguageServer/protocolFilter.ts +++ b/Extension/src/LanguageServer/protocolFilter.ts @@ -9,58 +9,69 @@ import { Middleware } from 'vscode-languageclient'; import { ClientCollection } from './clientCollection'; import { Client } from './client'; import * as vscode from 'vscode'; -import { CppSettings } from './settings'; +import { CppSettings, OtherSettings } from './settings'; import { onDidChangeActiveTextEditor, processDelayedDidOpen } from './extension'; export function createProtocolFilter(clients: ClientCollection): Middleware { // Disabling lint for invoke handlers - let defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data: any) => void) => { clients.ActiveClient.notifyWhenReady(() => callback(data)); }; + const defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data: any) => void) => { clients.ActiveClient.notifyWhenReady(() => callback(data)); }; // let invoke1 = (a, callback: (a) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a)); } return null; }; - let invoke2 = (a: any, b: any, callback: (a: any, b: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b)); - let invoke3 = (a: any, b: any, c: any, callback: (a: any, b: any, c: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c)); - let invoke4 = (a: any, b: any, c: any, d: any, callback: (a: any, b: any, c: any, d: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c, d)); - let invoke5 = (a: any, b: any, c: any, d: any, e: any, callback: (a: any, b: any, c: any, d: any, e: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c, d, e)); + const invoke2 = (a: any, b: any, callback: (a: any, b: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b)); + const invoke3 = (a: any, b: any, c: any, callback: (a: any, b: any, c: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c)); + const invoke4 = (a: any, b: any, c: any, d: any, callback: (a: any, b: any, c: any, d: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c, d)); + const invoke5 = (a: any, b: any, c: any, d: any, e: any, callback: (a: any, b: any, c: any, d: any, e: any) => any) => clients.ActiveClient.requestWhenReady(() => callback(a, b, c, d, e)); /* tslint:enable */ return { didOpen: (document, sendMessage) => { - let editor: vscode.TextEditor | undefined = vscode.window.visibleTextEditors.find(e => e.document === document); + const editor: vscode.TextEditor | undefined = vscode.window.visibleTextEditors.find(e => e.document === document); if (editor) { // If the file was visible editor when we were activated, we will not get a call to // onDidChangeVisibleTextEditors, so immediately open any file that is visible when we receive didOpen. // Otherwise, we defer opening the file until it's actually visible. - let me: Client = clients.getClientFor(document.uri); + const me: Client = clients.getClientFor(document.uri); if (clients.checkOwnership(me, document)) { me.TrackedDocuments.add(document); + const finishDidOpen = (doc: vscode.TextDocument) => { + me.provideCustomConfiguration(doc.uri, undefined); + me.notifyWhenReady(() => { + sendMessage(doc); + me.onDidOpenTextDocument(doc); + if (editor && editor === vscode.window.activeTextEditor) { + onDidChangeActiveTextEditor(editor); + } + }); + }; + let languageChanged: boolean = false; if ((document.uri.path.endsWith(".C") || document.uri.path.endsWith(".H")) && document.languageId === "c") { - let cppSettings: CppSettings = new CppSettings(); + const cppSettings: CppSettings = new CppSettings(); if (cppSettings.autoAddFileAssociations) { const fileName: string = path.basename(document.uri.fsPath); const mappingString: string = fileName + "@" + document.uri.fsPath; me.addFileAssociations(mappingString, false); + me.sendDidChangeSettings({ files: { associations: new OtherSettings().filesAssociations }}); + vscode.languages.setTextDocumentLanguage(document, "cpp").then((newDoc: vscode.TextDocument) => { + finishDidOpen(newDoc); + }); + languageChanged = true; } } - me.provideCustomConfiguration(document.uri, undefined); - me.notifyWhenReady(() => { - sendMessage(document); - me.onDidOpenTextDocument(document); - if (editor && editor === vscode.window.activeTextEditor) { - onDidChangeActiveTextEditor(editor); - } - }); + if (!languageChanged) { + finishDidOpen(document); + } } } else { // NO-OP // If the file is not opened into an editor (such as in response for a control-hover), // we do not actually load a translation unit for it. When we receive a didOpen, the file - // may not yet be visible. So, we defer creation of the translation until we receive a + // may not yet be visible. So, we defer creation of the translation until we receive a // call to onDidChangeVisibleTextEditors(), in extension.ts. A file is only loaded when // it is actually opened in the editor (not in response to control-hover, which sends a // didOpen), and first becomes visible. } }, didChange: (textDocumentChangeEvent, sendMessage) => { - let me: Client = clients.getClientFor(textDocumentChangeEvent.document.uri); + const me: Client = clients.getClientFor(textDocumentChangeEvent.document.uri); if (!me.TrackedDocuments.has(textDocumentChangeEvent.document)) { processDelayedDidOpen(textDocumentChangeEvent.document); } @@ -69,7 +80,7 @@ export function createProtocolFilter(clients: ClientCollection): Middleware { }, willSave: defaultHandler, willSaveWaitUntil: (event, sendMessage) => { - let me: Client = clients.getClientFor(event.document.uri); + const me: Client = clients.getClientFor(event.document.uri); if (me.TrackedDocuments.has(event.document)) { return me.requestWhenReady(() => sendMessage(event)); } @@ -77,7 +88,7 @@ export function createProtocolFilter(clients: ClientCollection): Middleware { }, didSave: defaultHandler, didClose: (document, sendMessage) => { - let me: Client = clients.getClientFor(document.uri); + const me: Client = clients.getClientFor(document.uri); if (me.TrackedDocuments.has(document)) { me.onDidCloseTextDocument(document); me.TrackedDocuments.delete(document); @@ -88,7 +99,7 @@ export function createProtocolFilter(clients: ClientCollection): Middleware { provideCompletionItem: invoke4, resolveCompletionItem: invoke2, provideHover: (document, position, token, next: (document: any, position: any, token: any) => any) => { - let me: Client = clients.getClientFor(document.uri); + const me: Client = clients.getClientFor(document.uri); if (clients.checkOwnership(me, document)) { return clients.ActiveClient.requestWhenReady(() => next(document, position, token)); } diff --git a/Extension/src/LanguageServer/references.ts b/Extension/src/LanguageServer/references.ts index 1de0a09501..2174c4896f 100644 --- a/Extension/src/LanguageServer/references.ts +++ b/Extension/src/LanguageServer/references.ts @@ -137,10 +137,10 @@ export function getReferenceTypeIconPath(referenceType: ReferenceType): { light: case ReferenceType.ConfirmationInProgress: basePath = "ref-confirmation-in-progress"; break; } - let lightPath: string = util.getExtensionFilePath(assetsFolder + basePath + postFixLight); - let lightPathUri: vscode.Uri = vscode.Uri.file(lightPath); - let darkPath: string = util.getExtensionFilePath(assetsFolder + basePath + postFixDark); - let darkPathUri: vscode.Uri = vscode.Uri.file(darkPath); + const lightPath: string = util.getExtensionFilePath(assetsFolder + basePath + postFixLight); + const lightPathUri: vscode.Uri = vscode.Uri.file(lightPath); + const darkPath: string = util.getExtensionFilePath(assetsFolder + basePath + postFixDark); + const darkPathUri: vscode.Uri = vscode.Uri.file(darkPath); return { light: lightPathUri, dark: darkPathUri @@ -148,10 +148,10 @@ export function getReferenceTypeIconPath(referenceType: ReferenceType): { light: } function getReferenceCanceledIconPath(): { light: vscode.Uri; dark: vscode.Uri } { - let lightPath: string = util.getExtensionFilePath("assets/ref-canceled-light.svg"); - let lightPathUri: vscode.Uri = vscode.Uri.file(lightPath); - let darkPath: string = util.getExtensionFilePath("assets/ref-canceled-dark.svg"); - let darkPathUri: vscode.Uri = vscode.Uri.file(darkPath); + const lightPath: string = util.getExtensionFilePath("assets/ref-canceled-light.svg"); + const lightPathUri: vscode.Uri = vscode.Uri.file(lightPath); + const darkPath: string = util.getExtensionFilePath("assets/ref-canceled-dark.svg"); + const darkPathUri: vscode.Uri = vscode.Uri.file(darkPath); return { light: lightPathUri, dark: darkPathUri @@ -256,7 +256,7 @@ export class ReferencesManager { let numConfirmingReferences: number = 0; let numFinishedWithoutConfirming: number = 0; let numFinishedConfirming: number = 0; - for (let targetLocationProgress of this.referencesCurrentProgress.targetReferencesProgress) { + for (const targetLocationProgress of this.referencesCurrentProgress.targetReferencesProgress) { switch (targetLocationProgress) { case TargetReferencesProgress.WaitingToLex: ++numWaitingToLex; @@ -315,7 +315,7 @@ export class ReferencesManager { private handleProgressStarted(referencesProgress: ReferencesProgress): void { this.referencesStartedWhileTagParsing = this.client.IsTagParsing; - let mode: ReferencesCommandMode = + const mode: ReferencesCommandMode = (referencesProgress === ReferencesProgress.StartedRename) ? ReferencesCommandMode.Rename : (this.visibleRangesDecreased && (Date.now() - this.visibleRangesDecreasedTicks < this.ticksForDetectingPeek) ? ReferencesCommandMode.Peek : ReferencesCommandMode.Find); @@ -429,7 +429,7 @@ export class ReferencesManager { } if (this.referencesStartedWhileTagParsing) { - let msg: string = localize("some.references.may.be.missing", "[Warning] Some references may be missing, because workspace parsing was incomplete when {0} was started.", + const msg: string = localize("some.references.may.be.missing", "[Warning] Some references may be missing, because workspace parsing was incomplete when {0} was started.", referencesCommandModeToString(this.client.ReferencesCommandMode)); if (this.client.ReferencesCommandMode === ReferencesCommandMode.Peek) { if (this.referencesChannel) { @@ -438,7 +438,7 @@ export class ReferencesManager { this.referencesChannel.show(true); } } else if (this.client.ReferencesCommandMode === ReferencesCommandMode.Find) { - let logChannel: vscode.OutputChannel = logger.getOutputChannel(); + const logChannel: vscode.OutputChannel = logger.getOutputChannel(); logChannel.appendLine(msg); logChannel.appendLine(""); logChannel.show(true); @@ -447,12 +447,12 @@ export class ReferencesManager { // Need to reset these before we call the callback, as the callback my trigger another request // and we need to ensure these values are already reset before that happens. - let referencesRequestPending: boolean = this.referencesRequestPending; - let referencesCanceled: boolean = this.referencesCanceled; + const referencesRequestPending: boolean = this.referencesRequestPending; + const referencesCanceled: boolean = this.referencesCanceled; this.referencesRequestPending = false; this.referencesCanceled = false; - let currentReferenceCommandMode: ReferencesCommandMode = this.client.ReferencesCommandMode; + const currentReferenceCommandMode: ReferencesCommandMode = this.client.ReferencesCommandMode; if (referencesResult.isFinished) { this.symbolSearchInProgress = false; @@ -490,9 +490,9 @@ export class ReferencesManager { // Display data based on command mode: peek references OR find all references if (currentReferenceCommandMode === ReferencesCommandMode.Peek) { - let showConfirmedReferences: boolean = referencesCanceled; + const showConfirmedReferences: boolean = referencesCanceled; if (this.findAllRefsView) { - let peekReferencesResults: string = this.findAllRefsView.getResultsAsText(showConfirmedReferences); + const peekReferencesResults: string = this.findAllRefsView.getResultsAsText(showConfirmedReferences); if (peekReferencesResults) { if (this.referencesChannel) { this.referencesChannel.appendLine(peekReferencesResults); diff --git a/Extension/src/LanguageServer/referencesModel.ts b/Extension/src/LanguageServer/referencesModel.ts index 2542166316..237f1094c3 100644 --- a/Extension/src/LanguageServer/referencesModel.ts +++ b/Extension/src/LanguageServer/referencesModel.ts @@ -15,15 +15,15 @@ export class ReferencesModel { this.originalSymbol = resultsInput.text; this.groupByFile = groupByFile; - let results: ReferenceInfo[] = resultsInput.referenceInfos.filter(r => r.type !== ReferenceType.Confirmed); + const results: ReferenceInfo[] = resultsInput.referenceInfos.filter(r => r.type !== ReferenceType.Confirmed); // Build a single flat list of all leaf nodes // Currently, the hierarchy is built each time referencesTreeDataProvider requests nodes. - for (let r of results) { + for (const r of results) { // Add reference to file - let noReferenceLocation: boolean = (r.position.line === 0 && r.position.character === 0); + const noReferenceLocation: boolean = (r.position.line === 0 && r.position.character === 0); if (noReferenceLocation) { - let node: TreeNode = new TreeNode(this, NodeType.fileWithPendingRef); + const node: TreeNode = new TreeNode(this, NodeType.fileWithPendingRef); node.fileUri = vscode.Uri.file(r.file); node.filename = r.file; node.referenceType = r.type; @@ -32,7 +32,7 @@ export class ReferencesModel { const range: vscode.Range = new vscode.Range(r.position.line, r.position.character, r.position.line, r.position.character + this.originalSymbol.length); const uri: vscode.Uri = vscode.Uri.file(r.file); const location: vscode.Location = new vscode.Location(uri, range); - let node: TreeNode = new TreeNode(this, NodeType.reference); + const node: TreeNode = new TreeNode(this, NodeType.reference); node.fileUri = uri; node.filename = r.file; node.referencePosition = r.position; @@ -49,11 +49,11 @@ export class ReferencesModel { } getReferenceTypeNodes(): TreeNode[] { - let result: TreeNode[] = []; - for (let n of this.nodes) { - let i: number = result.findIndex(e => e.referenceType === n.referenceType); + const result: TreeNode[] = []; + for (const n of this.nodes) { + const i: number = result.findIndex(e => e.referenceType === n.referenceType); if (i < 0) { - let node: TreeNode = new TreeNode(this, NodeType.referenceType); + const node: TreeNode = new TreeNode(this, NodeType.referenceType); node.referenceType = n.referenceType; result.push(node); } @@ -62,7 +62,7 @@ export class ReferencesModel { } getFileNodes(refType?: ReferenceType): TreeNode[] { - let result: TreeNode[] = []; + const result: TreeNode[] = []; let filteredFiles: TreeNode[] = []; // Get files by reference type if refType is specified. @@ -73,11 +73,11 @@ export class ReferencesModel { } // Create new nodes per unique file - for (let n of filteredFiles) { - let i: number = result.findIndex(item => item.filename === n.filename); + for (const n of filteredFiles) { + const i: number = result.findIndex(item => item.filename === n.filename); if (i < 0) { - let nodeType: NodeType = (n.node === NodeType.fileWithPendingRef ? NodeType.fileWithPendingRef : NodeType.file); - let node: TreeNode = new TreeNode(this, nodeType); + const nodeType: NodeType = (n.node === NodeType.fileWithPendingRef ? NodeType.fileWithPendingRef : NodeType.file); + const node: TreeNode = new TreeNode(this, nodeType); node.filename = n.filename; node.fileUri = n.fileUri; node.referenceType = refType; @@ -118,7 +118,7 @@ export class ReferencesModel { } getAllFilesWithPendingReferenceNodes(): TreeNode[] { - let result: TreeNode[] = this.nodes.filter(i => i.node === NodeType.fileWithPendingRef); + const result: TreeNode[] = this.nodes.filter(i => i.node === NodeType.fileWithPendingRef); result.sort((a, b) => { if (a.filename === undefined) { if (b.filename === undefined) { diff --git a/Extension/src/LanguageServer/referencesTreeDataProvider.ts b/Extension/src/LanguageServer/referencesTreeDataProvider.ts index 6061b59874..4bcb6985f4 100644 --- a/Extension/src/LanguageServer/referencesTreeDataProvider.ts +++ b/Extension/src/LanguageServer/referencesTreeDataProvider.ts @@ -49,7 +49,7 @@ export class ReferencesTreeDataProvider implements vscode.TreeDataProvider(section: string, deprecatedSection: string): T { - let info: any = this.settings.inspect(section); + const info: any = this.settings.inspect(section); if (info.workspaceFolderValue !== undefined) { return info.workspaceFolderValue; } else if (info.workspaceValue !== undefined) { @@ -38,7 +38,7 @@ class Settings { } else if (info.globalValue !== undefined) { return info.globalValue; } - let value: T | undefined = this.settings.get(deprecatedSection); + const value: T | undefined = this.settings.get(deprecatedSection); if (value !== undefined) { return value; } @@ -46,7 +46,7 @@ class Settings { } protected getWithNullAsUndefined(section: string): T | undefined { - let result: T | undefined | null = this.settings.get(section); + const result: T | undefined | null = this.settings.get(section); if (result === null) { return undefined; } @@ -81,8 +81,8 @@ export class CppSettings extends Settings { // Attempt to invoke both our own version of clang-format to see if we can successfully execute it, and to get it's version. let clangFormatVersion: string; try { - let exePath: string = getExtensionFilePath(`./LLVM/bin/${this.clangFormatName}`); - let output: string[] = execSync(`${exePath} --version`).toString().split(" "); + const exePath: string = getExtensionFilePath(`./LLVM/bin/${this.clangFormatName}`); + const output: string[] = execSync(`${exePath} --version`).toString().split(" "); if (output.length < 3 || output[0] !== "clang-format" || output[1] !== "version" || !semver.valid(output[2])) { return path; } @@ -94,7 +94,7 @@ export class CppSettings extends Settings { // Invoke the version on the system to compare versions. Use ours if it's more recent. try { - let output: string[] = execSync(`"${path}" --version`).toString().split(" "); + const output: string[] = execSync(`"${path}" --version`).toString().split(" "); if (output.length < 3 || output[0] !== "clang-format" || output[1] !== "version" || semver.ltr(output[2], clangFormatVersion)) { path = ""; } @@ -126,6 +126,7 @@ export class CppSettings extends Settings { public get workspaceParsingPriority(): string | undefined { return super.Section.get("workspaceParsingPriority"); } public get workspaceSymbols(): string | undefined { return super.Section.get("workspaceSymbols"); } public get exclusionPolicy(): string | undefined { return super.Section.get("exclusionPolicy"); } + public get simplifyStructuredComments(): boolean | undefined { return super.Section.get("simplifyStructuredComments"); } public get commentContinuationPatterns(): (string | CommentPattern)[] | undefined { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); } public get configurationWarnings(): string | undefined { return super.Section.get("configurationWarnings"); } public get preferredPathSeparator(): string | undefined { return super.Section.get("preferredPathSeparator"); } @@ -140,7 +141,7 @@ export class CppSettings extends Settings { public get defaultForcedInclude(): string[] | undefined { return super.Section.get("default.forcedInclude"); } public get defaultIntelliSenseMode(): string | undefined { return super.Section.get("default.intelliSenseMode"); } public get defaultCompilerPath(): string | undefined { - let result: string | undefined | null = super.Section.get("default.compilerPath"); + const result: string | undefined | null = super.Section.get("default.compilerPath"); if (result === null) { return undefined; } @@ -172,7 +173,7 @@ export class CppSettings extends Settings { } public toggleSetting(name: string, value1: string, value2: string): void { - let value: string | undefined = super.Section.get(name); + const value: string | undefined = super.Section.get(name); super.Section.update(name, value === value1 ? value2 : value1, getTarget()); } diff --git a/Extension/src/LanguageServer/settingsPanel.ts b/Extension/src/LanguageServer/settingsPanel.ts index 81593c6ee2..c939c8f05c 100644 --- a/Extension/src/LanguageServer/settingsPanel.ts +++ b/Extension/src/LanguageServer/settingsPanel.ts @@ -160,7 +160,7 @@ export class SettingsPanel { public setKnownCompilers(knownCompilers?: config.KnownCompiler[], pathSeparator?: string): void { if (knownCompilers && knownCompilers.length) { - for (let compiler of knownCompilers) { + for (const compiler of knownCompilers) { // Normalize path separators. let path: string = compiler.path; if (pathSeparator === "Forward Slash") { @@ -274,7 +274,7 @@ export class SettingsPanel { } private updateConfig(message: any): void { - let splitEntries: (input: any) => string[] = (input: any) => input.split("\n").filter((e: string) => e); + const splitEntries: (input: any) => string[] = (input: any) => input.split("\n").filter((e: string) => e); switch (message.key) { case elementId.configName: diff --git a/Extension/src/LanguageServer/settingsTracker.ts b/Extension/src/LanguageServer/settingsTracker.ts index edcd4ea2a3..765c39fbad 100644 --- a/Extension/src/LanguageServer/settingsTracker.ts +++ b/Extension/src/LanguageServer/settingsTracker.ts @@ -26,12 +26,12 @@ export class SettingsTracker { } public getUserModifiedSettings(): { [key: string]: string } { - let filter: FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => !this.areEqual(val, settings.inspect(key)?.defaultValue); + const filter: FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => !this.areEqual(val, settings.inspect(key)?.defaultValue); return this.collectSettings(filter); } public getChangedSettings(): { [key: string]: string } { - let filter: FilterFunction = (key: string, val: string) => !(key in this.previousCppSettings) || !this.areEqual(val, this.previousCppSettings[key]); + const filter: FilterFunction = (key: string, val: string) => !(key in this.previousCppSettings) || !this.areEqual(val, this.previousCppSettings[key]); return this.collectSettings(filter); } @@ -40,7 +40,7 @@ export class SettingsTracker { const settingsNonScoped: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp"); const selectCorrectlyScopedSettings = (rawSetting: any): vscode.WorkspaceConfiguration => (!rawSetting || rawSetting.scope === "resource" || rawSetting.scope === "machine-overridable") ? settingsResourceScope : settingsNonScoped; - let result: { [key: string]: string } = {}; + const result: { [key: string]: string } = {}; for (const key in settingsResourceScope) { const rawSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key]; const correctlyScopedSettings: vscode.WorkspaceConfiguration = selectCorrectlyScopedSettings(rawSetting); @@ -48,7 +48,13 @@ export class SettingsTracker { if (val === undefined) { continue; } - if (val instanceof Object && !(val instanceof Array)) { + + // Iterate through dotted "sub" settings. + const collectSettingsRecursive = (key: string, val: Object, depth: number) => { + if (depth > 4) { + // Limit settings recursion to 4 dots (not counting the first one in: `C_Cpp.`) + return; + } for (const subKey in val) { const newKey: string = key + "." + subKey; const newRawSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + newKey]; @@ -57,11 +63,18 @@ export class SettingsTracker { if (subVal === undefined) { continue; } - const entry: KeyValuePair | undefined = this.filterAndSanitize(newKey, subVal, correctlyScopedSubSettings, filter); - if (entry && entry.key && entry.value) { - result[entry.key] = entry.value; + if (subVal instanceof Object && !(subVal instanceof Array)) { + collectSettingsRecursive(newKey, subVal, depth + 1); + } else { + const entry: KeyValuePair | undefined = this.filterAndSanitize(newKey, subVal, correctlyScopedSubSettings, filter); + if (entry && entry.key && entry.value) { + result[entry.key] = entry.value; + } } } + }; + if (val instanceof Object && !(val instanceof Array)) { + collectSettingsRecursive(key, val, 1); continue; } @@ -77,20 +90,20 @@ export class SettingsTracker { private getSetting(settings: vscode.WorkspaceConfiguration, key: string): any { // Ignore methods and settings that don't exist if (settings.inspect(key)?.defaultValue !== undefined) { - let val: any = settings.get(key); + const val: any = settings.get(key); if (val instanceof Object) { return val; // It's a sub-section. } // Only return values that match the setting's type and enum (if applicable). - let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key]; + const curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key]; if (curSetting) { - let type: string | undefined = this.typeMatch(val, curSetting["type"]); + const type: string | undefined = this.typeMatch(val, curSetting["type"]); if (type) { if (type !== "string") { return val; } - let curEnum: any[] = curSetting["enum"]; + const curEnum: any[] = curSetting["enum"]; if (curEnum && curEnum.indexOf(val) === -1) { return ""; } @@ -105,7 +118,7 @@ export class SettingsTracker { if (type) { if (type instanceof Array) { for (let i: number = 0; i < type.length; i++) { - let t: string = type[i]; + const t: string = type[i]; if (t) { if (typeof value === t) { return t; @@ -132,7 +145,7 @@ export class SettingsTracker { switch (key) { case "clang_format_style": case "clang_format_fallbackStyle": { - let newKey: string = key + "2"; + const newKey: string = key + "2"; if (val) { switch (String(val).toLowerCase()) { case "visual studio": @@ -158,6 +171,7 @@ export class SettingsTracker { break; } case "commentContinuationPatterns": { + key = "commentContinuationPatterns2"; value = this.areEqual(val, settings.inspect(key)?.defaultValue) ? "" : "..."; // Track whether it's being used, but nothing specific about it. break; } diff --git a/Extension/src/LanguageServer/ui.ts b/Extension/src/LanguageServer/ui.ts index 1649aaecbc..d0c2e0856e 100644 --- a/Extension/src/LanguageServer/ui.ts +++ b/Extension/src/LanguageServer/ui.ts @@ -157,14 +157,14 @@ export class UI { } public activeDocumentChanged(): void { - let activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; + const activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; if (!activeEditor) { this.ShowConfiguration = false; } else { - let isCpp: boolean = (activeEditor.document.uri.scheme === "file" && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c")); + const isCpp: boolean = (activeEditor.document.uri.scheme === "file" && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c")); // It's sometimes desirable to see the config and icons when making settings changes. - let isSettingsJson: boolean = ((activeEditor.document.fileName.endsWith("c_cpp_properties.json") || activeEditor.document.fileName.endsWith("settings.json"))); + const isSettingsJson: boolean = ((activeEditor.document.fileName.endsWith("c_cpp_properties.json") || activeEditor.document.fileName.endsWith("settings.json"))); this.ShowConfiguration = isCpp || isSettingsJson; } @@ -179,10 +179,10 @@ export class UI { } public showConfigurations(configurationNames: string[]): Thenable { - let options: vscode.QuickPickOptions = {}; + const options: vscode.QuickPickOptions = {}; options.placeHolder = localize("select.a.configuration", "Select a Configuration..."); - let items: IndexableQuickPickItem[] = []; + const items: IndexableQuickPickItem[] = []; for (let i: number = 0; i < configurationNames.length; i++) { items.push({ label: configurationNames[i], description: "", index: i }); } @@ -194,11 +194,11 @@ export class UI { } public showConfigurationProviders(currentProvider?: string): Thenable { - let options: vscode.QuickPickOptions = {}; + const options: vscode.QuickPickOptions = {}; options.placeHolder = localize("select.configuration.provider", "Select a Configuration Provider..."); - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + const providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); - let items: KeyedQuickPickItem[] = []; + const items: KeyedQuickPickItem[] = []; providers.forEach(provider => { let label: string = provider.name; if (isSameProviderExtensionId(currentProvider, provider.extensionId)) { @@ -213,10 +213,10 @@ export class UI { } public showCompileCommands(paths: string[]): Thenable { - let options: vscode.QuickPickOptions = {}; + const options: vscode.QuickPickOptions = {}; options.placeHolder = localize("select.compile.commands", "Select a compile_commands.json..."); - let items: IndexableQuickPickItem[] = []; + const items: IndexableQuickPickItem[] = []; for (let i: number = 0; i < paths.length; i++) { items.push({label: paths[i], description: "", index: i}); } @@ -226,10 +226,10 @@ export class UI { } public showWorkspaces(workspaceNames: { name: string; key: string }[]): Thenable { - let options: vscode.QuickPickOptions = {}; + const options: vscode.QuickPickOptions = {}; options.placeHolder = localize("select.workspace", "Select a workspace folder..."); - let items: KeyedQuickPickItem[] = []; + const items: KeyedQuickPickItem[] = []; workspaceNames.forEach(name => items.push({ label: name.name, description: "", key: name.key })); return vscode.window.showQuickPick(items, options) @@ -237,11 +237,10 @@ export class UI { } public showParsingCommands(): Thenable { - let options: vscode.QuickPickOptions = {}; + const options: vscode.QuickPickOptions = {}; options.placeHolder = localize("select.parsing.command", "Select a parsing command..."); - let items: IndexableQuickPickItem[]; - items = []; + const items: IndexableQuickPickItem[] = []; if (this.browseEngineStatusBarItem.tooltip === "Parsing paused") { items.push({ label: localize("resume.parsing", "Resume Parsing"), description: "", index: 1 }); } else { @@ -269,8 +268,8 @@ export class UI { } private showConfigurationPrompt(priority: ConfigurationPriority, prompt: () => Thenable, onSkip: () => void): void { - let showPrompt: () => Thenable = async () => { - let configured: boolean = await prompt(); + const showPrompt: () => Thenable = async () => { + const configured: boolean = await prompt(); return Promise.resolve({ priority: priority, configured: configured diff --git a/Extension/src/abTesting.ts b/Extension/src/abTesting.ts index 8b2ceeb520..155618b861 100644 --- a/Extension/src/abTesting.ts +++ b/Extension/src/abTesting.ts @@ -68,7 +68,7 @@ export class ABTestSettings { const exists: boolean = fs.existsSync(cpptoolsJsonFile); if (exists) { const fileContent: string = fs.readFileSync(cpptoolsJsonFile).toString(); - let newSettings: Settings = JSON.parse(fileContent); + const newSettings: Settings = JSON.parse(fileContent); this.intelliSenseEngineDefault.Value = util.isNumber(newSettings.defaultIntelliSenseEngine) ? newSettings.defaultIntelliSenseEngine : this.intelliSenseEngineDefault.DefaultValue; this.recursiveIncludesDefault.Value = util.isNumber(newSettings.recursiveIncludes) ? newSettings.recursiveIncludes : this.recursiveIncludesDefault.DefaultValue; this.gotoDefIntelliSenseDefault.Value = util.isNumber(newSettings.gotoDefIntelliSense) ? newSettings.gotoDefIntelliSense : this.gotoDefIntelliSenseDefault.DefaultValue; @@ -87,7 +87,7 @@ export class ABTestSettings { private downloadCpptoolsJsonPkgAsync(): Promise { let hasError: boolean = false; - let telemetryProperties: { [key: string]: string } = {}; + const telemetryProperties: { [key: string]: string } = {}; const localConfigPath: string = util.getExtensionFilePath(localConfigFile); return util.downloadFileToDestination("https://go.microsoft.com/fwlink/?linkid=2097702", localConfigPath) .catch((error) => { diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 5b9d06b6f2..16ca52cd82 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -84,7 +84,7 @@ export function getRawTasksJson(): Promise { } export async function ensureBuildTaskExists(taskName: string): Promise { - let rawTasksJson: any = await getRawTasksJson(); + const rawTasksJson: any = await getRawTasksJson(); // Ensure that the task exists in the user's task.json. Task will not be found otherwise. if (!rawTasksJson.tasks) { @@ -105,9 +105,9 @@ export async function ensureBuildTaskExists(taskName: string): Promise { rawTasksJson.version = "2.0.0"; - let selectedTask2: vscode.Task = selectedTask; + const selectedTask2: vscode.Task = selectedTask; if (!rawTasksJson.tasks.find((task: any) => task.label === selectedTask2.definition.label)) { - let task: any = { + const task: any = { ...selectedTask2.definition, problemMatcher: selectedTask2.problemMatchers, group: { kind: "build", "isDefault": true } @@ -116,8 +116,8 @@ export async function ensureBuildTaskExists(taskName: string): Promise { } // TODO: It's dangerous to overwrite this file. We could be wiping out comments. - let settings: OtherSettings = new OtherSettings(); - let tasksJsonPath: string | undefined = getTasksJsonPath(); + const settings: OtherSettings = new OtherSettings(); + const tasksJsonPath: string | undefined = getTasksJsonPath(); if (!tasksJsonPath) { throw new Error("Failed to get tasksJsonPath in ensureBuildTaskExists()"); } @@ -131,7 +131,7 @@ export function fileIsCOrCppSource(file: string): boolean { } export function isEditorFileCpp(file: string): boolean { - let editor: vscode.TextEditor | undefined = vscode.window.visibleTextEditors.find(e => e.document.uri.toString() === file); + const editor: vscode.TextEditor | undefined = vscode.window.visibleTextEditors.find(e => e.document.uri.toString() === file); if (!editor) { return false; } @@ -167,13 +167,13 @@ export function getTasksJsonPath(): string | undefined { export function getVcpkgPathDescriptorFile(): string { if (process.platform === 'win32') { - let pathPrefix: string | undefined = process.env.LOCALAPPDATA; + const pathPrefix: string | undefined = process.env.LOCALAPPDATA; if (!pathPrefix) { throw new Error("Unable to read process.env.LOCALAPPDATA"); } return path.join(pathPrefix, "vcpkg/vcpkg.path.txt"); } else { - let pathPrefix: string | undefined = process.env.HOME; + const pathPrefix: string | undefined = process.env.HOME; if (!pathPrefix) { throw new Error("Unable to read process.env.HOME"); } @@ -203,7 +203,7 @@ export function getVcpkgRoot(): string { * @param document The document to check. */ export function isHeader(uri: vscode.Uri): boolean { - let ext: string = path.extname(uri.fsPath); + const ext: string = path.extname(uri.fsPath); return !ext || ext.startsWith(".h") || ext.startsWith(".H"); } @@ -242,8 +242,8 @@ const progressIntelliSenseNoSquiggles: number = 1000; // Might add more IntelliSense progress measurements later. // IntelliSense progress is separate from the install progress, because parse root can occur afterwards. -let installProgressStr: string = "CPP." + packageJson.version + ".Progress"; -let intelliSenseProgressStr: string = "CPP." + packageJson.version + ".IntelliSenseProgress"; +const installProgressStr: string = "CPP." + packageJson.version + ".Progress"; +const intelliSenseProgressStr: string = "CPP." + packageJson.version + ".IntelliSenseProgress"; export function getProgress(): number { return extensionContext ? extensionContext.globalState.get(installProgressStr, -1) : -1; @@ -256,7 +256,7 @@ export function getIntelliSenseProgress(): number { export function setProgress(progress: number): void { if (extensionContext && getProgress() < progress) { extensionContext.globalState.update(installProgressStr, progress); - let telemetryProperties: { [key: string]: string } = {}; + const telemetryProperties: { [key: string]: string } = {}; let progressName: string | undefined; switch (progress) { case 0: progressName = "install started"; break; @@ -275,7 +275,7 @@ export function setProgress(progress: number): void { export function setIntelliSenseProgress(progress: number): void { if (extensionContext && getIntelliSenseProgress() < progress) { extensionContext.globalState.update(intelliSenseProgressStr, progress); - let telemetryProperties: { [key: string]: string } = {}; + const telemetryProperties: { [key: string]: string } = {}; let progressName: string | undefined; switch (progress) { case progressIntelliSenseNoSquiggles: progressName = "IntelliSense no squiggles"; break; @@ -346,7 +346,7 @@ export function resolveVariables(input: string | undefined, additionalEnvironmen // Replace environment and configuration variables. let regexp: () => RegExp = () => /\$\{((env|config|workspaceFolder)(\.|:))?(.*?)\}/g; let ret: string = input; - let cycleCache: Set = new Set(); + const cycleCache: Set = new Set(); while (!cycleCache.has(ret)) { cycleCache.add(ret); ret = ret.replace(regexp(), (match: string, ignored1: string, varType: string, ignored2: string, name: string) => { @@ -359,7 +359,7 @@ export function resolveVariables(input: string | undefined, additionalEnvironmen switch (varType) { case "env": { if (additionalEnvironment) { - let v: string | string[] | undefined = additionalEnvironment[name]; + const v: string | string[] | undefined = additionalEnvironment[name]; if (isString(v)) { newValue = v; } else if (input === match && isArrayOfString(v)) { @@ -372,7 +372,7 @@ export function resolveVariables(input: string | undefined, additionalEnvironmen break; } case "config": { - let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); + const config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(); if (config) { newValue = config.get(name); } @@ -383,7 +383,7 @@ export function resolveVariables(input: string | undefined, additionalEnvironmen // We may consider doing replacement of ${workspaceFolder} here later, but we would have to update the language server and also // intercept messages with paths in them and add the ${workspaceFolder} variable back in (e.g. for light bulb suggestions) if (name && vscode.workspace && vscode.workspace.workspaceFolders) { - let folder: vscode.WorkspaceFolder | undefined = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase()); + const folder: vscode.WorkspaceFolder | undefined = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase()); if (folder) { newValue = folder.uri.fsPath; } @@ -399,7 +399,7 @@ export function resolveVariables(input: string | undefined, additionalEnvironmen // Resolve '~' at the start of the path. regexp = () => /^\~/g; ret = ret.replace(regexp(), (match: string, name: string) => { - let newValue: string | undefined = (process.platform === 'win32') ? process.env.USERPROFILE : process.env.HOME; + const newValue: string | undefined = (process.platform === 'win32') ? process.env.USERPROFILE : process.env.HOME; return newValue ? newValue : match; }); @@ -441,13 +441,13 @@ export function getHttpsProxyAgent(): HttpsProxyAgent | undefined { } // Basic sanity checking on proxy url - let proxyUrl: any = url.parse(proxy); + const proxyUrl: any = url.parse(proxy); if (proxyUrl.protocol !== "https:" && proxyUrl.protocol !== "http:") { return undefined; } - let strictProxy: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true); - let proxyOptions: any = { + const strictProxy: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true); + const proxyOptions: any = { host: proxyUrl.hostname, port: parseInt(proxyUrl.port, 10), auth: proxyUrl.auth, @@ -663,14 +663,14 @@ export function spawnChildProcess(process: string, args: string[], workingDirect return new Promise(function (resolve, reject): void { const child: child_process.ChildProcess = child_process.spawn(process, args, { cwd: workingDirectory }); - let stdout: Readable | null = child.stdout; + const stdout: Readable | null = child.stdout; if (stdout) { stdout.on('data', (data) => { dataCallback(`${data}`); }); } - let stderr: Readable | null = child.stderr; + const stderr: Readable | null = child.stderr; if (stderr) { stderr.on('data', (data) => { errorCallback(`${data}`); @@ -730,9 +730,9 @@ export function allowExecution(file: string): Promise { } export function removePotentialPII(str: string): string { - let words: string[] = str.split(" "); + const words: string[] = str.split(" "); let result: string = ""; - for (let word of words) { + for (const word of words) { if (word.indexOf(".") === -1 && word.indexOf("/") === -1 && word.indexOf("\\") === -1 && word.indexOf(":") === -1) { result += word + " "; } else { @@ -777,7 +777,7 @@ export function promptForReloadWindowDueToSettingsChange(): void { } export function promptReloadWindow(message: string): void { - let reload: string = localize("reload.string", "Reload"); + const reload: string = localize("reload.string", "Reload"); vscode.window.showInformationMessage(message, reload).then((value?: string) => { if (value === reload) { vscode.commands.executeCommand("workbench.action.reloadWindow"); @@ -798,8 +798,8 @@ export function createTempFileWithPostfix(postfix: string): Promise { return new Promise((resolve, reject) => { - let parsedUrl: url.Url = url.parse(urlStr); - let request: ClientRequest = https.request({ + const parsedUrl: url.Url = url.parse(urlStr); + const request: ClientRequest = https.request({ host: parsedUrl.host, path: parsedUrl.path, agent: getHttpsProxyAgent(), @@ -823,7 +823,7 @@ export function downloadFileToDestination(urlStr: string, destinationPath: strin return reject(); } // Write file using downloaded data - let createdFile: fs.WriteStream = fs.createWriteStream(destinationPath); + const createdFile: fs.WriteStream = fs.createWriteStream(destinationPath); createdFile.on('finish', () => { resolve(); }); response.on('error', (error) => { reject(error); }); response.pipe(createdFile); @@ -835,8 +835,8 @@ export function downloadFileToDestination(urlStr: string, destinationPath: strin export function downloadFileToStr(urlStr: string, headers?: OutgoingHttpHeaders): Promise { return new Promise((resolve, reject) => { - let parsedUrl: url.Url = url.parse(urlStr); - let request: ClientRequest = https.request({ + const parsedUrl: url.Url = url.parse(urlStr); + const request: ClientRequest = https.request({ host: parsedUrl.host, path: parsedUrl.path, agent: getHttpsProxyAgent(), @@ -876,13 +876,13 @@ export interface CompilerPathAndArgs { } function extractArgs(argsString: string): string[] { - let isWindows: boolean = os.platform() === 'win32'; - let result: string[] = []; + const isWindows: boolean = os.platform() === 'win32'; + const result: string[] = []; let currentArg: string = ""; let isWithinDoubleQuote: boolean = false; let isWithinSingleQuote: boolean = false; for (let i: number = 0; i < argsString.length; i++) { - let c: string = argsString[i]; + const c: string = argsString[i]; if (c === '\\') { currentArg += c; if (++i === argsString.length) { @@ -926,7 +926,7 @@ export function extractCompilerPathAndArgs(inputCompilerPath?: string, inputComp let compilerPath: string | undefined = inputCompilerPath; let compilerName: string = ""; let additionalArgs: string[] = []; - let isWindows: boolean = os.platform() === 'win32'; + const isWindows: boolean = os.platform() === 'win32'; if (compilerPath) { if (compilerPath.endsWith("\\cl.exe") || compilerPath.endsWith("/cl.exe") || compilerPath === "cl.exe") { // Input is only compiler name, this is only for cl.exe @@ -934,7 +934,7 @@ export function extractCompilerPathAndArgs(inputCompilerPath?: string, inputComp } else if (compilerPath.startsWith("\"")) { // Input has quotes around compiler path - let endQuote: number = compilerPath.substr(1).search("\"") + 1; + const endQuote: number = compilerPath.substr(1).search("\"") + 1; if (endQuote !== -1) { additionalArgs = extractArgs(compilerPath.substr(endQuote + 1)); compilerPath = compilerPath.substr(1, endQuote - 1); @@ -1018,10 +1018,10 @@ export class BlockingTask { this.promise = task(); } else { this.promise = new Promise((resolve, reject) => { - let f1: () => void = () => { + const f1: () => void = () => { task().then(resolve, reject); }; - let f2: (err: any) => void = (err) => { + const f2: (err: any) => void = (err) => { console.log(err); task().then(resolve, reject); }; @@ -1050,9 +1050,9 @@ interface VSCodeNlsConfig { export function getLocaleId(): string { // This replicates the language detection used by initializeSettings() in vscode-nls if (isString(process.env.VSCODE_NLS_CONFIG)) { - let vscodeOptions: VSCodeNlsConfig = JSON.parse(process.env.VSCODE_NLS_CONFIG) as VSCodeNlsConfig; + const vscodeOptions: VSCodeNlsConfig = JSON.parse(process.env.VSCODE_NLS_CONFIG) as VSCodeNlsConfig; if (vscodeOptions.availableLanguages) { - let value: any = vscodeOptions.availableLanguages['*']; + const value: any = vscodeOptions.availableLanguages['*']; if (isString(value)) { return value; } @@ -1065,8 +1065,8 @@ export function getLocaleId(): string { } export function getLocalizedHtmlPath(originalPath: string): string { - let locale: string = getLocaleId(); - let localizedFilePath: string = getExtensionFilePath(path.join("dist/html/", locale, originalPath)); + const locale: string = getLocaleId(); + const localizedFilePath: string = getExtensionFilePath(path.join("dist/html/", locale, originalPath)); if (!fs.existsSync(localizedFilePath)) { return getExtensionFilePath(originalPath); } @@ -1093,9 +1093,9 @@ export function getLocalizedString(params: LocalizeStringParams): string { } function decodeUCS16(input: string): number[] { - let output: number[] = []; + const output: number[] = []; let counter: number = 0; - let length: number = input.length; + const length: number = input.length; let value: number; let extra: number; while (counter < length) { @@ -1118,7 +1118,7 @@ function decodeUCS16(input: string): number[] { return output; } -let allowedIdentifierUnicodeRanges: number[][] = [ +const allowedIdentifierUnicodeRanges: number[][] = [ [0x0030, 0x0039], // digits [0x0041, 0x005A], // upper case letters [0x005F, 0x005F], // underscore @@ -1167,7 +1167,7 @@ let allowedIdentifierUnicodeRanges: number[][] = [ [0xE0000, 0xEFFFD] // LANGUAGE TAG (U+E0001) - VARIATION SELECTOR-256 (U+E01EF) ]; -let disallowedFirstCharacterIdentifierUnicodeRanges: number[][] = [ +const disallowedFirstCharacterIdentifierUnicodeRanges: number[][] = [ [0x0030, 0x0039], // digits [0x0300, 0x036F], // COMBINING GRAVE ACCENT - COMBINING LATIN SMALL LETTER X [0x1DC0, 0x1DFF], // COMBINING DOTTED GRAVE ACCENT - COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW @@ -1179,14 +1179,14 @@ export function isValidIdentifier(candidate: string): boolean { if (!candidate) { return false; } - let decoded: number[] = decodeUCS16(candidate); + const decoded: number[] = decodeUCS16(candidate); if (!decoded || !decoded.length) { return false; } // Reject if first character is disallowed for (let i: number = 0; i < disallowedFirstCharacterIdentifierUnicodeRanges.length; i++) { - let disallowedCharacters: number[] = disallowedFirstCharacterIdentifierUnicodeRanges[i]; + const disallowedCharacters: number[] = disallowedFirstCharacterIdentifierUnicodeRanges[i]; if (decoded[0] >= disallowedCharacters[0] && decoded[0] <= disallowedCharacters[1]) { return false; } @@ -1195,7 +1195,7 @@ export function isValidIdentifier(candidate: string): boolean { for (let position: number = 0; position < decoded.length; position++) { let found: boolean = false; for (let i: number = 0; i < allowedIdentifierUnicodeRanges.length; i++) { - let allowedCharacters: number[] = allowedIdentifierUnicodeRanges[i]; + const allowedCharacters: number[] = allowedIdentifierUnicodeRanges[i]; if (decoded[position] >= allowedCharacters[0] && decoded[position] <= allowedCharacters[1]) { found = true; break; @@ -1209,7 +1209,7 @@ export function isValidIdentifier(candidate: string): boolean { } function getUniqueWorkspaceNameHelper(workspaceFolder: vscode.WorkspaceFolder, addSubfolder: boolean): string { - let workspaceFolderName: string = workspaceFolder ? workspaceFolder.name : "untitled"; + const workspaceFolderName: string = workspaceFolder ? workspaceFolder.name : "untitled"; if (!workspaceFolder || workspaceFolder.index < 1) { return workspaceFolderName; // No duplicate names to search for. } diff --git a/Extension/src/cppTools.ts b/Extension/src/cppTools.ts index c9d63b1c45..8092b0591c 100644 --- a/Extension/src/cppTools.ts +++ b/Extension/src/cppTools.ts @@ -34,7 +34,7 @@ export class CppTools implements CppToolsTestApi { private addNotifyReadyTimer(provider: CustomConfigurationProvider1): void { if (this.version >= Version.v2) { const timeout: number = 30; - let timer: NodeJS.Timer = global.setTimeout(() => { + const timer: NodeJS.Timer = global.setTimeout(() => { console.warn(`registered provider ${provider.extensionId} did not call 'notifyReady' within ${timeout} seconds`); }, timeout * 1000); this.timers.set(provider.extensionId, timer); @@ -43,7 +43,7 @@ export class CppTools implements CppToolsTestApi { private removeNotifyReadyTimer(provider: CustomConfigurationProvider1): void { if (this.version >= Version.v2) { - let timer: NodeJS.Timer | undefined = this.timers.get(provider.extensionId); + const timer: NodeJS.Timer | undefined = this.timers.get(provider.extensionId); if (timer) { this.timers.delete(provider.extensionId); clearTimeout(timer); @@ -56,11 +56,11 @@ export class CppTools implements CppToolsTestApi { } public registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void { - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + const providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); if (providers.add(provider, this.version)) { const added: CustomConfigurationProvider1 | undefined = providers.get(provider); if (added) { - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.loggingLevel === "Information" || settings.loggingLevel === "Debug") { getOutputChannel().appendLine(localize("provider.registered", "Custom configuration provider '{0}' registered", added.name)); } @@ -74,8 +74,8 @@ export class CppTools implements CppToolsTestApi { } public notifyReady(provider: CustomConfigurationProvider): void { - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); - let p: CustomConfigurationProvider1 | undefined = providers.get(provider); + const providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + const p: CustomConfigurationProvider1 | undefined = providers.get(provider); if (p) { this.removeNotifyReadyTimer(p); @@ -92,8 +92,8 @@ export class CppTools implements CppToolsTestApi { } public didChangeCustomConfiguration(provider: CustomConfigurationProvider): void { - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); - let p: CustomConfigurationProvider1 | undefined = providers.get(provider); + const providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + const p: CustomConfigurationProvider1 | undefined = providers.get(provider); if (p) { if (!p.isReady) { @@ -108,8 +108,8 @@ export class CppTools implements CppToolsTestApi { } public didChangeCustomBrowseConfiguration(provider: CustomConfigurationProvider): void { - let providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); - let p: CustomConfigurationProvider1 | undefined = providers.get(provider); + const providers: CustomConfigurationProviderCollection = getCustomConfigProviders(); + const p: CustomConfigurationProvider1 | undefined = providers.get(provider); if (p) { LanguageServer.getClients().forEach(client => client.updateCustomBrowseConfiguration(p)); diff --git a/Extension/src/githubAPI.ts b/Extension/src/githubAPI.ts index 00ca5b26f9..aa4c048aaf 100644 --- a/Extension/src/githubAPI.ts +++ b/Extension/src/githubAPI.ts @@ -126,10 +126,11 @@ export interface BuildInfo { /** * Use the GitHub API to retrieve the download URL of the extension version the user should update to, if any. * @param updateChannel The user's updateChannel setting. + * @param isFromSettingsChange True if the invocation is the result of a settings change. * @return Download URL for the extension VSIX package that the user should install. If the user * does not need to update, resolves to undefined. */ -export async function getTargetBuildInfo(updateChannel: string): Promise { +export async function getTargetBuildInfo(updateChannel: string, isFromSettingsChange: boolean): Promise { return getReleaseJson() .then(builds => { if (!builds || builds.length === 0) { @@ -144,7 +145,7 @@ export async function getTargetBuildInfo(updateChannel: string): Promise("autoUpdate")) { +export function getTargetBuild(builds: Build[], userVersion: PackageVersion, updateChannel: string, isFromSettingsChange: boolean): Build | undefined { + if (!isFromSettingsChange && !vscode.workspace.getConfiguration("extensions", null).get("autoUpdate")) { return undefined; } const latestVersion: PackageVersion = new PackageVersion(builds[0].name); diff --git a/Extension/src/linuxDistribution.ts b/Extension/src/linuxDistribution.ts index 3f99ee9627..dd38f114ec 100644 --- a/Extension/src/linuxDistribution.ts +++ b/Extension/src/linuxDistribution.ts @@ -16,11 +16,9 @@ export class LinuxDistribution { * https://www.freedesktop.org/software/systemd/man/os-release.html */ public static GetDistroInformation(): Promise { - let linuxDistro: Promise; - // First check /etc/os-release and only fallback to /usr/lib/os-release // as per the os-release documentation. - linuxDistro = LinuxDistribution.getDistroInformationFromFile('/etc/os-release') + const linuxDistro: Promise = LinuxDistribution.getDistroInformationFromFile('/etc/os-release') .catch(() => LinuxDistribution.getDistroInformationFromFile('/usr/lib/os-release')) .catch(() => Promise.resolve(new LinuxDistribution('unknown', 'unknown'))); // couldn't get distro information; return linuxDistro; @@ -45,9 +43,9 @@ export class LinuxDistribution { let distroName: string = 'unknown'; let distroVersion: string = 'unknown'; - let keyValues: string[] = data.split(os.EOL); + const keyValues: string[] = data.split(os.EOL); for (let i: number = 0; i < keyValues.length; i++) { - let keyValue: string[] = keyValues[i].split('='); + const keyValue: string[] = keyValues[i].split('='); if (keyValue.length === 2) { if (keyValue[0] === idKey) { distroName = keyValue[1]; diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 236c0492f2..d309f0c5d7 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -31,7 +31,7 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle(); const cppTools: CppTools1 = new CppTools1(); let languageServiceDisabled: boolean = false; let reloadMessageShown: boolean = false; -let disposables: vscode.Disposable[] = []; +const disposables: vscode.Disposable[] = []; export async function activate(context: vscode.ExtensionContext): Promise { let errMsg: string = ""; @@ -54,8 +54,8 @@ export async function activate(context: vscode.ExtensionContext): Promise { console.assert(uri.path[0] === '/', "A preceeding slash is expected on schema uri path"); - let fileName: string = uri.path.substr(1); - let locale: string = util.getLocaleId(); + const fileName: string = uri.path.substr(1); + const locale: string = util.getLocaleId(); let localizedFilePath: string = util.getExtensionFilePath(path.join("dist/schema/", locale, fileName)); const fileExists: boolean = await util.checkFileExists(localizedFilePath); if (!fileExists) { @@ -73,7 +73,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { } async function downloadAndInstallPackages(info: PlatformInformation): Promise { - let outputChannelLogger: Logger = getOutputChannelLogger(); + const outputChannelLogger: Logger = getOutputChannelLogger(); outputChannelLogger.appendLine(localize("updating.dependencies", "Updating C/C++ dependencies...")); - let packageManager: PackageManager = new PackageManager(info, outputChannelLogger); + const packageManager: PackageManager = new PackageManager(info, outputChannelLogger); return vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, @@ -244,8 +244,8 @@ function invalidPackageVersion(pkg: IPackage, info: PlatformInformation): boolea } function makeOfflineBinariesExecutable(info: PlatformInformation): Promise { - let promises: Thenable[] = []; - let packages: IPackage[] = util.packageJson["runtimeDependencies"]; + const promises: Thenable[] = []; + const packages: IPackage[] = util.packageJson["runtimeDependencies"]; packages.forEach(p => { if (p.binaries && p.binaries.length > 0 && packageMatchesPlatform(p, info)) { @@ -256,8 +256,8 @@ function makeOfflineBinariesExecutable(info: PlatformInformation): Promise } function cleanUpUnusedBinaries(info: PlatformInformation): Promise { - let promises: Thenable[] = []; - let packages: IPackage[] = util.packageJson["runtimeDependencies"]; + const promises: Thenable[] = []; + const packages: IPackage[] = util.packageJson["runtimeDependencies"]; const logger: Logger = getOutputChannelLogger(); packages.forEach(p => { @@ -277,7 +277,7 @@ function cleanUpUnusedBinaries(info: PlatformInformation): Promise { function removeUnnecessaryFile(): Promise { if (os.platform() !== 'win32') { - let sourcePath: string = util.getDebugAdaptersPath("bin/OpenDebugAD7.exe.config"); + const sourcePath: string = util.getDebugAdaptersPath("bin/OpenDebugAD7.exe.config"); if (fs.existsSync(sourcePath)) { fs.rename(sourcePath, util.getDebugAdaptersPath("bin/OpenDebugAD7.exe.config.unused"), (err: NodeJS.ErrnoException | null) => { if (err) { @@ -296,13 +296,13 @@ function touchInstallLockFile(): Promise { } function handleError(error: any): void { - let installationInformation: InstallationInformation = getInstallationInformation(); + const installationInformation: InstallationInformation = getInstallationInformation(); installationInformation.hasError = true; installationInformation.telemetryProperties['stage'] = installationInformation.stage ?? ""; let errorMessage: string; if (error instanceof PackageManagerError) { - let packageError: PackageManagerError = error; + const packageError: PackageManagerError = error; installationInformation.telemetryProperties['error.methodName'] = packageError.methodName; installationInformation.telemetryProperties['error.message'] = packageError.message; @@ -327,7 +327,7 @@ function handleError(error: any): void { installationInformation.telemetryProperties['error.toString'] = util.removePotentialPII(errorMessage); } - let outputChannelLogger: Logger = getOutputChannelLogger(); + const outputChannelLogger: Logger = getOutputChannelLogger(); if (installationInformation.stage === 'downloadPackages') { outputChannelLogger.appendLine(""); } @@ -340,7 +340,7 @@ function handleError(error: any): void { } function sendTelemetry(info: PlatformInformation): boolean { - let installBlob: InstallationInformation = getInstallationInformation(); + const installBlob: InstallationInformation = getInstallationInformation(); const success: boolean = !installBlob.hasError; installBlob.telemetryProperties['success'] = success.toString(); @@ -363,7 +363,7 @@ function sendTelemetry(info: PlatformInformation): boolean { } async function postInstall(info: PlatformInformation): Promise { - let outputChannelLogger: Logger = getOutputChannelLogger(); + const outputChannelLogger: Logger = getOutputChannelLogger(); outputChannelLogger.appendLine(""); outputChannelLogger.appendLine(localize('finished.installing.dependencies', "Finished installing dependencies")); outputChannelLogger.appendLine(""); @@ -382,7 +382,7 @@ async function postInstall(info: PlatformInformation): Promise { } async function finalizeExtensionActivation(): Promise { - let settings: CppSettings = new CppSettings(); + const settings: CppSettings = new CppSettings(); if (settings.intelliSenseEngine === "Disabled") { languageServiceDisabled = true; getTemporaryCommandRegistrarInstance().disableLanguageServer(); @@ -402,9 +402,9 @@ async function finalizeExtensionActivation(): Promise { })); getTemporaryCommandRegistrarInstance().activateLanguageServer(); - let packageJson: any = util.getRawPackageJson(); + const packageJson: any = util.getRawPackageJson(); let writePackageJson: boolean = false; - let packageJsonPath: string = util.getExtensionFilePath("package.json"); + const packageJsonPath: string = util.getExtensionFilePath("package.json"); if (packageJsonPath.includes(".vscode-insiders") || packageJsonPath.includes(".vscode-exploration")) { if (packageJson.contributes.configuration.properties['C_Cpp.updateChannel'].default === 'Default') { packageJson.contributes.configuration.properties['C_Cpp.updateChannel'].default = 'Insiders'; @@ -419,7 +419,7 @@ async function finalizeExtensionActivation(): Promise { function rewriteManifest(): Promise { // Replace activationEvents with the events that the extension should be activated for subsequent sessions. - let packageJson: any = util.getRawPackageJson(); + const packageJson: any = util.getRawPackageJson(); packageJson.activationEvents = [ "onLanguage:cpp", @@ -442,7 +442,9 @@ function rewriteManifest(): Promise { "onCommand:C_Cpp.RescanWorkspace", "onCommand:C_Cpp.VcpkgClipboardInstallSuggested", "onCommand:C_Cpp.VcpkgClipboardOnlineHelpSuggested", - "onDebug", + "onDebugInitialConfigurations", + "onDebugResolve:cppdbg", + "onDebugResolve:cppvsdbg", "workspaceContains:/.vscode/c_cpp_properties.json", "onFileSystem:cpptools-schema" ]; diff --git a/Extension/src/nativeStrings.json b/Extension/src/nativeStrings.json index b6ea3dd5a7..2376f363d6 100644 --- a/Extension/src/nativeStrings.json +++ b/Extension/src/nativeStrings.json @@ -158,5 +158,37 @@ "fallback_to_no_bitness": "Failed to query compiler. Falling back to no bitness.", "intellisense_client_creation_aborted": "IntelliSense client creation aborted: {0}", "include_errors_config_provider_intellisense_disabled ": "#include errors detected based on information provided by the configurationProvider setting. IntelliSense features for this translation unit ({0}) will be provided by the Tag Parser.", - "include_errors_config_provider_squiggles_disabled ": "#include errors detected based on information provided by the configurationProvider setting. Squiggles are disabled for this translation unit ({0})." + "include_errors_config_provider_squiggles_disabled ": "#include errors detected based on information provided by the configurationProvider setting. Squiggles are disabled for this translation unit ({0}).", + "preprocessor_keyword": { + "text": "preprocessor keyword", + "hint": "Refers to C/C++ processor keywords" + }, + "c_keyword": "C keyword", + "cpp_keyword": "C++ keyword", + "overload": { + "text": "+1 overload", + "hint": "Refers to 'overloaded' function in C++. This is part of a description indicating there is 1 additional overload of a specified function." + }, + "overloads": { + "text": "+%d overloads", + "hint": "Refers to 'overloaded' functions in C++. This is part of a description indicating there are N additional overloads of a specified function. %d is replaced with that number." + }, + "specialization": { + "text": "+1 specialization", + "hint": "Refers to a C++ template specialization. This is part of a description indicating there is 1 additional specialization of a function." + }, + "specializations": { + "text": "+%d specializations", + "hint": "Refers to C++ template specializations. This is part of a description indicating there are N additional specializations of a function. %d is replaced with that number." + }, + "expands_to": "Expands to:", + "file_label": "File:", + "parameters_label": "Parameters:", + "returns_label": { + "text": "Returns:", + "hint": "This label is for the return value description for a function. Usage example: 'Returns: Area of a shape.'" + }, + "deprecated_label": "Deprecated:", + "exceptions_label": "Exceptions:", + "template_parameters_label": "Template Parameters:" } diff --git a/Extension/src/packageManager.ts b/Extension/src/packageManager.ts index 8229b26cf5..1f3d9c4054 100644 --- a/Extension/src/packageManager.ts +++ b/Extension/src/packageManager.ts @@ -119,7 +119,7 @@ export class PackageManager { private BuildPromiseChain(items: TItem[], promiseBuilder: (item: TItem) => Promise): Promise { let promiseChain: Promise = Promise.resolve(null); - for (let item of items) { + for (const item of items) { promiseChain = promiseChain.then(() => promiseBuilder(item)); } @@ -133,7 +133,7 @@ export class PackageManager { this.allPackages = util.packageJson.runtimeDependencies; // Convert relative binary paths to absolute - for (let pkg of this.allPackages) { + for (const pkg of this.allPackages) { if (pkg.binaries) { pkg.binaries = pkg.binaries.map((value) => util.getExtensionFilePath(value)); } @@ -210,10 +210,10 @@ export class PackageManager { this.AppendLineChannel(" " + localize("done", "Done!")); if (retryCount !== 0) { // Log telemetry to see if retrying helps. - let telemetryProperties: { [key: string]: string } = {}; + const telemetryProperties: { [key: string]: string } = {}; telemetryProperties["success"] = success ? `OnRetry${retryCount}` : 'false'; if (lastError instanceof PackageManagerError) { - let packageError: PackageManagerError = lastError; + const packageError: PackageManagerError = lastError; telemetryProperties['error.methodName'] = packageError.methodName; telemetryProperties['error.message'] = packageError.message; if (packageError.pkg) { @@ -230,10 +230,10 @@ export class PackageManager { // reloadCpptoolsJson in main.ts uses ~25% of this function. private DownloadFile(urlString: any, pkg: IPackage, delay: number, progress: vscode.Progress<{message?: string; increment?: number}>): Promise { - let parsedUrl: url.Url = url.parse(urlString); - let proxyStrictSSL: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true); + const parsedUrl: url.Url = url.parse(urlString); + const proxyStrictSSL: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true); - let options: https.RequestOptions = { + const options: https.RequestOptions = { host: parsedUrl.host, path: parsedUrl.path, agent: util.getHttpsProxyAgent(), @@ -253,7 +253,7 @@ export class PackageManager { return reject(new PackageManagerError('Temporary Package file unavailable', localize("temp.package.unavailable", 'Temporary Package file unavailable'), 'DownloadFile', pkg)); } - let handleHttpResponse: (response: IncomingMessage) => void = (response: IncomingMessage) => { + const handleHttpResponse: (response: IncomingMessage) => void = (response: IncomingMessage) => { if (response.statusCode === 301 || response.statusCode === 302) { // Redirect - download from new location let redirectUrl: string | string[]; @@ -271,7 +271,7 @@ export class PackageManager { return reject(new PackageManagerError('Invalid response code received', localize("invalid.response.code.received", 'Invalid response code received'), 'DownloadFile', pkg)); } // Download failed - print error message - let errorMessage: string = localize("failed.web.error", "failed (error code '{0}')", response.statusCode); + const errorMessage: string = localize("failed.web.error", "failed (error code '{0}')", response.statusCode); return reject(new PackageManagerWebResponseError(response.socket, 'HTTP/HTTPS Response Error', localize("web.response.error", 'HTTP/HTTPS Response Error'), 'DownloadFile', pkg, errorMessage, response.statusCode.toString())); } else { // Downloading - hook up events @@ -284,16 +284,16 @@ export class PackageManager { } contentLength = response.headers['content-length'][0]; } - let packageSize: number = parseInt(contentLength, 10); - let downloadPercentage: number = 0; + const packageSize: number = parseInt(contentLength, 10); + const downloadPercentage: number = 0; let dots: number = 0; - let tmpFile: fs.WriteStream = fs.createWriteStream("", { fd: pkg.tmpFile.fd }); + const tmpFile: fs.WriteStream = fs.createWriteStream("", { fd: pkg.tmpFile.fd }); this.AppendChannel(`(${Math.ceil(packageSize / 1024)} KB) `); response.on('data', (data) => { // Update dots after package name in output console - let newDots: number = Math.ceil(downloadPercentage / 5); + const newDots: number = Math.ceil(downloadPercentage / 5); if (newDots > dots) { this.AppendChannel(".".repeat(newDots - dots)); dots = newDots; @@ -310,7 +310,7 @@ export class PackageManager { } }; - let request: ClientRequest = https.request(options, handleHttpResponse); + const request: ClientRequest = https.request(options, handleHttpResponse); request.on('error', (error) => reject(new PackageManagerError( @@ -347,7 +347,7 @@ export class PackageManager { zipfile.readEntry(); zipfile.on('entry', (entry: yauzl.Entry) => { - let absoluteEntryPath: string = util.getExtensionFilePath(entry.fileName); + const absoluteEntryPath: string = util.getExtensionFilePath(entry.fileName); if (entry.fileName.endsWith("/")) { // Directory - create it @@ -377,7 +377,7 @@ export class PackageManager { // Create as a .tmp file to avoid partially unzipped files // counting as completed files. - let absoluteEntryTempFile: string = absoluteEntryPath + ".tmp"; + const absoluteEntryTempFile: string = absoluteEntryPath + ".tmp"; if (fs.existsSync(absoluteEntryTempFile)) { try { await util.unlinkPromise(absoluteEntryTempFile); @@ -387,8 +387,8 @@ export class PackageManager { } // Make sure executable files have correct permissions when extracted - let fileMode: number = (pkg.binaries && pkg.binaries.indexOf(absoluteEntryPath) !== -1) ? 0o755 : 0o664; - let writeStream: fs.WriteStream = fs.createWriteStream(absoluteEntryTempFile, { mode: fileMode }); + const fileMode: number = (pkg.binaries && pkg.binaries.indexOf(absoluteEntryPath) !== -1) ? 0o755 : 0o664; + const writeStream: fs.WriteStream = fs.createWriteStream(absoluteEntryTempFile, { mode: fileMode }); writeStream.on('close', async () => { try { diff --git a/Extension/src/platform.ts b/Extension/src/platform.ts index 4e777c1e0e..918b51c060 100644 --- a/Extension/src/platform.ts +++ b/Extension/src/platform.ts @@ -27,7 +27,7 @@ export class PlatformInformation { constructor(public platform: string, public architecture?: string, public distribution?: LinuxDistribution, public version?: string) { } public static GetPlatformInformation(): Promise { - let platform: string = os.platform(); + const platform: string = os.platform(); let architecturePromise: Promise; let distributionPromise: Promise = Promise.resolve(undefined); let versionPromise: Promise = Promise.resolve(undefined); @@ -63,9 +63,9 @@ export class PlatformInformation { return util.execChildProcess('wmic os get osarchitecture', util.extensionPath) .then((architecture) => { if (architecture) { - let archArray: string[] = architecture.split(os.EOL); + const archArray: string[] = architecture.split(os.EOL); if (archArray.length >= 2) { - let arch: string = archArray[1].trim(); + const arch: string = archArray[1].trim(); // Note: This string can be localized. So, we'll just check to see if it contains 32 or 64. if (arch.indexOf('64') >= 0) { diff --git a/Extension/src/telemetry.ts b/Extension/src/telemetry.ts index b0b1bdc10e..b25c16d6ad 100644 --- a/Extension/src/telemetry.ts +++ b/Extension/src/telemetry.ts @@ -45,7 +45,7 @@ export function logLanguageServerEvent(eventName: string, properties?: { [key: s function createReporter(): TelemetryReporter | null { if (util.extensionContext) { - let packageInfo: IPackageInfo = getPackageInfo(); + const packageInfo: IPackageInfo = getPackageInfo(); if (packageInfo) { return new TelemetryReporter(packageInfo.name, packageInfo.version, appInsightsKey); } diff --git a/Extension/test.tsconfig.json b/Extension/test.tsconfig.json index 2d9a6ab425..8eecc93c1f 100644 --- a/Extension/test.tsconfig.json +++ b/Extension/test.tsconfig.json @@ -12,6 +12,8 @@ "noImplicitUseStrict": true }, "include": [ - "test/**/*.ts" + "test/**/*.ts", + "tools/**/*.ts", + "ui/**/*.ts" ] } \ No newline at end of file diff --git a/Extension/test/integrationTests/IntelliSenseFeatures/quickInfo.test.ts b/Extension/test/integrationTests/IntelliSenseFeatures/quickInfo.test.ts index 5d2071d9ce..aa4bc1d356 100644 --- a/Extension/test/integrationTests/IntelliSenseFeatures/quickInfo.test.ts +++ b/Extension/test/integrationTests/IntelliSenseFeatures/quickInfo.test.ts @@ -11,9 +11,9 @@ import * as testHelpers from '../testHelpers'; suite("[Quick info test]", function(): void { let cpptools: apit.CppToolsTestApi; - let disposables: vscode.Disposable[] = []; - let filePath: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/quickInfo.cpp"; - let fileUri: vscode.Uri = vscode.Uri.file(filePath); + const disposables: vscode.Disposable[] = []; + const filePath: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/quickInfo.cpp"; + const fileUri: vscode.Uri = vscode.Uri.file(filePath); let platform: string = ""; suiteSetup(async function(): Promise { @@ -21,10 +21,10 @@ suite("[Quick info test]", function(): void { cpptools = await apit.getCppToolsTestApi(api.Version.latest); platform = os.platform(); - let testHook: apit.CppToolsTestHook = cpptools.getTestHook(); + const testHook: apit.CppToolsTestHook = cpptools.getTestHook(); disposables.push(testHook); - let getIntelliSenseStatus: any = new Promise((resolve, reject) => { + const getIntelliSenseStatus: any = new Promise((resolve, reject) => { disposables.push(testHook.IntelliSenseStatusChanged(result => { result = result as apit.IntelliSenseStatus; if (result.filename === "quickInfo.cpp" && result.status === apit.Status.IntelliSenseReady) { @@ -45,51 +45,51 @@ suite("[Quick info test]", function(): void { }); test("[Hover over function call]", async () => { - let result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 12))); + const result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 12))); - let expectedMap: Map = new Map(); + const expectedMap: Map = new Map(); expectedMap.set("win32", `\`\`\`cpp\nvoid myfunction(int var1, std::string var2, std::string var3)\n\`\`\``); expectedMap.set("linux", `\`\`\`cpp\nvoid myfunction(int var1, std::string var2, std::string var3)\n\`\`\``); expectedMap.set("darwin", `\`\`\`cpp\nvoid myfunction(int var1, std::__cxx11::string var2, std::__cxx11::string var3)\n\`\`\``); - let expected1: string = expectedMap.get(platform); - let actual1: string = (result[0].contents[0]).value; + const expected1: string = expectedMap.get(platform); + const actual1: string = (result[0].contents[0]).value; assert.equal(actual1, expected1); - let expected2: string = `comment for myfunction`; - let actual2: string = (result[0].contents[1]).value; + const expected2: string = `comment for myfunction`; + const actual2: string = (result[0].contents[1]).value; assert.equal(actual2, expected2); }); test("[Hover over function param string variable]", async () => { - let result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 30))); + const result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 30))); - let expectedMap: Map = new Map(); + const expectedMap: Map = new Map(); expectedMap.set("win32", `\`\`\`cpp\nstd::string stringVar\n\`\`\``); expectedMap.set("linux", `\`\`\`cpp\nstd::string stringVar\n\`\`\``); expectedMap.set("darwin", `\`\`\`cpp\nstd::__cxx11::string stringVar\n\`\`\``); - let expected: string = expectedMap.get(platform); - let actual: string = (result[0].contents[0]).value; + const expected: string = expectedMap.get(platform); + const actual: string = (result[0].contents[0]).value; assert.equal(actual, expected); }); test("[Hover over function param string literal]", async () => { - let result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 44))); + const result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(12, 44))); - let expectedMap: Map = new Map(); + const expectedMap: Map = new Map(); expectedMap.set("win32", `\`\`\`cpp\nstd::string::basic_string(const char *_Ptr)\n\`\`\`\n\n+17 overloads\n`); expectedMap.set("linux", `\`\`\`cpp\nstd::string::basic_string<...>(const char *__s, const std::allocator<...> &__a = std::allocator<...>())\n\`\`\`\n\n+17 overloads\n`); expectedMap.set("darwin", `\`\`\`cpp\nstd::__cxx11::string::basic_string<...>(const char *__s, const std::allocator<...> &__a = std::allocator<...>())\n\`\`\`\n\n+17 overloads\n`); - let expected: string = expectedMap.get(platform); - let actual: string = (result[0].contents[0]).value; + const expected: string = expectedMap.get(platform); + const actual: string = (result[0].contents[0]).value; assert.equal(actual, expected); }); test("[Hover over function param with squiggles]", async () => { - let result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(13, 18))); - let expected: string = `\`\`\`cpp\nint intVar\n\`\`\``; - let actual: string = (result[0].contents[0]).value; + const result: vscode.Hover[] = (await vscode.commands.executeCommand('vscode.executeHoverProvider', fileUri, new vscode.Position(13, 18))); + const expected: string = `\`\`\`cpp\nint intVar\n\`\`\``; + const actual: string = (result[0].contents[0]).value; assert.equal(actual, expected); }); }); diff --git a/Extension/test/integrationTests/IntelliSenseFeatures/reference.test.ts b/Extension/test/integrationTests/IntelliSenseFeatures/reference.test.ts index a24fc2a2d7..d8b16fc72d 100644 --- a/Extension/test/integrationTests/IntelliSenseFeatures/reference.test.ts +++ b/Extension/test/integrationTests/IntelliSenseFeatures/reference.test.ts @@ -14,9 +14,9 @@ function delay(ms: number): Promise { suite(`[Reference test]`, function(): void { let cpptools: apit.CppToolsTestApi; - let disposables: vscode.Disposable[] = []; - let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/references.cpp"; - let fileUri: vscode.Uri = vscode.Uri.file(path); + const disposables: vscode.Disposable[] = []; + const path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/references.cpp"; + const fileUri: vscode.Uri = vscode.Uri.file(path); let testHook: apit.CppToolsTestHook; let getIntelliSenseStatus: any; let document: vscode.TextDocument; @@ -46,10 +46,10 @@ suite(`[Reference test]`, function(): void { test("[Find confirmed references of a symbol]", async () => { // Get reference of function declaration "int func1()" - let declarationResult: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(17, 7))); - let functionCallResult: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(24, 21))); + const declarationResult: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(17, 7))); + const functionCallResult: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(24, 21))); - let expectedText: string = "func1"; + const expectedText: string = "func1"; assertTextInLocation(document, expectedText, declarationResult); assertTextInLocation(document, expectedText, functionCallResult); assert.deepEqual(declarationResult, functionCallResult); @@ -57,9 +57,9 @@ suite(`[Reference test]`, function(): void { test("[Find references of local param]", async () => { // Get reference of local param: var1 in "int func1(float var1)" - let result: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(21, 18))); + const result: vscode.Location[] = (await vscode.commands.executeCommand("vscode.executeReferenceProvider", fileUri, new vscode.Position(21, 18))); - let expectedText: string = "var1"; + const expectedText: string = "var1"; assertTextInLocation(document, expectedText, result); assert.equal(result.length, 2); }); @@ -90,7 +90,7 @@ function assertTextInLocation(document: vscode.TextDocument, expectedText: strin console.log("expected reference text: " + expectedText); } Locations.forEach(location => { - let actualtext: string = document.getText(location.range); + const actualtext: string = document.getText(location.range); if (displayLog) { console.log("actual reference text: " + actualtext); } diff --git a/Extension/test/integrationTests/debug/integration.test.ts b/Extension/test/integrationTests/debug/integration.test.ts index 0ac98ce45d..dc8ed9035d 100644 --- a/Extension/test/integrationTests/debug/integration.test.ts +++ b/Extension/test/integrationTests/debug/integration.test.ts @@ -11,7 +11,7 @@ suite(`Debug Integration Test: `, function(): void { let hijackedFactoryFile: string; suiteSetup(async function(): Promise { - let extension: vscode.Extension = vscode.extensions.getExtension("ms-vscode.cpptools"); + const extension: vscode.Extension = vscode.extensions.getExtension("ms-vscode.cpptools"); if (!extension.isActive) { await extension.activate(); } @@ -21,7 +21,7 @@ suite(`Debug Integration Test: `, function(): void { // If it is failing on startDebugging. Investigate the SimpleCppProject's tasks.json or launch.json. await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], "(gdb) Launch"); - let debugSessionTerminated: Promise = new Promise(resolve => { + const debugSessionTerminated: Promise = new Promise(resolve => { vscode.debug.onDidTerminateDebugSession((e) => resolve()); }); diff --git a/Extension/test/integrationTests/languageServer/languageServer.integration.test.ts b/Extension/test/integrationTests/languageServer/languageServer.integration.test.ts index ac44d77a8d..4db0b6c09d 100644 --- a/Extension/test/integrationTests/languageServer/languageServer.integration.test.ts +++ b/Extension/test/integrationTests/languageServer/languageServer.integration.test.ts @@ -16,7 +16,7 @@ suite("multiline comment setting tests", function(): void { await testHelpers.activateCppExtension(); }); - let defaultRules: vscode.OnEnterRule[] = [ + const defaultRules: vscode.OnEnterRule[] = [ { beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/, afterText: /^\s*\*\/$/, @@ -39,7 +39,7 @@ suite("multiline comment setting tests", function(): void { action: { indentAction: vscode.IndentAction.None, removeText: 1 } } ]; - let defaultSLRules: vscode.OnEnterRule[] = [ + const defaultSLRules: vscode.OnEnterRule[] = [ { beforeText: /^\s*\/\/\/.+$/, action: { indentAction: vscode.IndentAction.None, appendText: '///' } @@ -51,27 +51,27 @@ suite("multiline comment setting tests", function(): void { ]; test("Check the default OnEnterRules for C", () => { - let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**" ]).onEnterRules; + const rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**" ]).onEnterRules; assert.deepEqual(rules, defaultRules); }); test("Check for removal of single line comment continuations for C", () => { - let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**", "///" ]).onEnterRules; + const rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('c', [ "/**", "///" ]).onEnterRules; assert.deepEqual(rules, defaultRules); }); test("Check the default OnEnterRules for C++", () => { - let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**" ]).onEnterRules; + const rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**" ]).onEnterRules; assert.deepEqual(rules, defaultRules); }); test("Make sure duplicate rules are removed", () => { - let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**", { begin: "/**", continue: " * " }, "/**" ]).onEnterRules; + const rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "/**", { begin: "/**", continue: " * " }, "/**" ]).onEnterRules; assert.deepEqual(rules, defaultRules); }); test("Check single line rules for C++", () => { - let rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "///" ]).onEnterRules; + const rules: vscode.OnEnterRule[] = getLanguageConfigFromPatterns('cpp', [ "///" ]).onEnterRules; assert.deepEqual(rules, defaultSLRules); }); @@ -85,7 +85,7 @@ function cppPropertiesPath(): string { async function changeCppProperties(cppProperties: config.ConfigurationJson, disposables: vscode.Disposable[]): Promise { await util.writeFileText(cppPropertiesPath(), JSON.stringify(cppProperties)); - let contents: string = await util.readFileText(cppPropertiesPath()); + const contents: string = await util.readFileText(cppPropertiesPath()); console.log(" wrote c_cpp_properties.json: " + contents); // Sleep for 4000ms for file watcher @@ -97,34 +97,34 @@ async function changeCppProperties(cppProperties: config.ConfigurationJson, disp suite("extensibility tests v3", function(): void { let cpptools: apit.CppToolsTestApi; let lastResult: api.SourceFileConfigurationItem[]; - let defaultConfig: api.SourceFileConfiguration = { + const defaultConfig: api.SourceFileConfiguration = { includePath: [ "${workspaceFolder}", "/v3/folder" ], defines: [ "${workspaceFolder}" ], intelliSenseMode: "msvc-x64", standard: "c++17" }; let lastBrowseResult: api.WorkspaceBrowseConfiguration; - let defaultBrowseConfig: api.WorkspaceBrowseConfiguration = { + const defaultBrowseConfig: api.WorkspaceBrowseConfiguration = { browsePath: [ "/v3/folder" ], compilerPath: "", standard: "c++14", windowsSdkVersion: "8.1" }; - let defaultFolderBrowseConfig: api.WorkspaceBrowseConfiguration = { + const defaultFolderBrowseConfig: api.WorkspaceBrowseConfiguration = { browsePath: [ "/v3/folder-1" ], compilerPath: "", standard: "c++14", windowsSdkVersion: "8.1" }; - let provider: api.CustomConfigurationProvider = { + const provider: api.CustomConfigurationProvider = { name: "cpptoolsTest-v3", extensionId: "ms-vscode.cpptools-test3", canProvideConfiguration(document: vscode.Uri): Thenable { return Promise.resolve(true); }, provideConfigurations(uris: vscode.Uri[]): Thenable { - let result: api.SourceFileConfigurationItem[] = []; + const result: api.SourceFileConfigurationItem[] = []; uris.forEach(uri => { result.push({ uri: uri.toString(), @@ -152,7 +152,7 @@ suite("extensibility tests v3", function(): void { console.log(" disposed"); } }; - let disposables: vscode.Disposable[] = []; + const disposables: vscode.Disposable[] = []; suiteSetup(async function(): Promise { cpptools = await apit.getCppToolsTestApi(api.Version.v3); @@ -173,15 +173,15 @@ suite("extensibility tests v3", function(): void { test("Check provider - main3.cpp", async () => { // Open a c++ file to start the language server. - let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main3.cpp"; - let uri: vscode.Uri = vscode.Uri.file(path); + const path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main3.cpp"; + const uri: vscode.Uri = vscode.Uri.file(path); - let testHook: apit.CppToolsTestHook = cpptools.getTestHook(); - let testResult: any = new Promise((resolve, reject) => { + const testHook: apit.CppToolsTestHook = cpptools.getTestHook(); + const testResult: any = new Promise((resolve, reject) => { disposables.push(testHook.IntelliSenseStatusChanged(result => { result = result as apit.IntelliSenseStatus; if (result.filename === "main3.cpp" && result.status === apit.Status.IntelliSenseReady) { - let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; + const expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; assert.deepEqual(lastResult, expected); assert.deepEqual(lastBrowseResult, defaultFolderBrowseConfig); resolve(); @@ -191,7 +191,7 @@ suite("extensibility tests v3", function(): void { }); disposables.push(testHook); - let document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); + const document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); await vscode.window.showTextDocument(document); await testResult; }); @@ -202,14 +202,14 @@ suite("extensibility tests v3", function(): void { suite("extensibility tests v2", function(): void { let cpptools: apit.CppToolsTestApi; let lastResult: api.SourceFileConfigurationItem[]; - let defaultConfig: api.SourceFileConfiguration = { + const defaultConfig: api.SourceFileConfiguration = { includePath: [ "${workspaceFolder}", "/v2/folder" ], defines: [ "${workspaceFolder}" ], intelliSenseMode: "msvc-x64", standard: "c++17" }; let lastBrowseResult: api.WorkspaceBrowseConfiguration; - let defaultBrowseConfig: api.WorkspaceBrowseConfiguration = { + const defaultBrowseConfig: api.WorkspaceBrowseConfiguration = { browsePath: [ "/v2/folder" ], compilerPath: "", standard: "c++14", @@ -217,14 +217,14 @@ suite("extensibility tests v2", function(): void { }; // Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members. - let provider: any = { + const provider: any = { name: "cpptoolsTest-v2", extensionId: "ms-vscode.cpptools-test2", canProvideConfiguration(document: vscode.Uri): Thenable { return Promise.resolve(true); }, provideConfigurations(uris: vscode.Uri[]): Thenable { - let result: api.SourceFileConfigurationItem[] = []; + const result: api.SourceFileConfigurationItem[] = []; uris.forEach(uri => { result.push({ uri: uri.toString(), @@ -245,7 +245,7 @@ suite("extensibility tests v2", function(): void { console.log(" disposed"); } }; - let disposables: vscode.Disposable[] = []; + const disposables: vscode.Disposable[] = []; suiteSetup(async function(): Promise { cpptools = await apit.getCppToolsTestApi(api.Version.v2); @@ -266,16 +266,16 @@ suite("extensibility tests v2", function(): void { test("Check provider - main2.cpp", async () => { // Open a c++ file to start the language server. - let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main2.cpp"; - let uri: vscode.Uri = vscode.Uri.file(path); + const path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main2.cpp"; + const uri: vscode.Uri = vscode.Uri.file(path); - let testHook: apit.CppToolsTestHook = cpptools.getTestHook(); - let testResult: any = new Promise((resolve, reject) => { + const testHook: apit.CppToolsTestHook = cpptools.getTestHook(); + const testResult: any = new Promise((resolve, reject) => { disposables.push(testHook.IntelliSenseStatusChanged(result => { result = result as apit.IntelliSenseStatus; if (result.filename === "main2.cpp" && result.status === apit.Status.IntelliSenseReady) { - let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; + const expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; assert.deepEqual(lastResult, expected); assert.deepEqual(lastBrowseResult, defaultBrowseConfig); resolve(); @@ -285,7 +285,7 @@ suite("extensibility tests v2", function(): void { }); disposables.push(testHook); - let document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); + const document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); await vscode.window.showTextDocument(document); await testResult; }); @@ -296,7 +296,7 @@ suite("extensibility tests v2", function(): void { suite("extensibility tests v1", function(): void { let cpptools: apit.CppToolsTestApi; let lastResult: api.SourceFileConfigurationItem[]; - let defaultConfig: api.SourceFileConfiguration = { + const defaultConfig: api.SourceFileConfiguration = { includePath: [ "${workspaceFolder}" ], defines: [ "${workspaceFolder}" ], intelliSenseMode: "msvc-x64", @@ -304,14 +304,14 @@ suite("extensibility tests v1", function(): void { }; // Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members. - let provider: any = { + const provider: any = { name: "cpptoolsTest-v1", extensionId: "ms-vscode.cpptools-test", canProvideConfiguration(document: vscode.Uri): Thenable { return Promise.resolve(true); }, provideConfigurations(uris: vscode.Uri[]): Thenable { - let result: api.SourceFileConfigurationItem[] = []; + const result: api.SourceFileConfigurationItem[] = []; uris.forEach(uri => { result.push({ uri: uri.toString(), @@ -325,7 +325,7 @@ suite("extensibility tests v1", function(): void { console.log(" disposed"); } }; - let disposables: vscode.Disposable[] = []; + const disposables: vscode.Disposable[] = []; suiteSetup(async function(): Promise { cpptools = await apit.getCppToolsTestApi(api.Version.v1); @@ -345,15 +345,15 @@ suite("extensibility tests v1", function(): void { test("Check provider - main1.cpp", async () => { // Open a c++ file to start the language server. - let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main1.cpp"; - let uri: vscode.Uri = vscode.Uri.file(path); + const path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main1.cpp"; + const uri: vscode.Uri = vscode.Uri.file(path); - let testHook: apit.CppToolsTestHook = cpptools.getTestHook(); - let testResult: any = new Promise((resolve, reject) => { + const testHook: apit.CppToolsTestHook = cpptools.getTestHook(); + const testResult: any = new Promise((resolve, reject) => { disposables.push(testHook.IntelliSenseStatusChanged(result => { result = result as apit.IntelliSenseStatus; if (result.filename === "main1.cpp" && result.status === apit.Status.IntelliSenseReady) { - let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; + const expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; assert.deepEqual(lastResult, expected); resolve(); } @@ -362,7 +362,7 @@ suite("extensibility tests v1", function(): void { }); disposables.push(testHook); - let document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); + const document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); await vscode.window.showTextDocument(document); await testResult; }); @@ -373,7 +373,7 @@ suite("extensibility tests v1", function(): void { suite("extensibility tests v0", function(): void { let cpptools: apit.CppToolsTestApi; let lastResult: api.SourceFileConfigurationItem[]; - let defaultConfig: api.SourceFileConfiguration = { + const defaultConfig: api.SourceFileConfiguration = { includePath: [ "${workspaceFolder}" ], defines: [ "${workspaceFolder}" ], intelliSenseMode: "msvc-x64", @@ -381,13 +381,13 @@ suite("extensibility tests v0", function(): void { }; // Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members. - let provider: any = { + const provider: any = { name: "cpptoolsTest-v0", canProvideConfiguration(document: vscode.Uri): Thenable { return Promise.resolve(true); }, provideConfigurations(uris: vscode.Uri[]): Thenable { - let result: api.SourceFileConfigurationItem[] = []; + const result: api.SourceFileConfigurationItem[] = []; uris.forEach(uri => { result.push({ uri: uri.toString(), @@ -398,7 +398,7 @@ suite("extensibility tests v0", function(): void { return Promise.resolve(result); } }; - let disposables: vscode.Disposable[] = []; + const disposables: vscode.Disposable[] = []; suiteSetup(async function(): Promise { cpptools = await apit.getCppToolsTestApi(api.Version.v0); @@ -419,15 +419,15 @@ suite("extensibility tests v0", function(): void { test("Check provider - main.cpp", async () => { // Open a C++ file to start the language server. - let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main.cpp"; - let uri: vscode.Uri = vscode.Uri.file(path); + const path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main.cpp"; + const uri: vscode.Uri = vscode.Uri.file(path); - let testHook: apit.CppToolsTestHook = cpptools.getTestHook(); - let testResult: any = new Promise((resolve, reject) => { + const testHook: apit.CppToolsTestHook = cpptools.getTestHook(); + const testResult: any = new Promise((resolve, reject) => { disposables.push(testHook.IntelliSenseStatusChanged(result => { result = result as apit.IntelliSenseStatus; if (result.filename === "main.cpp" && result.status === apit.Status.IntelliSenseReady) { - let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; + const expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ]; assert.deepEqual(lastResult, expected); resolve(); } @@ -436,7 +436,7 @@ suite("extensibility tests v0", function(): void { }); disposables.push(testHook); - let document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); + const document: vscode.TextDocument = await vscode.workspace.openTextDocument(path); await vscode.window.showTextDocument(document); await testResult; }); diff --git a/Extension/test/integrationTests/testHelpers.ts b/Extension/test/integrationTests/testHelpers.ts index ccacf98525..6cf52ad6ff 100644 --- a/Extension/test/integrationTests/testHelpers.ts +++ b/Extension/test/integrationTests/testHelpers.ts @@ -7,7 +7,7 @@ import * as vscode from 'vscode'; export const defaultTimeout: number = 100000; export async function activateCppExtension(): Promise { - let extension: vscode.Extension = vscode.extensions.getExtension("ms-vscode.cpptools"); + const extension: vscode.Extension = vscode.extensions.getExtension("ms-vscode.cpptools"); if (!extension.isActive) { await extension.activate(); } diff --git a/Extension/test/unitTests/ParsedEnvironmentFile.test.ts b/Extension/test/unitTests/ParsedEnvironmentFile.test.ts index a0fefdacbf..6aa5a13c14 100644 --- a/Extension/test/unitTests/ParsedEnvironmentFile.test.ts +++ b/Extension/test/unitTests/ParsedEnvironmentFile.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; // Because the environment variable is set as an array, the index does not matter. function assertEnvironmentEqual(env: Environment[], name: string, value: string): void { let found: boolean = false; - for (let e of env) { + for (const e of env) { if (e.name === name) { assert(e.value === value, `Checking if ${e.value} == ${value}`); found = true; diff --git a/Extension/test/unitTests/common.test.ts b/Extension/test/unitTests/common.test.ts index b9e3ab7c16..0d6cd8197e 100644 --- a/Extension/test/unitTests/common.test.ts +++ b/Extension/test/unitTests/common.test.ts @@ -198,8 +198,8 @@ suite("Common Utility validation", () => { }); test("escapeForSquiggles:", () => { - let testEscapeForSquigglesScenario: any = (input: string, expectedOutput: string) => { - let result: string = escapeForSquiggles(input); + const testEscapeForSquigglesScenario: any = (input: string, expectedOutput: string) => { + const result: string = escapeForSquiggles(input); if (result !== expectedOutput) { throw new Error(`escapeForSquiggles failure: for \"${input}\", \"${result}\" !== \"${expectedOutput}\"`); } diff --git a/Extension/test/unitTests/extension.test.ts b/Extension/test/unitTests/extension.test.ts index b16a5574ac..b5b70dbbd1 100644 --- a/Extension/test/unitTests/extension.test.ts +++ b/Extension/test/unitTests/extension.test.ts @@ -46,9 +46,9 @@ suite("LinuxDistro Tests", () => { 'REDHAT_SUPPORT_PRODUCT="centos"' + os.EOL + 'REDHAT_SUPPORT_PRODUCT_VERSION="7"'; - let ubuntu1404: LinuxDistribution = LinuxDistribution.getDistroInformation(dataUbuntu1404); - let ubuntu1510: LinuxDistribution = LinuxDistribution.getDistroInformation(dataUbuntu1510); - let centos73: LinuxDistribution = LinuxDistribution.getDistroInformation(dataCentos73); + const ubuntu1404: LinuxDistribution = LinuxDistribution.getDistroInformation(dataUbuntu1404); + const ubuntu1510: LinuxDistribution = LinuxDistribution.getDistroInformation(dataUbuntu1510); + const centos73: LinuxDistribution = LinuxDistribution.getDistroInformation(dataCentos73); assert.equal(ubuntu1404.name, 'ubuntu'); assert.equal(ubuntu1404.version, '"14.04"'); @@ -63,7 +63,7 @@ suite("LinuxDistro Tests", () => { test("Parse invalid os-release file", () => { const data: string = 'garbage"'; - let unknown: LinuxDistribution = LinuxDistribution.getDistroInformation(data); + const unknown: LinuxDistribution = LinuxDistribution.getDistroInformation(data); assert.equal(unknown.name, 'unknown'); assert.equal(unknown.version, 'unknown'); }); @@ -86,11 +86,11 @@ suite("Pick Process Tests", () => { 'Name=conhost.exe' + os.EOL + 'ProcessId=59148' + os.EOL; - let parsedOutput: Process[] = WmicProcessParser.ParseProcessFromWmic(wmicOutput); + const parsedOutput: Process[] = WmicProcessParser.ParseProcessFromWmic(wmicOutput); - let process1: Process = parsedOutput[0]; - let process2: Process = parsedOutput[1]; - let process3: Process = parsedOutput[2]; + const process1: Process = parsedOutput[0]; + const process2: Process = parsedOutput[1]; + const process3: Process = parsedOutput[2]; assert.equal(process1.commandLine, ''); assert.equal(process1.name, 'System Idle Process'); @@ -111,11 +111,11 @@ suite("Pick Process Tests", () => { '15470 ScopedBookmarkAgent ScopedBookmarkAgent' + os.EOL + '15220 mdworker mdworker -s mdworker -c MDSImporterWorker -m com.apple.mdworker.shared' + os.EOL; - let parsedOutput: Process[] = PsProcessParser.ParseProcessFromPs(psOutput); + const parsedOutput: Process[] = PsProcessParser.ParseProcessFromPs(psOutput); - let process1: Process = parsedOutput[0]; - let process2: Process = parsedOutput[1]; - let process3: Process = parsedOutput[2]; + const process1: Process = parsedOutput[0]; + const process2: Process = parsedOutput[1]; + const process3: Process = parsedOutput[2]; assert.equal(process1.commandLine, 'ScopedBookmarkAgent'); assert.equal(process1.name, 'ScopedBookmarkAgent'); diff --git a/Extension/test/unitTests/updowngrade.test.ts b/Extension/test/unitTests/updowngrade.test.ts index 6abc408181..8aca246ccf 100644 --- a/Extension/test/unitTests/updowngrade.test.ts +++ b/Extension/test/unitTests/updowngrade.test.ts @@ -31,7 +31,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider2); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, release0); }); }); @@ -46,7 +46,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider1); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild, undefined); }); test("Insider to Insider", () => { @@ -56,7 +56,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider3); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild, undefined); }); test("Release to Insider", () => { @@ -67,7 +67,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(release1); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild, undefined); }); }); @@ -81,7 +81,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider3); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, release0); }); test("Insider to Insider", () => { @@ -92,7 +92,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider3); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, insider1); }); }); @@ -107,7 +107,7 @@ suite("UpgradeDowngrade", () => { name: insider2, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(release0); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, release1); }); test("Insider to Release", () => { @@ -117,7 +117,7 @@ suite("UpgradeDowngrade", () => { name: insider2, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider2); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, release1); }); }); @@ -130,7 +130,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(release0); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, insider1); }); test("Release to Insider, no Upgrade", () => { @@ -140,7 +140,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(release0); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild, undefined); }); test("Insider to Insider, Upgrade", () => { @@ -151,7 +151,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider1); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild.name, insider2); }); test("Insider to Insider, no Upgrade", () => { @@ -161,7 +161,7 @@ suite("UpgradeDowngrade", () => { name: release0, assets: three_assets}]; const userVersion: PackageVersion = new PackageVersion(insider2); - const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel); + const targetBuild: Build | undefined = getTargetBuild(builds, userVersion, updateChannel, false); assert.equal(targetBuild, undefined); }); }); diff --git a/Extension/tools/.eslintrc.js b/Extension/tools/.eslintrc.js new file mode 100644 index 0000000000..d91a265864 --- /dev/null +++ b/Extension/tools/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + "parserOptions": { + "project": "test.tsconfig.json", + "sourceType": "module" + } +}; diff --git a/Extension/tools/GenerateOptionsSchema.ts b/Extension/tools/GenerateOptionsSchema.ts index ff59a0deda..418f34ad29 100644 --- a/Extension/tools/GenerateOptionsSchema.ts +++ b/Extension/tools/GenerateOptionsSchema.ts @@ -1,7 +1,7 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ import * as fs from 'fs'; import * as os from 'os'; @@ -9,7 +9,7 @@ import * as os from 'os'; function appendFieldsToObject(reference: any, obj: any): any { // Make sure it is an object type if (typeof obj === 'object') { - for (let referenceKey in reference) { + for (const referenceKey in reference) { // If key exists in original object and is an object. if (obj.hasOwnProperty(referenceKey)) { obj[referenceKey] = appendFieldsToObject(reference[referenceKey], obj[referenceKey]); @@ -25,13 +25,13 @@ function appendFieldsToObject(reference: any, obj: any): any { // Combines two object's fields, giving the parentDefault a higher precedence. function mergeDefaults(parentDefault: any, childDefault: any): any { - let newDefault: any = {}; + const newDefault: any = {}; - for (let attrname in childDefault) { + for (const attrname in childDefault) { newDefault[attrname] = childDefault[attrname]; } - for (let attrname in parentDefault) { + for (const attrname in parentDefault) { newDefault[attrname] = parentDefault[attrname]; } @@ -40,7 +40,7 @@ function mergeDefaults(parentDefault: any, childDefault: any): any { function updateDefaults(object: any, defaults: any): any { if (defaults !== null) { - for (let key in object) { + for (const key in object) { if (object[key].hasOwnProperty('type') && object[key].type === 'object' && object[key].properties !== null) { object[key].properties = updateDefaults(object[key].properties, mergeDefaults(defaults, object[key].default)); } else if (key in defaults) { @@ -54,17 +54,17 @@ function updateDefaults(object: any, defaults: any): any { function refReplace(definitions: any, ref: any): any { // $ref is formatted as "#/definitions/ObjectName" - let referenceStringArray: string[] = ref['$ref'].split('/'); + const referenceStringArray: string[] = ref['$ref'].split('/'); // Getting "ObjectName" - let referenceName: string = referenceStringArray[referenceStringArray.length - 1]; + const referenceName: string = referenceStringArray[referenceStringArray.length - 1]; // Make sure reference has replaced its own $ref fields and hope there are no recursive references. definitions[referenceName] = replaceReferences(definitions, definitions[referenceName]); // Retrieve ObjectName from definitions. (TODO: Does not retrieve inner objects) // Need to deep copy, there are no functions in these objects. - let reference: any = JSON.parse(JSON.stringify(definitions[referenceName])); + const reference: any = JSON.parse(JSON.stringify(definitions[referenceName])); ref = appendFieldsToObject(reference, ref); @@ -75,7 +75,7 @@ function refReplace(definitions: any, ref: any): any { } function replaceReferences(definitions: any, objects: any): any { - for (let key in objects) { + for (const key in objects) { if (objects[key].hasOwnProperty('$ref')) { objects[key] = refReplace(definitions, objects[key]); } @@ -96,8 +96,8 @@ function replaceReferences(definitions: any, objects: any): any { } function generateOptionsSchema(): void { - let packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString()); - let schemaJSON: any = JSON.parse(fs.readFileSync('tools/OptionsSchema.json').toString()); + const packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString()); + const schemaJSON: any = JSON.parse(fs.readFileSync('tools/OptionsSchema.json').toString()); schemaJSON.definitions = replaceReferences(schemaJSON.definitions, schemaJSON.definitions); diff --git a/Extension/tools/OptionsSchema.json b/Extension/tools/OptionsSchema.json index e96ca1cab0..c8f0f07e1d 100644 --- a/Extension/tools/OptionsSchema.json +++ b/Extension/tools/OptionsSchema.json @@ -45,6 +45,13 @@ }, "description": "%c_cpp.debuggers.pipeTransport.pipeEnv.description%", "default": {} + }, + "quoteArgs": { + "exceptions": { + "type": "boolean", + "description": "%c_cpp.debuggers.pipeTransport.quoteArgs.description%", + "default": true + } } } }, @@ -528,6 +535,16 @@ "type": "boolean", "description": "%c_cpp.debuggers.logging.engineLogging.description%", "default": false + }, + "threadExit": { + "type": "boolean", + "description": "%c_cpp.debuggers.cppvsdbg.logging.threadExit.description%", + "default": false + }, + "processExit": { + "type": "boolean", + "description": "%c_cpp.debuggers.cppvsdbg.logging.processExit.description%", + "default": true } } }, diff --git a/Extension/tools/copyDebuggerDependencies.ts b/Extension/tools/copyDebuggerDependencies.ts index 588efca266..bd9a414057 100644 --- a/Extension/tools/copyDebuggerDependencies.ts +++ b/Extension/tools/copyDebuggerDependencies.ts @@ -13,7 +13,7 @@ import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; -//Change this to true to force a dev workflow. +// Change this to true to force a dev workflow. const EnableDevWorkflow: boolean = false; const DebugAdapterPath: string = "./debugAdapters"; @@ -46,13 +46,13 @@ function findCppToolsExtensionDebugAdapterFolder(): string { let dirPath: string = os.homedir(); if (fs.existsSync(dirPath)) { - let files: string[] = fs.readdirSync(dirPath); + const files: string[] = fs.readdirSync(dirPath); for (let i: number = 0; i < files.length; i++) { // Check to see if it starts with '.vscode' if (vscodeFolderRegExp.test(files[i])) { - let extPath: string = path.join(dirPath, files[i], "extensions"); + const extPath: string = path.join(dirPath, files[i], "extensions"); if (fs.existsSync(extPath)) { - let extFiles: string[] = fs.readdirSync(extPath); + const extFiles: string[] = fs.readdirSync(extPath); for (let j: number = 0; j < extFiles.length; j++) { if (cpptoolsFolderRegExp.test(path.join(extFiles[j]))) { dirPath = path.join(extPath, extFiles[j]); @@ -77,7 +77,7 @@ function findCppToolsExtensionDebugAdapterFolder(): string { function enableDevWorkflow(): Boolean { if (process.env.AGENT_ID) { - //Agent machines must not attempt any dev workflows + // Agent machines must not attempt any dev workflows return false; } @@ -168,9 +168,9 @@ function removeFolder(root: string): void { return; } - let files: string[] = fs.readdirSync(root); + const files: string[] = fs.readdirSync(root); for (let i: number = 0; i < files.length; i++) { - let fullPath: string = path.join(root, files[i]); + const fullPath: string = path.join(root, files[i]); console.warn('Found entry %s', fullPath); if (!isDirectory(fullPath)) { console.warn('Deleting %s', fullPath); @@ -194,7 +194,7 @@ function isDirectory(dir: string): Boolean { function makeDirectory(dir: string): void { try { - //Note: mkdir is limited to creating folders with one level of nesting. Creating "a/b" if 'a' doesn't exist will throw a ENOENT. + // Note: mkdir is limited to creating folders with one level of nesting. Creating "a/b" if 'a' doesn't exist will throw a ENOENT. fs.mkdirSync(dir); } catch (e) { if ((e).code !== "EEXIST") { diff --git a/Extension/tools/prepublish.js b/Extension/tools/prepublish.js index d0deda5cd6..d061e2a7de 100644 --- a/Extension/tools/prepublish.js +++ b/Extension/tools/prepublish.js @@ -40,4 +40,4 @@ if (process.env.CPPTOOLS_DEV || !fs.existsSync('./debugAdapters/bin/cppdbg.ad7En // Required for nightly builds. Nightly builds do not enable CPPTOOLS_DEV. console.log(">> node " + copyDebuggerDependenciesJSFile); cp.execSync("node " + copyDebuggerDependenciesJSFile, { stdio: [0, 1, 2] }); -} \ No newline at end of file +} diff --git a/Extension/ui/.eslintrc.js b/Extension/ui/.eslintrc.js new file mode 100644 index 0000000000..d91a265864 --- /dev/null +++ b/Extension/ui/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + "parserOptions": { + "project": "test.tsconfig.json", + "sourceType": "module" + } +}; diff --git a/Extension/ui/settings.ts b/Extension/ui/settings.ts index 7f3ca897f5..c97df52823 100644 --- a/Extension/ui/settings.ts +++ b/Extension/ui/settings.ts @@ -156,7 +156,7 @@ class SettingsApp { } const configName: HTMLInputElement = document.getElementById(elementId.configName); - let list: HTMLSelectElement = document.getElementById(elementId.configSelection); + const list: HTMLSelectElement = document.getElementById(elementId.configSelection); if (configName.value === "") { (document.getElementById(elementId.configName)).value = list.options[list.selectedIndex].value; @@ -247,9 +247,7 @@ class SettingsApp { private updateConfig(config: any): void { this.updating = true; try { - let joinEntries: (input: any) => string = (input: string[]) => { - return (input && input.length) ? input.join("\n") : ""; - }; + const joinEntries: (input: any) => string = (input: string[]) => (input && input.length) ? input.join("\n") : ""; // Basic settings (document.getElementById(elementId.configName)).value = config.name; @@ -308,14 +306,14 @@ class SettingsApp { private updateConfigSelection(message: any): void { this.updating = true; try { - let list: HTMLSelectElement = document.getElementById(elementId.configSelection); + const list: HTMLSelectElement = document.getElementById(elementId.configSelection); // Clear list before updating list.options.length = 0; // Update list - for (let name of message.selections) { - let option: HTMLOptionElement = document.createElement("option"); + for (const name of message.selections) { + const option: HTMLOptionElement = document.createElement("option"); option.text = name; option.value = name; list.append(option); @@ -330,7 +328,7 @@ class SettingsApp { private setKnownCompilers(compilers: string[]): void { this.updating = true; try { - let list: HTMLSelectElement = document.getElementById(elementId.knownCompilers); + const list: HTMLSelectElement = document.getElementById(elementId.knownCompilers); // No need to add items unless webview is reloaded, in which case it will not have any elements. // Otherwise, add items again. @@ -340,14 +338,14 @@ class SettingsApp { if (compilers.length === 0) { // Get HTML element containing the string, as we can't localize strings in HTML js - let noCompilerSpan: HTMLSpanElement = document.getElementById(elementId.noCompilerPathsDetected); - let option: HTMLOptionElement = document.createElement("option"); + const noCompilerSpan: HTMLSpanElement = document.getElementById(elementId.noCompilerPathsDetected); + const option: HTMLOptionElement = document.createElement("option"); option.text = noCompilerSpan.textContent; option.disabled = true; list.append(option); } else { - for (let path of compilers) { - let option: HTMLOptionElement = document.createElement("option"); + for (const path of compilers) { + const option: HTMLOptionElement = document.createElement("option"); option.text = path; option.value = path; list.append(option); @@ -369,4 +367,4 @@ class SettingsApp { } } -let app: SettingsApp = new SettingsApp(); +const app: SettingsApp = new SettingsApp(); diff --git a/Extension/yarn.lock b/Extension/yarn.lock index a97e4ef457..5e3be46d83 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -204,10 +204,10 @@ dependencies: source-map "^0.6.1" -"@types/vscode@1.43.0": - version "1.43.0" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.43.0.tgz#22276e60034c693b33117f1068ffaac0e89522db" - integrity sha512-kIaR9qzd80rJOxePKpCB/mdy00mz8Apt2QA5Y6rdrKFn13QNFNeP3Hzmsf37Bwh/3cS7QjtAeGSK7wSqAU0sYQ== +"@types/vscode@1.44.0": + version "1.44.0" + resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.44.0.tgz#62ecfe3d0e38942fce556574da54ee1013c775b7" + integrity sha512-WJZtZlinE3meRdH+I7wTsIhpz/GLhqEQwmPGeh4s1irWLwMzCeTV8WZ+pgPTwrDXoafVUWwo1LiZ9HJVHFlJSQ== "@types/webpack-sources@*": version "0.1.6" diff --git a/LICENSE.txt b/LICENSE.md similarity index 84% rename from LICENSE.txt rename to LICENSE.md index 53d8ede1c8..5ea0ed647e 100644 --- a/LICENSE.txt +++ b/LICENSE.md @@ -1,19 +1,15 @@ -------------------------------------------- START OF LICENSE ----------------------------------------- - -vscode-cpptools - -Copyright (c) Microsoft Corporation - -All rights reserved. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------------------------------------------------ END OF LICENSE ------------------------------------------ \ No newline at end of file +vscode-cpptools + +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Themes/README.md b/Themes/README.md index 9f80ac2fcf..b34aee95f9 100644 --- a/Themes/README.md +++ b/Themes/README.md @@ -1,8 +1,10 @@ # C/C++ Extension UI Themes -[Semantic colorization was added to the C/C++ Extension in version 0.24.0](https://devblogs.microsoft.com/cppblog/visual-studio-code-c-c-extension-july-2019-update/). By default, colorization in VS Code is syntactic/lexical and leverages TextMate grammar to associate named 'scopes' with syntactic elements. Themes and settings can be used to apply the colors associated with those scopes. Our implementation of semantic colorization leverages the same system of associating colors with named scopes. But, some tokens that can be colored by semantic colorization in C/C++ do not have existing analogs in VS Code's TextMate grammar. So, new named scopes are required. Information about these new scopes can be found [here](https://code.visualstudio.com/docs/cpp/colorization-cpp). Because these scopes are new, existing themes do not include colors for them either. +[Semantic colorization was added to the C/C++ Extension in version 0.24.0](https://devblogs.microsoft.com/cppblog/visual-studio-code-c-c-extension-july-2019-update/). At the time, colorization in VS Code was purely syntactic/lexical and leveraged TextMate grammar to associate named 'scopes' with syntactic elements. Themes and settings can be used to associate colors with these scopes. Our original implementation of semantic colorization leveraged the same system of associating colors with named scopes. But, some tokens that can be colored by semantic colorization in C/C++ did not have existing analogs in VS Code's TextMate grammar. So, new named scopes are required. Because these scopes were new, existing themes did not include colors for them either. -We created C/C++ Extension UI Themes to closely match Visual Studio themes, and include colors for many of the new scopes. +We created C/C++ Extension UI Themes to closely match Visual Studio themes and include colors for many of the new scopes. + +VS Code has since provided an API for semantic colorization. The C/C++ Extension has transitioned from its own implementation to this new API. These themes now include colors for some of the new semantic token scopes. ## Example @@ -16,7 +18,7 @@ Dark Theme ## Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. diff --git a/Themes/themes/cpptools_dark_vs.json b/Themes/themes/cpptools_dark_vs.json index a0394b6d67..d2d7daaa77 100644 --- a/Themes/themes/cpptools_dark_vs.json +++ b/Themes/themes/cpptools_dark_vs.json @@ -20,6 +20,7 @@ "statusBarItem.remoteForeground": "#FFF", "statusBarItem.remoteBackground": "#16825D" }, + "semanticHighlighting": true, "tokenColors": [ { "scope": [ @@ -466,5 +467,37 @@ "foreground": "#7F7F7F" } } + ], + "semanticTokenColors": [ + { + "operatorOverload": { + "foreground": "#B4B4B4" + } + }, + { + "operatorOverloadMember": { + "foreground": "#B4B4B4" + } + }, + { + "newOperator": { + "foreground": "#569CD6" + } + }, + { + "numberLiteral": { + "foreground": "#B5CEA8" + } + }, + { + "customLiteral": { + "foreground": "#DADADA" + } + }, + { + "stringLiteral": { + "foreground": "#D69D85" + } + } ] } \ No newline at end of file diff --git a/Themes/themes/cpptools_light_vs.json b/Themes/themes/cpptools_light_vs.json index 4901df8c77..b1f5e6fd18 100644 --- a/Themes/themes/cpptools_light_vs.json +++ b/Themes/themes/cpptools_light_vs.json @@ -19,6 +19,7 @@ "statusBarItem.remoteForeground": "#FFF", "statusBarItem.remoteBackground": "#16825D" }, + "semanticHighlighting": true, "tokenColors": [ { "scope": ["meta.embedded", "source.groovy.embedded"], @@ -455,5 +456,27 @@ "foreground": "#808080" } } + ], + "semanticTokenColors": [ + { + "operatorOverload": { + "foreground": "#008080" + } + }, + { + "operatorOverloadMember": { + "foreground": "#008080" + } + }, + { + "newOperator": { + "foreground": "#0000FF" + } + }, + { + "stringLiteral": { + "foreground": "#A31515" + } + } ] } \ No newline at end of file