Compare commits

...
25 Commits
Author SHA1 Message Date
Colen Garoutte-Carson 98696368f4 Merge pull request #13025 from microsoft/main 2024-12-05 12:45:31 -08:00
Colen Garoutte-Carson ee71e1f82c Update changelog for 1.23.2 (2nd time) (#13024) 2024-12-05 12:39:02 -08:00
[email protected] 05d43dc2f7 [Auto] Localization - Translated Strings (#12869) 2024-12-05 12:09:39 -08:00
Sean McManus 99d98afcec Merge pull request #13021 from microsoft/main
Merge to insiders for 1.23.2
2024-12-04 20:04:33 -08:00
Colen Garoutte-Carson 44b736e84a Update changelog for 1.23.2 (#13020) 2024-12-04 18:55:51 -08:00
Sean McManus 052bcffe37 Fix an unnecessary cancel/re-request with GitHub Copilot requests (and fix some other bugs with Copilot exception handling) (#12988)
* Fix an unnecessary cancel/re-request with GitHub Copilot requests.
* A couple bug fixes from the previous PR.
* Fix another loc case.
2024-12-04 15:01:24 -08:00
Colen Garoutte-Carson 74d691f431 Update mac runner to macos-14 (#13013) 2024-12-03 15:21:03 -08:00
adrianstephens 9efde543c5 pass optional parameter to C_Cpp.ConfigurationSelect (#12993) 2024-12-02 19:19:52 -08:00
Glen Chung a6089eaa6c Support A/B Compiler Arguments Traits (#12979)
- Depends on cpptools' update to provide ProjectContextResult.
- Send "standardVersion" trait in completion prompt by default.
- Added the following new traits
  - intelliSenseDisclaimer: compiler information disclaimer.
  - intelliSenseDisclaimerBeginning: to note the beginning of IntelliSense information.
  - compilerArguments: a list of compiler command arguments that could affect Copilot generating completions.
  - directAsks: direct asking Copilot to do something instead of providing an argument.
  - intelliSenseDisclaimerEnd: to note the end of IntelliSense information.
- A/B Experimental flags
  - copilotcppTraits: deprecated, no longer used.
  - copilotcppExcludeTraits:: deprecated, no longer used.
  - copilotcppIncludeTraits: string array to include individual trait, i.e., compilerArguments.
  - copilotcppMsvcCompilerArgumentFilter: map of regex string to absence prompt for MSVC.
  - copilotcppClangCompilerArgumentFilter: map of regex string to absence prompt for Clang.
  - copilotcppGccCompilerArgumentFilter: map of regex string to absence prompt for GCC.
  - copilotcppCompilerArgumentDirectAskMap: map of argument to prompt.
2024-12-02 14:38:50 -08:00
Colen Garoutte-Carson 21a44d9be6 Add a string for multiple compile_commands.json (on native side) (#12964) 2024-12-02 12:31:42 -08:00
Bob Brown bfa3c7544e Add a CODEOWNERS file for required PR reviews (#12987) 2024-11-21 13:02:20 -08:00
dependabot[bot] 64e9106cb3 Bump cross-spawn from 7.0.3 to 7.0.6 in /Extension (#12973)
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6.
- [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6)

---
updated-dependencies:
- dependency-name: cross-spawn
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-19 10:46:12 -08:00
Colen Garoutte-Carson 05fbc0eae7 Fix matching of editorConfig sections patterns (#12953) 2024-11-12 18:44:32 -08:00
Colen Garoutte-Carson 9646722501 Address issue with Attempting to use languageClient before initialized (#12959) 2024-11-12 16:25:04 -08:00
Yiftah Waisman 911c39d054 Fixes to compile commands file watchers fallback logic (#12948)
* close file watchers before clearing the array
* keep track of fallback time per file
2024-11-12 16:02:42 -08:00
Sean McManus 784f1450c0 Merge pull request #12939 from microsoft/main
Update changelog. (#12938)
2024-11-06 13:56:23 -08:00
Sean McManus c9cae0b8c0 Update changelog. (#12938) 2024-11-06 12:43:56 -08:00
Sean McManus 7d26dd1c4f Merge pull request #12932 from microsoft/main
Merge for 1.23.1
2024-11-05 17:29:22 -08:00
Sean McManus 1b21b69422 Update changelog for 1.23.1 (#12931)
* Update changelog for 1.23.1
2024-11-05 17:15:09 -08:00
Colen Garoutte-Carson 390046ccf4 Fix processing of bools and numbers in editorConfig files (#12923) 2024-11-04 18:08:15 -08:00
Ben McMorran fcd0b0c25f Add telemetry for #cpp failures (#12910) 2024-10-30 17:02:51 -07:00
LucaandBen McMorran dc8140199b Ensure only wel known values are passed in to the LLM #2293227 (#12907)
Co-authored-by: Ben McMorran <[email protected]>
2024-10-30 14:32:31 -08:00
Bob Brown 1462b0dacb Normalize messages for bad paths (#12904) 2024-10-30 10:54:22 -07:00
Colen Garoutte-Carson e45dbcec9b Fix issue with requests in protocolFilter.ts causing stalls (#12906) 2024-10-29 18:46:13 -07:00
Sean McManus f51404d9db Switch to @vscode/dts. (#12901) 2024-10-29 17:57:47 -07:00
89 changed files with 1436 additions and 303 deletions
+1 -1
View File
@@ -10,6 +10,6 @@ jobs:
job:
uses: ./.github/workflows/job-compile-and-test.yml
with:
runner-env: macos-12
runner-env: macos-14
platform: mac
yarn-args: --network-timeout 100000
+8
View File
@@ -0,0 +1,8 @@
# Each line is a file pattern followed by one or more owners.
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @microsoft/cpptools-maintainers will be requested for
# review when someone opens a pull request.
* @microsoft/cpptools-maintainers
+38
View File
@@ -1,5 +1,43 @@
# C/C++ for Visual Studio Code Changelog
### Version 1.23.2: December 5, 2024
### Enhancements
* Changes to how paths are internally canonicalized on Linux and macOS, avoiding file system access to improve performance and delay resolution of symbolic links. [#12924](https://github.com/microsoft/vscode-cpptools/issues/12924)
* Add handling of `-fno-char8_t` and `-fchar8_t` compiler arguments. [#12968](https://github.com/microsoft/vscode-cpptools/issues/12968)
* Add support for providing well-known compiler argument information to Copilot Completions. [PR #12979](https://github.com/microsoft/vscode-cpptools/pull/12979)
* Fixed unnecessary cancellation of Copilot context requests. [PR #12988](https://github.com/microsoft/vscode-cpptools/pull/12988)
* Add support for passing an additional parameter to `C_Cpp.ConfigurationSelect` command. [PR #12993](https://github.com/microsoft/vscode-cpptools/pull/12993)
* Thank you for the contribution. [@adrianstephens](https://github.com/adrianstephens)
* Update clang-format and clang-tidy from 19.1.2 to 19.1.5.
### Bug Fixes
* Increase clang-format timeout from 10 seconds to 30 seconds. [#10213](https://github.com/microsoft/vscode-cpptools/issues/10213)
* Fix casing of path in include completion tooltip on Windows. [#12895](https://github.com/microsoft/vscode-cpptools/issues/12895)
* Fix pattern matching of sections in `.editorConfig` files. [#12933](https://github.com/microsoft/vscode-cpptools/issues/12933)
* Fix handling of relative paths passed to cl.exe `/reference` argument. [#12944](https://github.com/microsoft/vscode-cpptools/issues/12944)
* Fix a leak of compile command file watchers. [#12946](https://github.com/microsoft/vscode-cpptools/issues/12946)
* Thank you for the contribution. [@yiftahw](https://github.com/yiftahw) [PR #12948](https://github.com/microsoft/vscode-cpptools/pull/12948)
* Fix a compile commands fallback logic issue. [#12947](https://github.com/microsoft/vscode-cpptools/issues/12947)
* Thank you for the contribution. [@yiftahw](https://github.com/yiftahw) [PR #12948](https://github.com/microsoft/vscode-cpptools/pull/12948)
* Fix an issue in which a `didOpen` event was processed before the language client was fully started. [#12954](https://github.com/microsoft/vscode-cpptools/issues/12954)
* Fix IntelliSense issues related to large header files (>32K) and encodings other than UTF-8.
* Fix a deadlock.
### Version 1.23.1: November 6, 2024
### Bug Fixes
* A potential fix for a crash during process shutdown (in `uv_run`). [#12668](https://github.com/microsoft/vscode-cpptools/issues/12668)
* Fix a performance issue where some LSP requests would delay other LSP requests. [#12905](https://github.com/microsoft/vscode-cpptools/issues/12905)
* A potential fix for a crash in cpptools (in `report_intellisense_results`).
* Fix a random deadlock with `compiler_info::find_or_create`.
* Fix a random deadlock with `handle_edits`.
* Other internal fixes.
## Version 1.22.11: November 5, 2024
### Bug Fixes
* Fix system includes incorrectly being treated as non-system includes when specified with `-I`. [#12842](https://github.com/microsoft/vscode-cpptools/issues/12842)
* Fix inactive region ranges when multi-byte UTF-8 characters are used. [#12879](https://github.com/microsoft/vscode-cpptools/issues/12879)
* Fix formatting with `.editorconfig` files. [#12921](https://github.com/microsoft/vscode-cpptools/issues/12921)
## Version 1.23.0: October 29, 2024
### Enhancements
* Update to clang-format and clang-tidy 19.1.2. [#12824](https://github.com/microsoft/vscode-cpptools/issues/12824)
+26
View File
@@ -2429,6 +2429,7 @@ The notices below are from non-npm sources.
- ANTLR (http://www.antlr2.org/)
- C++11 Sublime Text Snippets (https://github.com/Rapptz/cpp-sublime-snippet)
- Clang (https://clang.llvm.org/)
- editorconfig-core-js (https://github.com/editorconfig/editorconfig-core-js)
- gcc-11/libgcc (https://packages.ubuntu.com/jammy/gcc-11-base)
- Guidelines Support Library (https://github.com/Microsoft/GSL)
- libc++ (https://libcxx.llvm.org/index.html)
@@ -2677,6 +2678,31 @@ mechanisms:
=========================================
END OF Clang NOTICES AND INFORMATION
%% editorconfig-core-js NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright © 2012 EditorConfig Team
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 editorconfig-core-js NOTICES AND INFORMATION
%% gcc-9/libgcc NOTICES AND INFORMATION BEGIN HERE
=========================================
The following runtime libraries are licensed under the terms of the
@@ -16,7 +16,7 @@
"compiler.path.not.exists": "找不到 {0}。将忽略 {1} 任务。",
"pre.Launch.Task": "preLaunchTask: {0}",
"debugger.path.not.exists": "找不到 {0} 调试器。将忽略 {1} 的调试配置。",
"build.and.debug.active.file": "生成和调试活动文件",
"build.and.debug.active.file": "构建和调试活动文件",
"cl.exe.not.available": "仅当从 VS 开发人员命令提示符处运行 VS Code 时,{0} 生成和调试才可用。",
"lldb.find.failed": "缺少 lldb-mi 可执行文件的依赖项“{0}”。",
"lldb.search.paths": "搜索范围:",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "路径不是文件: {0}",
"path.is.not.a.directory": "路径不是目录: {0}",
"duplicate.name": "{0} 重复。配置名称应是唯一的。",
"cannot.find2": "无法找到“{0}”。",
"multiple.paths.not.allowed": "不允许使用多个路径。",
"paths.are.not.directories": "路径不是目录: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "函数必须通过引用返回一个值。C 代码不能返回引用。",
"refactor_extract_xborder_jump": "所选代码和外层代码之间的存在跳跃。",
"refactor_extract_missing_return": "在所选代码中,一些控制路径退出而没有设置返回值。这只受标量、数字、和指针返回类型支持。",
"expand_selection": "展开选择(以启用“提取到函数”)"
"expand_selection": "展开选择(以启用“提取到函数”)",
"file_not_found_in_path2": "在 compile_commands.json 文件中找不到 \"{0}\"。此文件将改用文件夹“{1}”中的 c_cpp_properties.json 中包含的 \"includePath\"。"
}
@@ -6,6 +6,6 @@
{
"walkthrough.windows.title.open.dev.command.prompt": "使用开发人员命令提示符重新启动",
"walkthrough.windows.background.dev.command.prompt": "正在使用带有 MSVC 编译器的 Windows 机器,因此需要从开发人员命令提示符中启动 VS Code,以便所有环境变量都能正确设置。要使用开发人员命令提示符重新启动:",
"walkthrough.open.command.prompt": "通过在 Windows 开始菜单中键入 \"developer\" 来打开 VS 的开发人员命令提示提示。选择 VS 的开发人员命令提示提示,它将自动导航到当前打开的文件夹。",
"walkthrough.open.command.prompt": "通过在 Windows 开始菜单中键入 \"developer\" 来打开 VS 的开发人员命令提示。选择 VS 的开发人员命令提示,它将自动导航到当前打开的文件夹。",
"walkthrough.windows.press.f5": "在命令提示符中键入 \"code\",然后按 Enter。这应该重新启动 VS Code 并将你带回此演练。"
}
@@ -20,6 +20,6 @@
"walkthrough.windows.command.prompt.name1": "VS 的 Developer 命令提示",
"walkthrough.windows.check.install": "在 VS 的开发人员命令提示中键入 {0} 以检查 MSVC 安装。你应该会看到包含版本和基本使用说明的版权消息。",
"walkthrough.windows.note2": "注意",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、 {2})或 Windows 命令提示符未设置必要的路径环境变量。",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、{2} 或 Windows 命令提示符)未设置必要的路径环境变量。",
"walkthrough.windows.command.prompt.name2": "VS 的开发人员命令提示"
}
@@ -14,7 +14,7 @@
"walkthrough.windows.command.prompt.name1": "VS 的 Developer 命令提示",
"walkthrough.windows.check.install": "在 VS 的开发人员命令提示中键入 {0} 以检查 MSVC 安装。你应该会看到包含版本和基本使用说明的版权消息。",
"walkthrough.windows.note2": "注意",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、 {2})或 Windows 命令提示符未设置必要的路径环境变量。",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、{2} 或 Windows 命令提示符)未设置必要的路径环境变量。",
"walkthrough.windows.command.prompt.name2": "VS 的开发人员命令提示",
"walkthrough.windows.other.compilers": "其他编译器选项",
"walkthrough.windows.text3": "如果面向的是 Windows 中的 Linux,请查看{0}。或者,可{1}。",
@@ -14,7 +14,7 @@
"walkthrough.windows.command.prompt.name1": "VS 的 Developer 命令提示",
"walkthrough.windows.check.install": "在 VS 的开发人员命令提示中键入 {0} 以检查 MSVC 安装。你应该会看到包含版本和基本使用说明的版权消息。",
"walkthrough.windows.note2": "注意",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、 {2})或 Windows 命令提示符未设置必要的路径环境变量。",
"walkthrough.windows.note2.text": "要从命令行或 VS Code 使用 MSVC,必须从 {0} 运行。普通 shell (例如 {1}、{2} 或 Windows 命令提示符)未设置必要的路径环境变量。",
"walkthrough.windows.command.prompt.name2": "VS 的开发人员命令提示",
"walkthrough.windows.other.compilers": "其他编译器选项",
"walkthrough.windows.text3": "如果面向的是 Windows 中的 Linux,请查看{0}。或者,可{1}。",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "路徑不是檔案: {0}",
"path.is.not.a.directory": "路徑不是目錄: {0}",
"duplicate.name": "{0} 重複。組態名稱應該是唯一的。",
"cannot.find2": "找不到 \"{0}\"。",
"multiple.paths.not.allowed": "不允許使用多個路徑。",
"paths.are.not.directories": "路徑不是目錄: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "函式必須藉傳址傳回值。C 程式碼無法傳回參考。",
"refactor_extract_xborder_jump": "所選程式碼與周圍的程式碼之間存在跳躍。",
"refactor_extract_missing_return": "在選取的程式碼中,有一些控制項路徑未設定傳回值便結束。只有純量、數值與指標傳回類型支援此作法。",
"expand_selection": "展開選取範圍 (以啟用 [擷取至函式])"
"expand_selection": "展開選取範圍 (以啟用 [擷取至函式])",
"file_not_found_in_path2": "在 compile_commands.json 檔案中找不到 \"{0}\"。將對此檔案改用資料夾 '{1}' 中 c_cpp_properties.json 的 'includePath'。"
}
+1 -1
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Formátování",
"c_cpp.subheaders.codeDocumentation.title": "Dokumentace ke kódu",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Analýza kódu",
"c_cpp.subheaders.debugging.title": "Ladění",
"c_cpp.subheaders.resourceManagement.title": "Správa prostředků",
"c_cpp.subheaders.miscellaneous.title": "Různé",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Cesta není soubor: {0}",
"path.is.not.a.directory": "Cesta není adresář: {0}",
"duplicate.name": "{0} je duplicitní. Název konfigurace by měl být jedinečný.",
"cannot.find2": "Nejde najít {0}.",
"multiple.paths.not.allowed": "Více cest není povoleno.",
"paths.are.not.directories": "Cesty nejsou adresáře: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "Funkce by musela vracet hodnotu pomocí odkazu. Kód C nemůže vracet odkazy.",
"refactor_extract_xborder_jump": "Přecházení mezi vybraným kódem a okolním kódem jsou k dispozici.",
"refactor_extract_missing_return": "Ve vybraném kódu se některé cesty ovládacího prvku ukončují bez nastavení návratové hodnoty. To se podporuje jenom u skalárních, numerických a ukazovacích návratových typů.",
"expand_selection": "Rozbalit výběr (pro povolení možnosti Extrahovat do funkce)"
"expand_selection": "Rozbalit výběr (pro povolení možnosti Extrahovat do funkce)",
"file_not_found_in_path2": "\"{0}\" not found in compile_commands.json files. 'includePath' from c_cpp_properties.json in folder '{1}' will be used for this file instead."
}
+1 -1
View File
@@ -39,7 +39,7 @@
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "Codeanalyse für aktive Dateien ausführen",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "Codeanalyse für geöffnete Dateien ausführen",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "Codeanalyse für alle Dateien ausführen",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Alle Code Analysis Probleme löschen",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Alle Codeanalyseprobleme löschen",
"c_cpp.command.BuildAndDebugFile.title": "C/C++-Datei debuggen",
"c_cpp.command.BuildAndRunFile.title": "C/C++-Datei ausführen",
"c_cpp.command.AddDebugConfiguration.title": "Debugkonfiguration hinzufügen",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Der Pfad ist keine Datei: {0}",
"path.is.not.a.directory": "Der Pfad ist kein Verzeichnis: {0}",
"duplicate.name": "\"{0}\" ist ein Duplikat. Der Konfigurationsname muss eindeutig sein.",
"cannot.find2": "\"{0}\" wurde nicht gefunden.",
"multiple.paths.not.allowed": "Mehrere Pfade sind nicht zulässig.",
"paths.are.not.directories": "Pfade sind keine Verzeichnisse: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "Die Funktion muss einen Wert durch Verweis zurückgeben. C-Code kann keine Verweise zurückgeben.",
"refactor_extract_xborder_jump": "Es sind Sprünge zwischen dem ausgewählten und dem umgebenden Code vorhanden.",
"refactor_extract_missing_return": "Im ausgewählten Code werden einige Steuerungspfade beendet, ohne den Rückgabewert festzulegen. Dies wird nur für skalare, numerische und Zeigerrückgabetypen unterstützt.",
"expand_selection": "Auswahl erweitern (um „In Funktion extrahieren“ zu aktivieren)"
"expand_selection": "Auswahl erweitern (um „In Funktion extrahieren“ zu aktivieren)",
"file_not_found_in_path2": "„{0}“ wurde in compile_commands.json-Dateien nicht gefunden. Stattdessen wird „includePath“ aus „c_cpp_properties.json“ im Ordner „{1}“ für diese Datei verwendet."
}
+1 -1
View File
@@ -39,7 +39,7 @@
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "Ejecutar análisis de código en el archivo activo",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "Ejecutar análisis de código en archivos abiertos",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "Ejecutar análisis de código en todos los archivos",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Borrar todos los problemas de Code Analysis",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Borrar todos los problemas de análisis de código",
"c_cpp.command.BuildAndDebugFile.title": "Depurar archivo C/C++",
"c_cpp.command.BuildAndRunFile.title": "Ejecutar archivo C/C++",
"c_cpp.command.AddDebugConfiguration.title": "Agregar configuración de depuración",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "La ruta de acceso no es un archivo: {0}",
"path.is.not.a.directory": "La ruta de acceso no es un directorio: {0}",
"duplicate.name": "{0} es un duplicado. El nombre de la configuración debe ser único.",
"cannot.find2": "No se encuentra \"{0}\".",
"multiple.paths.not.allowed": "No se permiten varias rutas de acceso.",
"paths.are.not.directories": "Las rutas de acceso no son directorios: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "La función debería devolver un valor por referencia. El código C no puede devolver referencias.",
"refactor_extract_xborder_jump": "Hay saltos entre el código seleccionado y el código que lo rodea.",
"refactor_extract_missing_return": "En el código seleccionado, algunas rutas de control salen sin establecer el valor devuelto. Esto se admite solo para tipos de valor devuelto escalar, numérico y puntero.",
"expand_selection": "Expandir selección (para habilitar 'Extraer a función')"
"expand_selection": "Expandir selección (para habilitar 'Extraer a función')",
"file_not_found_in_path2": "\"{0}\" no se encuentra en compile_commands.json archivos. ''includePath'' de c_cpp_properties.json de la carpeta ''{1}'' se usará en su lugar para este archivo."
}
+1 -1
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Mise en forme",
"c_cpp.subheaders.codeDocumentation.title": "Documentation du code",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Analyse du code",
"c_cpp.subheaders.debugging.title": "Débogage",
"c_cpp.subheaders.resourceManagement.title": "Gestion des ressources",
"c_cpp.subheaders.miscellaneous.title": "Divers",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Le chemin n'est pas un fichier : {0}",
"path.is.not.a.directory": "Le chemin n'est pas un répertoire : {0}",
"duplicate.name": "{0} est dupliqué. Le nom de configuration doit être unique.",
"cannot.find2": "\"{0}\" est introuvable.",
"multiple.paths.not.allowed": "Il est interdit dutiliser plusieurs chemin daccès.",
"paths.are.not.directories": "Les chemins daccès ne sont pas des répertoires : {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "La fonction doit renvoyer une valeur par référence. Le code C ne peut pas renvoyer de référence.",
"refactor_extract_xborder_jump": "Des sauts entre le code sélectionné et le code environnant sont présents.",
"refactor_extract_missing_return": "Dans le code sélectionné, certains chemins de contrôle s'arrêtent sans définir la valeur renvoyée. Cela n'est pris en charge que pour les types de retour scalaire, numérique et pointeur.",
"expand_selection": "Développer la sélection (pour activer ' Extraire vers la fonction')"
"expand_selection": "Développer la sélection (pour activer ' Extraire vers la fonction')",
"file_not_found_in_path2": "« {0} » n'a pas été trouvé dans les fichiers compile_commands.json. « includePath » from c_cpp_properties.json in folder « {1} » sera utilisé pour ce fichier à la place."
}
+3 -3
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Formattazione",
"c_cpp.subheaders.codeDocumentation.title": "Documentazione del codice",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Analisi codice",
"c_cpp.subheaders.debugging.title": "Debug",
"c_cpp.subheaders.resourceManagement.title": "Gestione risorse",
"c_cpp.subheaders.miscellaneous.title": "Varie",
@@ -39,7 +39,7 @@
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "Esegui analisi del codice su File attivo",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "Esegui analisi del codice su Apri file",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "Esegui analisi del codice su Tutti i file",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Cancellare tutti i problemi Code Analysis",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Cancellare tutti i problemi di analisi codice",
"c_cpp.command.BuildAndDebugFile.title": "Debug file C/C++",
"c_cpp.command.BuildAndRunFile.title": "Esegui file C/C++",
"c_cpp.command.AddDebugConfiguration.title": "Aggiungere configurazione di debug",
@@ -70,7 +70,7 @@
"c_cpp.configuration.codeAnalysis.runAutomatically.markdownDescription": "Se è `true`, analisi del codice verrà eseguito automaticamente su un file dopo l'apertura o il salvataggio.",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showDisable.markdownDescription": "Se è `true`, l'azione codice 'Disabilita' verrà visualizzata quando disponibile (all'analisi codice successiva). Quando si usa l'azione codice 'Disabilita', aggiunge il codice di avviso all'impostazione `C_Cpp.codeAnalysis.clangTidy.checks.disabled`.",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showDocumentation.markdownDescription": "Se è `true`, l'azione codice 'Mostra documentazione per' verrà visualizzata quando disponibile (all'analisi codice successiva).",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showClear.description": "Controlla quali opzioni di azione codice per il problema Code Analysis 'Cancella' sono disponibili. La modifica dell'impostazione per visualizzare altre opzioni potrebbe richiedere la ripetizione dell'analisi codice.",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showClear.description": "Controlla quali opzioni di azione codice per il problema di analisi codice 'Cancella' sono disponibili. La modifica dell'impostazione per visualizzare altre opzioni potrebbe richiedere la ripetizione dell'analisi codice.",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showClear.None.description": "Non mostrare azioni codice 'Cancella'.",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showClear.AllOnly.description": "Mostrare solo l'azione codice 'Cancella tutto' (o 'Cancella tutti <type>' se è presente un solo tipo o 'Cancella questo' se è presente un solo problema).",
"c_cpp.configuration.codeAnalysis.clangTidy.codeAction.showClear.AllAndAllType.description": "Mostrare l'azione codice 'Cancella tutto' (se sono presenti più tipi di problema) e l'azione codice 'Cancella tutti <type>' (o 'Cancella questo' se è presente un solo problema per <type>)",
@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"fix.all.code.analysis.problems": "Correggere tutti i problemi Code Analysis",
"clear.all.code.analysis.problems": "Cancellare tutti i problemi di Code Analysis",
"fix.all.code.analysis.problems": "Correggere tutti i problemi analisi codice",
"clear.all.code.analysis.problems": "Cancellare tutti i problemi di analisi codice",
"fix.all.type.problems": "Correggere tutti i problemi {0}",
"disable.all.type.problems": "Disabilitare tutti i problemi {0}",
"clear.all.type.problems": "Cancellare tutti i problemi {0}",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Il percorso non è un file: {0}",
"path.is.not.a.directory": "Il percorso non è una directory: {0}",
"duplicate.name": "{0} è duplicato. Il nome della configurazione deve essere univoco.",
"cannot.find2": "Non è possibile trovare \"{0}\".",
"multiple.paths.not.allowed": "Più percorsi non sono consentiti.",
"paths.are.not.directories": "I percorsi non sono directory: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -16,7 +16,7 @@
"configuration.select.first": "Apri prima una cartella per selezionare una configurazione.",
"configuration.provider.select.first": "Apri prima una cartella per selezionare un provider di configurazione.",
"edit.configurations.open.first": "Aprire prima una cartella per modificare le configurazioni",
"code.action.aborted": "Impossibile applicare la correzione di Code Analysis perché il documento è stato modificato.",
"code.action.aborted": "Impossibile applicare la correzione di analisi codice perché il documento è stato modificato.",
"prerelease.message": "È disponibile una versione non definitiva dell'estensione C/C++. Passare a questa versione?",
"yes.button": "Sì",
"no.button": "No"
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -33,7 +33,7 @@
"startup.codeanalysis.status": "Avvio...",
"c.cpp.codeanalysis.statusbar.showRunNowOptions": "Esegui",
"running.analysis.processed.tooltip": "In esecuzione: {0} / {1} ({2}%)",
"select.code.analysis.command": "Selezionare un comando di Code Analysis...",
"select.code.analysis.command": "Selezionare un comando di analisi codice...",
"cancel.analysis": "Annulla",
"resume.analysis": "Riprendi",
"pause.analysis": "Sospendi",
@@ -241,7 +241,7 @@
"inline_macro": "Macro inline",
"unable_to_access_browse_database": "Impossibile accedere al database di esplorazione. ({0})",
"default_compiler_path_modified_explicit_intellisense_mode": "IntelliSenseMode è stato modificato perché non corrisponde al compilatore rilevato. Provare a impostare \"compilerPath\". Impostare \"compilerPath\" su \"\" per disabilitare il rilevamento delle inclusioni e delle definizioni del sistema.",
"remove_all_code_analysis_problems": "Rimuovere tutti i problemi Code Analysis",
"remove_all_code_analysis_problems": "Rimuovere tutti i problemi analisi codice",
"multiple_locations_note": "(Più località)",
"folder_tag": "Cartella",
"file_tag": "File",
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "La funzione deve restituire un valore per riferimento. Il codice C non è in grado di restituire riferimenti.",
"refactor_extract_xborder_jump": "Sono presenti collegamenti tra il codice selezionato e quello circostante.",
"refactor_extract_missing_return": "Nel codice selezionato alcuni percorsi di controllo terminano senza impostare il valore restituito. Questo comportamento è supportato solo per tipi restituiti scalari, numerici e puntatore.",
"expand_selection": "Espandi selezione (per abilitare 'Estrai in funzione')"
"expand_selection": "Espandi selezione (per abilitare 'Estrai in funzione')",
"file_not_found_in_path2": "\"{0}\" non è stato trovato nei file compile_commands.json. In alternativa per questo file verrà usato ''includePath'' del file c_cpp_properties.json nella cartella ''{1}''."
}
+2 -2
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "書式設定",
"c_cpp.subheaders.codeDocumentation.title": "コード ドキュメント",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "コード分析",
"c_cpp.subheaders.debugging.title": "デバッグ",
"c_cpp.subheaders.resourceManagement.title": "リソース管理",
"c_cpp.subheaders.miscellaneous.title": "その他",
@@ -449,4 +449,4 @@
"c_cpp.configuration.refactoring.includeHeader.never.description": "ヘッダー ファイルを含めることはありません。",
"c_cpp.languageModelTools.configuration.displayName": "C/C++ 構成",
"c_cpp.languageModelTools.configuration.userDescription": "言語標準バージョンやターゲット プラットフォームなど、アクティブ C または C++ ファイルの構成。"
}
}
@@ -16,7 +16,6 @@
"path.is.not.a.file": "パスがファイルではありません: {0}",
"path.is.not.a.directory": "パスがディレクトリではありません: {0}",
"duplicate.name": "{0} が重複しています。構成名は一意である必要があります。",
"cannot.find2": "\"{0}\" が見つかりません。",
"multiple.paths.not.allowed": "複数のパスは使用できません。",
"paths.are.not.directories": "パスはディレクトリではありません: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "関数は参照渡しで値を返す必要があります。C コードは参照を返すことができません。",
"refactor_extract_xborder_jump": "選択したコードと周囲のコードの間にジャンプが存在します。",
"refactor_extract_missing_return": "選択したコードでは、戻り値を設定せずに一部のコントロール パスが終了します。これは、スカラー型、数値型、およびポインター型の戻り値に対してのみサポートされます。",
"expand_selection": "選択範囲を展開する ([関数に抽出] を有効にする)"
"expand_selection": "選択範囲を展開する ([関数に抽出] を有効にする)",
"file_not_found_in_path2": "\"{0}\" が compile_commands.json ファイルに見つかりません。フォルダー '{1}' にある c_cpp_properties.json からの 'includePath' が、このファイルで代わりに使用されます。"
}
+2 -2
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "서식 지정",
"c_cpp.subheaders.codeDocumentation.title": "코드 설명서",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "코드 분석",
"c_cpp.subheaders.debugging.title": "디버깅",
"c_cpp.subheaders.resourceManagement.title": "리소스 관리",
"c_cpp.subheaders.miscellaneous.title": "기타",
@@ -39,7 +39,7 @@
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "활성 파일에서 코드 분석 실행",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "열린 파일에서 코드 분석 실행",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "모든 파일에 대한 코드 분석 실행",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "모든 Code Analysis 문제 해결",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "모든 코드 분석 문제 해결",
"c_cpp.command.BuildAndDebugFile.title": "C/C++ 파일 디버그",
"c_cpp.command.BuildAndRunFile.title": "C/C++ 파일 실행",
"c_cpp.command.AddDebugConfiguration.title": "디버그 구성 추가",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "경로가 파일이 아닙니다. {0}",
"path.is.not.a.directory": "경로가 디렉터리가 아닙니다. {0}",
"duplicate.name": "{0}은(는) 중복됩니다. 구성 이름은 고유해야 합니다.",
"cannot.find2": "\"{0}\"을(를) 찾을 수 없습니다.",
"multiple.paths.not.allowed": "여러 경로는 허용되지 않습니다.",
"paths.are.not.directories": "경로는 디렉터리가 아닙니다. {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "이 함수는 값을 참조로 반환해야 합니다. C 코드는 참조를 반환할 수 없습니다.",
"refactor_extract_xborder_jump": "선택된 코드와 주변 코드 사이에 점프가 있습니다.",
"refactor_extract_missing_return": "선택된 코드에서 일부 제어 경로가 반환 값 설정 없이 종료됩니다. 이는 스칼라, 숫자 및 포인터 반환 형식에 대해서만 지원됩니다.",
"expand_selection": "선택 영역 확장('함수로 추출'을 사용하도록 설정)"
"expand_selection": "선택 영역 확장('함수로 추출'을 사용하도록 설정)",
"file_not_found_in_path2": "compile_commands.json 파일에서 \"{0}\"을(를) 찾을 수 없습니다. '{1}' 폴더의 c_cpp_properties.json 'includePath'가 대신 이 파일에 사용됩니다."
}
+2 -2
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Formatowanie",
"c_cpp.subheaders.codeDocumentation.title": "Dokumentacja dotyczące kodu",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Analiza kodu",
"c_cpp.subheaders.debugging.title": "Debugowanie",
"c_cpp.subheaders.resourceManagement.title": "Zarządzanie zasobami",
"c_cpp.subheaders.miscellaneous.title": "Różne",
@@ -63,7 +63,7 @@
"c_cpp.configuration.references.maxMemory.markdownDescription": "Mniej procesów „Znajdź wszystkie odwołania” i „Zmień nazwę” będzie buforowanych i uruchamianych współbieżnie po przekroczeniu tego użycia pamięci (w MB). Wartość domyślna `null` (pusta) używa wartości dziedziczonej z elementu `#C_Cpp.maxMemory#`.",
"c_cpp.configuration.codeAnalysis.maxConcurrentThreads.markdownDescription": "Maksymalna liczba współbieżnych wątków do użycia na potrzeby analizy kodu. Wartość domyślna `null` (pusta) używa połowy wartości elementu `#C_Cpp.maxConcurrentThreads#`.",
"c_cpp.configuration.codeAnalysis.maxMemory.markdownDescription": "Mniej procesów analizy kodu będzie uruchamianych współbieżnie po przekroczeniu tego użycia pamięci (w MB). Wartość domyślna `null` (pusta) używa wartości dziedziczonej z elementu `#C_Cpp.maxMemory#`.",
"c_cpp.configuration.codeAnalysis.updateDelay.markdownDescription": "Steruje opóźnieniem w milisekundach zanim rozszerzenie Code Analysis rozpocznie przetwarzanie po wyzwoleniu zapisu z edycji, gdy właściwość `#files.autoSave#` ma wartość `afterDelay`, a właściwość `#C_Cpp.codeAnalysis.runAutomatically#` ma wartość `true`.",
"c_cpp.configuration.codeAnalysis.updateDelay.markdownDescription": "Steruje opóźnieniem w milisekundach, zanim analiza kodu rozpocznie przetwarzanie po wyzwoleniu zapisu z edycji, gdy właściwość `#files.autoSave#` ma wartość `afterDelay`, a właściwość `#C_Cpp.codeAnalysis.runAutomatically#` ma wartość `true`.",
"c_cpp.configuration.codeAnalysis.exclude.markdownDescription": "Skonfiguruj wzorce globalne dla wykluczania folderów i plików na potrzeby analizy kodu. Pliki, które nie znajdują się w folderze obszaru roboczego, są zawsze wykluczone. Dziedziczy wartości z elementów `#files.exclude#` i `#C_Cpp.files.exclude#`. Przeczytaj więcej o [wzorcach globalnych](https://code.visualstudio.com/docs/editor/codebasics#_advanced-search-options).",
"c_cpp.configuration.codeAnalysis.excludeBoolean.markdownDescription": "Wzorzec globalny do dopasowywania ścieżek do plików. Aby włączyć lub wyłączyć wzorzec, ustaw na wartość `true` lub `false`.",
"c_cpp.configuration.codeAnalysis.excludeWhen.markdownDescription": "Dodatkowe sprawdzenie elementów równorzędnych pasującego pliku. Użyj ciągu `$(basename)` jako zmiennej dla nazwy pasującego pliku.",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Ścieżka nie jest plikiem: {0}",
"path.is.not.a.directory": "Ścieżka nie jest katalogiem: {0}",
"duplicate.name": "Element {0} jest duplikatem. Nazwa konfiguracji musi być unikatowa.",
"cannot.find2": "Nie można znaleźć elementu „{0}”.",
"multiple.paths.not.allowed": "Wiele ścieżek jest niedozwolonych.",
"paths.are.not.directories": "Ścieżki nie są katalogami: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "Funkcja musiałaby zwracać wartość przez referencję. W kodzie języka C nie można zwracać referencji.",
"refactor_extract_xborder_jump": "Występują skoki między zaznaczonym kodem a otaczającym kodem.",
"refactor_extract_missing_return": "W zaznaczonym kodzie niektóre ścieżki kontroli kończą działanie bez ustawienia zwracanej wartości. Jest to obsługiwane tylko w przypadku zwracanych typów skalarnych, liczbowych i wskaźnikowych.",
"expand_selection": "Rozwiń wybór (aby włączyć opcję „Wyodrębnij do funkcji”)"
"expand_selection": "Rozwiń wybór (aby włączyć opcję „Wyodrębnij do funkcji”)",
"file_not_found_in_path2": "\"{0}\" not found in compile_commands.json files. 'includePath' from c_cpp_properties.json in folder '{1}' will be used for this file instead."
}
+5 -5
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Formatação",
"c_cpp.subheaders.codeDocumentation.title": "Documentação do Código",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Análise de Código",
"c_cpp.subheaders.debugging.title": "Depurando",
"c_cpp.subheaders.resourceManagement.title": "Gerenciamento de Recursos",
"c_cpp.subheaders.miscellaneous.title": "Diversos",
@@ -39,7 +39,7 @@
"c_cpp.command.RunCodeAnalysisOnActiveFile.title": "Executar Análise de Código no Arquivo Ativo",
"c_cpp.command.RunCodeAnalysisOnOpenFiles.title": "Executar Análise de Código em Abrir Arquivos",
"c_cpp.command.RunCodeAnalysisOnAllFiles.title": "Executar Análise de Código em Todos os Arquivos",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Limpar Todos os Problemas de Code Analysis",
"c_cpp.command.RemoveAllCodeAnalysisProblems.title": "Limpar Todos os Problemas de Análise de Código",
"c_cpp.command.BuildAndDebugFile.title": "Depurar Arquivo C/C++",
"c_cpp.command.BuildAndRunFile.title": "Executar Arquivo C/C++",
"c_cpp.command.AddDebugConfiguration.title": "Adicionar a Configuração de Depuração",
@@ -430,9 +430,9 @@
"c_cpp.walkthrough.command.prompt.title": "Iniciar no prompt de comando do desenvolvedor",
"c_cpp.walkthrough.command.prompt.description": "Ao usar o compilador Microsoft Visual Studio C++, a extensão C++ exige que você inicie o VS Code no prompt de comando do desenvolvedor. Siga as instruções à direita para reiniciar.\n[Recarregar Janela](command:workbench.action.reloadWindow)",
"c_cpp.walkthrough.run.debug.title": "Executar e depurar o arquivo C++",
"c_cpp.walkthrough.run.debug.mac.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"clang++ - Construir e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.linux.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"g++ - Construir e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.windows.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"cl.exe - Construir e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.mac.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"clang++ - Compilar e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.linux.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"g++ - Compilar e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.windows.description": "Abra seu arquivo C++ e clique no botão play no canto superior direito do editor ou pressione F5 quando estiver no arquivo. Selecione \"cl.exe - Compilar e depurar arquivo ativo\" para executar com o depurador.",
"c_cpp.walkthrough.run.debug.windows.altText": "Imagem mostrando um ponto de interrupção em um arquivo C++, o botão f5 e o símbolo de execução no canto superior direito",
"c_cpp.walkthrough.customize.debugging.title": "Personalizar a depuração",
"c_cpp.walkthrough.customize.debugging.mac.description": "Para personalizar a configuração de depuração, selecione o Explorer na barra de atividades e abra uma pasta que inclua o arquivo C++. Abra o arquivo C++ e selecione \"Adicionar Configuração de Depuração\" à direita do botão reproduzir. A nova configuração de depuração é salva no arquivo launch.json do projeto. \n[Saiba mais](https://code.visualstudio.com/docs/cpp/config-linux#_debug-helloworldcpp)",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "O caminho não é um arquivo: {0}",
"path.is.not.a.directory": "O caminho não é um diretório: {0}",
"duplicate.name": "{0} é uma duplicata. O nome da configuração deve ser exclusivo.",
"cannot.find2": "Não é possível localizar \"{0}\".",
"multiple.paths.not.allowed": "Vários caminhos não são permitidos.",
"paths.are.not.directories": "Os caminhos não são diretórios: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "A função teria que retornar um valor por referência. O código C não pode retornar referências.",
"refactor_extract_xborder_jump": "Saltos entre o código selecionado e o código ao redor estão presentes.",
"refactor_extract_missing_return": "No código selecionado, alguns caminhos de controle são encerrados sem definir o valor retornado. Isso tem suporte apenas para os tipos de retorno escalar, numérico e de ponteiro.",
"expand_selection": "Expandir seleção (para habilitar \"Extrair para função\")"
"expand_selection": "Expandir seleção (para habilitar \"Extrair para função\")",
"file_not_found_in_path2": "\"{0}\" não encontrado nos arquivos compile_commands.json. \"includePath\" de c_cpp_properties.json na pasta \"{1}\" será usado para esse arquivo."
}
+1 -1
View File
@@ -7,7 +7,7 @@
"c_cpp.subheaders.intelliSense.title": "IntelliSense",
"c_cpp.subheaders.formatting.title": "Форматирование",
"c_cpp.subheaders.codeDocumentation.title": "Документирование кода",
"c_cpp.subheaders.codeAnalysis.title": "Code Analysis",
"c_cpp.subheaders.codeAnalysis.title": "Анализ кода",
"c_cpp.subheaders.debugging.title": "Отладка",
"c_cpp.subheaders.resourceManagement.title": "Управление ресурсами",
"c_cpp.subheaders.miscellaneous.title": "Прочее",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Путь не является файлом: {0}",
"path.is.not.a.directory": "Путь не является каталогом: {0}",
"duplicate.name": "{0} является дубликатом. Имя конфигурации должно быть уникальным.",
"cannot.find2": "Не удается найти \"{0}\".",
"multiple.paths.not.allowed": "Запрещено использовать несколько путей.",
"paths.are.not.directories": "Пути не являются каталогами: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "Функция предполагает возврат значения по ссылке. Код C не может возвращать ссылки.",
"refactor_extract_xborder_jump": "Есть переходы между выбранным кодом и окружающим его кодом.",
"refactor_extract_missing_return": "В выбранном коде некоторые контрольные пути завершаются без установки возвращаемого значения. Это поддерживается только для скалярных, числовых типов возвращаемого значения и типов возвращаемого значения-указателей.",
"expand_selection": "Развернуть выделенный фрагмент (чтобы включить функцию \"Извлечение в функцию\")"
"expand_selection": "Развернуть выделенный фрагмент (чтобы включить функцию \"Извлечение в функцию\")",
"file_not_found_in_path2": "\"{0}\" не найден в файлах compile_commands.json. Вместо него для этого файла будет использоваться \"includePath\" из файла c_cpp_properties.json в папке \"{1}\"."
}
+3 -3
View File
@@ -430,9 +430,9 @@
"c_cpp.walkthrough.command.prompt.title": "Geliştirici komut istemini kullanarak yeniden başlat",
"c_cpp.walkthrough.command.prompt.description": "Microsoft Visual Studio C++ derleyicisini kullanırken, C++ uzantısı, geliştirici komut isteminden VS Code'u başlatmanızı gerektirir. Yeniden başlatmak için sağdaki talimatları izleyin.\n[Yeniden Yükleme Penceresi](command:workbench.action.reloadWindow)",
"c_cpp.walkthrough.run.debug.title": "C++ dosyanızı çalıştırın ve hata ayıklayın",
"c_cpp.walkthrough.run.debug.mac.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"clang++ - Etkin dosya oluştur ve hata ayıkla\" seçeneğini seçin.",
"c_cpp.walkthrough.run.debug.linux.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"g++ - Aktif dosya oluştur ve hata ayıkla\"yı seçin.",
"c_cpp.walkthrough.run.debug.windows.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"cl.exe - Etkin dosya oluştur ve hata ayıkla\" seçeneğini seçin.",
"c_cpp.walkthrough.run.debug.mac.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"clang++ - Etkin dosya derle ve hata ayıkla\" seçeneğini seçin.",
"c_cpp.walkthrough.run.debug.linux.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"g++ - Aktif dosya derle ve hata ayıkla\"yı seçin.",
"c_cpp.walkthrough.run.debug.windows.description": "C++ dosyanızı açın ve düzenleyicinin sağ üst köşesindeki oynat düğmesine tıklayın veya dosyadayken F5'e basın. Hata ayıklayıcı ile çalıştırmak için \"cl.exe - Etkin dosya derle ve hata ayıkla\" seçeneğini seçin.",
"c_cpp.walkthrough.run.debug.windows.altText": "C++ dosyasında bir kesme noktası, f5 düğmesi ve sağ üstte çalıştır simgesini gösteren resim",
"c_cpp.walkthrough.customize.debugging.title": "Hata ayıklamayı özelleştir",
"c_cpp.walkthrough.customize.debugging.mac.description": "Hata ayıklama yapılandırmanızı özelleştirmek için etkinlik çubuğunda Gezgin'i seçin ve C++ dosyanızı içeren bir klasörü açın. C++ dosyasını açın ve oynat düğmesinin sağındaki \"Hata Ayıklama Yapılandırması Ekle\" seçeneğini seçin. Yeni hata ayıklama yapılandırması projenizin launch.json dosyasına kaydedilir. \n[Learn More](https://code.visualstudio.com/docs/cpp/config-linux#_debug-helloworldcpp)",
@@ -16,7 +16,6 @@
"path.is.not.a.file": "Yol bir dosya değil: {0}",
"path.is.not.a.directory": "Yol bir dizin değil: {0}",
"duplicate.name": "{0} yineleniyor. Yapılandırma adı benzersiz olmalıdır.",
"cannot.find2": "\"{0}\" bulunamıyor.",
"multiple.paths.not.allowed": "Birden fazla yola izin verilmez.",
"paths.are.not.directories": "Yollar dizin değil: {0}"
}
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.relatedfilesprovider.error": "Error while retrieving result. Reason: {0}"
}
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Do not edit this file. It is machine generated.
{
"copilot.projectcontext.error": "Error while retrieving the project context. Reason: {0}",
"copilot.cppcontext.error": "Error while retrieving the #cpp context."
}
@@ -315,5 +315,6 @@
"refactor_extract_reference_return_c_code": "İşlevin başvuruya göre bir değer döndürmesi gerekiyor. C kodu başvuruları döndüremiyor.",
"refactor_extract_xborder_jump": "Seçili kod ile çevreleyen kod arasında atlamalar var.",
"refactor_extract_missing_return": "Seçili kodda bazı denetim yolları, dönüş değeri ayarlanmadan çıkış yapıyor. Bu durum yalnızca skaler, sayısal ve işaretçi dönüş türlerinde desteklenir.",
"expand_selection": "Seçimi genişlet (\"İşleve çıkar\" seçeneğini etkinleştirmek için)"
"expand_selection": "Seçimi genişlet (\"İşleve çıkar\" seçeneğini etkinleştirmek için)",
"file_not_found_in_path2": "\"{0}\" compile_commands.json dosyaları içinde bulunamadı. Bu dosya yerine '{1}' klasöründeki c_cpp_properties.json dosyasında bulunan 'includePath' kullanılacak."
}
+3 -4
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "1.23.0-main",
"version": "1.23.2-main",
"publisher": "ms-vscode",
"icon": "LanguageCCPP_color_128x.png",
"readme": "README.md",
@@ -6511,13 +6511,12 @@
"translations-generate": "set NODE_OPTIONS=--no-experimental-fetch && gulp translations-generate",
"translations-import": "gulp translations-import",
"import-edge-strings": "ts-node -T ./.scripts/import_edge_strings.ts",
"prep:dts": "yarn verify dts --quiet || (npx vscode-dts dev && npx vscode-dts main)",
"prep:dts": "yarn verify dts --quiet || (npx @vscode/dts dev && npx @vscode/dts main)",
"build": "yarn prep:dts && echo [Building TypeScript code] && tsc --build tsconfig.json"
},
"devDependencies": {
"@octokit/rest": "^20.1.1",
"@types/glob": "^7.2.0",
"@types/minimatch": "^3.0.5",
"@types/mocha": "^10.0.6",
"@types/node": "^20.14.2",
"@types/node-fetch": "^2.6.11",
@@ -6569,7 +6568,7 @@
"comment-json": "^4.2.3",
"escape-string-regexp": "^2.0.0",
"glob": "^7.2.3",
"minimatch": "^3.0.5",
"minimatch": "^4.2.0",
"mkdirp": "^3.0.1",
"node-fetch": "^2.7.0",
"node-loader": "^2.0.0",
+51 -15
View File
@@ -541,6 +541,19 @@ export interface ChatContextResult {
targetArchitecture: string;
}
export interface FileContextResult {
compilerArguments: string[];
}
export interface ProjectContextResult {
language: string;
standardVersion: string;
compiler: string;
targetPlatform: string;
targetArchitecture: string;
fileContext: FileContextResult;
}
// Requests
const PreInitializationRequest: RequestType<void, string, void> = new RequestType<void, string, void>('cpptools/preinitialize');
const InitializationRequest: RequestType<CppInitializationParams, void, void> = new RequestType<CppInitializationParams, void, void>('cpptools/initialize');
@@ -560,7 +573,8 @@ const GoToDirectiveInGroupRequest: RequestType<GoToDirectiveInGroupParams, Posit
const GenerateDoxygenCommentRequest: RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult | undefined, void> = new RequestType<GenerateDoxygenCommentParams, GenerateDoxygenCommentResult, void>('cpptools/generateDoxygenComment');
const ChangeCppPropertiesRequest: RequestType<CppPropertiesParams, void, void> = new RequestType<CppPropertiesParams, void, void>('cpptools/didChangeCppProperties');
const IncludesRequest: RequestType<GetIncludesParams, GetIncludesResult, void> = new RequestType<GetIncludesParams, GetIncludesResult, void>('cpptools/getIncludes');
const CppContextRequest: RequestType<void, ChatContextResult, void> = new RequestType<void, ChatContextResult, void>('cpptools/getChatContext');
const CppContextRequest: RequestType<TextDocumentIdentifier, ChatContextResult, void> = new RequestType<TextDocumentIdentifier, ChatContextResult, void>('cpptools/getChatContext');
const ProjectContextRequest: RequestType<TextDocumentIdentifier, ProjectContextResult, void> = new RequestType<TextDocumentIdentifier, ProjectContextResult, void>('cpptools/getProjectContext');
// Notifications to the server
const DidOpenNotification: NotificationType<DidOpenTextDocumentParams> = new NotificationType<DidOpenTextDocumentParams>('textDocument/didOpen');
@@ -762,7 +776,7 @@ export interface Client {
PauseCodeAnalysis(): void;
ResumeCodeAnalysis(): void;
CancelCodeAnalysis(): void;
handleConfigurationSelectCommand(): Promise<void>;
handleConfigurationSelectCommand(config?: string): Promise<void>;
handleConfigurationProviderSelectCommand(): Promise<void>;
handleShowActiveCodeAnalysisCommands(): Promise<void>;
handleShowIdleCodeAnalysisCommands(): Promise<void>;
@@ -790,8 +804,9 @@ export interface Client {
getShowConfigureIntelliSenseButton(): boolean;
setShowConfigureIntelliSenseButton(show: boolean): void;
addTrustedCompiler(path: string): Promise<void>;
getIncludes(maxDepth: number, token: vscode.CancellationToken): Promise<GetIncludesResult>;
getChatContext(token: vscode.CancellationToken): Promise<ChatContextResult>;
getIncludes(maxDepth: number): Promise<GetIncludesResult>;
getChatContext(uri: vscode.Uri, token: vscode.CancellationToken): Promise<ChatContextResult>;
getProjectContext(uri: vscode.Uri): Promise<ProjectContextResult>;
}
export function createClient(workspaceFolder?: vscode.WorkspaceFolder): Client {
@@ -1285,6 +1300,12 @@ export class DefaultClient implements Client {
// Listen for messages from the language server.
this.registerNotifications();
// If a file is already open when we activate, sometimes we don't get any notifications about visible
// or active text editors, visible ranges, or text selection. As a workaround, we trigger
// onDidChangeVisibleTextEditors here.
const cppEditors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => util.isCpp(e.document));
await this.onDidChangeVisibleTextEditors(cppEditors);
}
// update all client configurations
@@ -2207,17 +2228,31 @@ export class DefaultClient implements Client {
await this.languageClient.sendNotification(DidOpenNotification, params);
}
public async getIncludes(maxDepth: number, token: vscode.CancellationToken): Promise<GetIncludesResult> {
/**
* Copilot completion-related requests (e.g. getIncludes and getProjectContext) will have their cancellation tokens cancelled
* if the current request times out (showing the user completion results without context info),
* but the results can still be used for future requests (due to caching) so it's better to return results instead of cancelling.
* This is different behavior from the getChatContext, which does handle cancel requests, since the request blocks
* the UI results and always re-requests (no caching).
*/
public async getIncludes(maxDepth: number): Promise<GetIncludesResult> {
const params: GetIncludesParams = { maxDepth: maxDepth };
await this.ready;
return DefaultClient.withLspCancellationHandling(
() => this.languageClient.sendRequest(IncludesRequest, params, token), token);
return this.languageClient.sendRequest(IncludesRequest, params);
}
public async getChatContext(token: vscode.CancellationToken): Promise<ChatContextResult> {
public async getProjectContext(uri: vscode.Uri): Promise<ProjectContextResult> {
const params: TextDocumentIdentifier = { uri: uri.toString() };
await this.ready;
return this.languageClient.sendRequest(ProjectContextRequest, params);
}
public async getChatContext(uri: vscode.Uri, token: vscode.CancellationToken): Promise<ChatContextResult> {
const params: TextDocumentIdentifier = { uri: uri.toString() };
await withCancellation(this.ready, token);
return DefaultClient.withLspCancellationHandling(
() => this.languageClient.sendRequest(CppContextRequest, null, token), token);
() => this.languageClient.sendRequest(CppContextRequest, params, token), token);
}
/**
@@ -2311,7 +2346,6 @@ export class DefaultClient implements Client {
throw e;
}
}
if (token.isCancellationRequested) {
throw new vscode.CancellationError();
}
@@ -2571,7 +2605,8 @@ export class DefaultClient implements Client {
}
let foundGlobMatch: boolean = false;
for (const assoc in assocs) {
if (minimatch(filePath, assoc)) {
const matcher = new minimatch.Minimatch(assoc);
if (matcher.match(filePath)) {
foundGlobMatch = true;
break; // Assoc matched a glob pattern.
}
@@ -3241,11 +3276,11 @@ export class DefaultClient implements Client {
/**
* command handlers
*/
public async handleConfigurationSelectCommand(): Promise<void> {
public async handleConfigurationSelectCommand(config?: string): Promise<void> {
await this.ready;
const configNames: string[] | undefined = this.configuration.ConfigurationNames;
if (configNames) {
const index: number = await ui.showConfigurations(configNames);
const index: number = config ? configNames.indexOf(config) : await ui.showConfigurations(configNames);
if (index < 0) {
return;
}
@@ -4121,6 +4156,7 @@ class NullClient implements Client {
getShowConfigureIntelliSenseButton(): boolean { return false; }
setShowConfigureIntelliSenseButton(show: boolean): void { }
addTrustedCompiler(path: string): Promise<void> { return Promise.resolve(); }
getIncludes(maxDepth: number, token: vscode.CancellationToken): Promise<GetIncludesResult> { return Promise.resolve({} as GetIncludesResult); }
getChatContext(token: vscode.CancellationToken): Promise<ChatContextResult> { return Promise.resolve({} as ChatContextResult); }
getIncludes(maxDepth: number): Promise<GetIncludesResult> { return Promise.resolve({} as GetIncludesResult); }
getChatContext(uri: vscode.Uri, token: vscode.CancellationToken): Promise<ChatContextResult> { return Promise.resolve({} as ChatContextResult); }
getProjectContext(uri: vscode.Uri): Promise<ProjectContextResult> { return Promise.resolve({} as ProjectContextResult); }
}
+36 -9
View File
@@ -138,7 +138,7 @@ export class CppProperties {
private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
private compileCommandsFile: vscode.Uri | undefined | null = undefined;
private compileCommandsFileWatchers: fs.FSWatcher[] = [];
private compileCommandsFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
private compileCommandsFileWatcherFallbackTime: Map<string, Date> = new Map<string, Date>(); // Used when file watching fails.
private defaultCompilerPath: string | null = null;
private knownCompilers?: KnownCompiler[];
private defaultCStandard: string | null = null;
@@ -1093,6 +1093,10 @@ export class CppProperties {
if (configuration.compileCommands) {
configuration.compileCommands = this.resolvePath(configuration.compileCommands);
if (!this.compileCommandsFileWatcherFallbackTime.has(configuration.compileCommands)) {
// Start tracking the fallback time for a new path.
this.compileCommandsFileWatcherFallbackTime.set(configuration.compileCommands, new Date());
}
}
if (configuration.forcedInclude) {
@@ -1104,12 +1108,31 @@ export class CppProperties {
}
}
this.clearStaleCompileCommandsFileWatcherFallbackTimes();
this.updateCompileCommandsFileWatchers();
if (!this.configurationIncomplete) {
this.onConfigurationsChanged();
}
}
private clearStaleCompileCommandsFileWatcherFallbackTimes(): void {
// We need to keep track of relevant timestamps, so we cannot simply clear all entries.
// Instead, we clear entries that are no longer relevant.
const trackedCompileCommandsPaths: Set<string> = new Set();
this.configurationJson?.configurations.forEach((config: Configuration) => {
const path = this.resolvePath(config.compileCommands);
if (path.length > 0) {
trackedCompileCommandsPaths.add(path);
}
});
for (const path of this.compileCommandsFileWatcherFallbackTime.keys()) {
if (!trackedCompileCommandsPaths.has(path)) {
this.compileCommandsFileWatcherFallbackTime.delete(path);
}
}
}
private compileCommandsFileWatcherTimer?: NodeJS.Timeout;
private compileCommandsFileWatcherFiles: Set<string> = new Set<string>();
@@ -1948,7 +1971,7 @@ export class CppProperties {
compilerPath = checkPathExists.path;
}
if (!compilerPathExists) {
compilerMessage = localize('cannot.find2', "Cannot find \"{0}\".", compilerPath);
compilerMessage = localize('cannot.find', "Cannot find: {0}", compilerPath);
newSquiggleMetrics.PathNonExistent++;
}
if (compilerMessage) {
@@ -1975,7 +1998,7 @@ export class CppProperties {
dotConfigPath = checkPathExists.path;
}
if (!dotConfigPathExists) {
dotConfigMessage = localize('cannot.find2', "Cannot find \"{0}\".", dotConfigPath);
dotConfigMessage = localize('cannot.find', "Cannot find: {0}", dotConfigPath);
newSquiggleMetrics.PathNonExistent++;
} else if (dotConfigPath && !util.checkFileExistsSync(dotConfigPath)) {
dotConfigMessage = localize("path.is.not.a.file", "Path is not a file: {0}", dotConfigPath);
@@ -2083,7 +2106,7 @@ export class CppProperties {
} else {
badPath = `"${expandedPaths[0]}"`;
}
message = localize('cannot.find2', "Cannot find {0}", badPath);
message = localize('cannot.find', "Cannot find: {0}", badPath);
newSquiggleMetrics.PathNonExistent++;
} else {
// Check for file versus path mismatches.
@@ -2141,7 +2164,7 @@ export class CppProperties {
endOffset = curOffset + curMatch.length;
let message: string;
if (!pathExists) {
message = localize('cannot.find2', "Cannot find \"{0}\".", expandedPaths[0]);
message = localize('cannot.find', "Cannot find: {0}", expandedPaths[0]);
newSquiggleMetrics.PathNonExistent++;
const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
new vscode.Range(document.positionAt(envTextStartOffSet + curOffset),
@@ -2310,14 +2333,18 @@ export class CppProperties {
fs.stat(compileCommandsFile, (err, stats) => {
if (err) {
if (err.code === "ENOENT" && this.compileCommandsFile) {
this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close());
this.compileCommandsFileWatchers = []; // reset file watchers
this.onCompileCommandsChanged(compileCommandsFile);
this.compileCommandsFile = null; // File deleted
}
} else if (stats.mtime > this.compileCommandsFileWatcherFallbackTime) {
this.compileCommandsFileWatcherFallbackTime = new Date();
this.onCompileCommandsChanged(compileCommandsFile);
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
} else {
const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile);
if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) {
this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date());
this.onCompileCommandsChanged(compileCommandsFile);
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
}
}
});
}
+114 -29
View File
@@ -5,9 +5,16 @@
'use strict';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as util from '../common';
import { ChatContextResult, GetIncludesResult } from './client';
import * as logger from '../logger';
import * as telemetry from '../telemetry';
import { GetIncludesResult } from './client';
import { getActiveClient } from './extension';
import { getCompilerArgumentFilterMap, getProjectContext } from './lmTool';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
export interface CopilotTrait {
name: string;
@@ -34,35 +41,113 @@ export async function registerRelatedFilesProvider(): Promise<void> {
for (const languageId of ['c', 'cpp', 'cuda-cpp']) {
api.registerRelatedFilesProvider(
{ extensionId: util.extensionContext.extension.id, languageId },
async (_uri: vscode.Uri, context: { flags: Record<string, unknown> }, token: vscode.CancellationToken) => {
async (uri: vscode.Uri, context: { flags: Record<string, unknown> }) => {
const start = performance.now();
const telemetryProperties: Record<string, string> = {};
const telemetryMetrics: Record<string, number> = {};
try {
const getIncludesHandler = async () => (await getIncludes(1))?.includedFiles.map(file => vscode.Uri.file(file)) ?? [];
const getTraitsHandler = async () => {
const projectContext = await getProjectContext(uri, context);
const getIncludesHandler = async () => (await getIncludesWithCancellation(1, token))?.includedFiles.map(file => vscode.Uri.file(file)) ?? [];
const getTraitsHandler = async () => {
const chatContext: ChatContextResult | undefined = await (getActiveClient().getChatContext(token) ?? undefined);
if (!projectContext) {
return undefined;
}
if (!chatContext) {
return undefined;
let traits: CopilotTrait[] = [
{ name: "intelliSenseDisclaimer", value: '', includeInPrompt: true, promptTextOverride: `IntelliSense is currently configured with the following compiler information. It reflects the active configuration, and the project may have more configurations targeting different platforms.` },
{ name: "intelliSenseDisclaimerBeginning", value: '', includeInPrompt: true, promptTextOverride: `Beginning of IntelliSense information.` }
];
if (projectContext.language) {
traits.push({ name: "language", value: projectContext.language, includeInPrompt: true, promptTextOverride: `The language is ${projectContext.language}.` });
}
if (projectContext.compiler) {
traits.push({ name: "compiler", value: projectContext.compiler, includeInPrompt: true, promptTextOverride: `This project compiles using ${projectContext.compiler}.` });
}
if (projectContext.standardVersion) {
traits.push({ name: "standardVersion", value: projectContext.standardVersion, includeInPrompt: true, promptTextOverride: `This project uses the ${projectContext.standardVersion} language standard.` });
}
if (projectContext.targetPlatform) {
traits.push({ name: "targetPlatform", value: projectContext.targetPlatform, includeInPrompt: true, promptTextOverride: `This build targets ${projectContext.targetPlatform}.` });
}
if (projectContext.targetArchitecture) {
traits.push({ name: "targetArchitecture", value: projectContext.targetArchitecture, includeInPrompt: true, promptTextOverride: `This build targets ${projectContext.targetArchitecture}.` });
}
if (projectContext.compiler) {
// We will process compiler arguments based on copilotcppXXXCompilerArgumentFilters and copilotcppCompilerArgumentDirectAskMap feature flags.
// The copilotcppXXXCompilerArgumentFilters are maps. The keys are regex strings for filtering and the values, if not empty,
// are the prompt text to use when no arguments are found.
// copilotcppCompilerArgumentDirectAskMap map individual matched argument to a prompt text.
// For duplicate matches, the last one will be used.
const filterMap = getCompilerArgumentFilterMap(projectContext.compiler, context);
if (filterMap !== undefined) {
const directAskMap: Record<string, string> = context.flags.copilotcppCompilerArgumentDirectAskMap ? JSON.parse(context.flags.copilotcppCompilerArgumentDirectAskMap as string) : {};
let directAsks: string = '';
const remainingArguments: string[] = [];
for (const key in filterMap) {
if (!key) {
continue;
}
const matchedArgument = projectContext.compilerArguments[key] as string;
if (matchedArgument?.length > 0) {
if (directAskMap[matchedArgument]) {
directAsks += `${directAskMap[matchedArgument]} `;
} else {
remainingArguments.push(matchedArgument);
}
} else if (filterMap[key]) {
// Use the prompt text in the absence of argument.
directAsks += `${filterMap[key]} `;
}
}
if (remainingArguments.length > 0) {
const compilerArgumentsValue = remainingArguments.join(", ");
traits.push({ name: "compilerArguments", value: compilerArgumentsValue, includeInPrompt: true, promptTextOverride: `The compiler arguments include: ${compilerArgumentsValue}.` });
}
if (directAsks) {
traits.push({ name: "directAsks", value: directAsks, includeInPrompt: true, promptTextOverride: directAsks });
}
}
}
traits.push({ name: "intelliSenseDisclaimerEnd", value: '', includeInPrompt: true, promptTextOverride: `End of IntelliSense information.` });
const includeTraitsArray = context.flags.copilotcppIncludeTraits ? context.flags.copilotcppIncludeTraits as string[] : [];
const includeTraits = new Set(includeTraitsArray);
telemetryProperties["includeTraits"] = includeTraitsArray.join(',');
// standardVersion trait is enabled by default.
traits = traits.filter(trait => includeTraits.has(trait.name) || trait.name === 'standardVersion');
telemetryProperties["traits"] = traits.map(trait => trait.name).join(',');
return traits.length > 0 ? traits : undefined;
};
// Call both handlers in parallel
const traitsPromise = getTraitsHandler();
const includesPromise = getIncludesHandler();
return { entries: await includesPromise, traits: await traitsPromise };
}
catch (exception) {
try {
const err: Error = exception as Error;
logger.getOutputChannelLogger().appendLine(localize("copilot.relatedfilesprovider.error", "Error while retrieving result. Reason: {0}", err.message));
}
let traits: CopilotTrait[] = [
{ name: "language", value: chatContext.language, includeInPrompt: true, promptTextOverride: `The language is ${chatContext.language}.` },
{ name: "compiler", value: chatContext.compiler, includeInPrompt: true, promptTextOverride: `This project compiles using ${chatContext.compiler}.` },
{ name: "standardVersion", value: chatContext.standardVersion, includeInPrompt: true, promptTextOverride: `This project uses the ${chatContext.standardVersion} language standard.` },
{ name: "targetPlatform", value: chatContext.targetPlatform, includeInPrompt: true, promptTextOverride: `This build targets ${chatContext.targetPlatform}.` },
{ name: "targetArchitecture", value: chatContext.targetArchitecture, includeInPrompt: true, promptTextOverride: `This build targets ${chatContext.targetArchitecture}.` }
];
const excludeTraits = context.flags.copilotcppExcludeTraits as string[] ?? [];
traits = traits.filter(trait => !excludeTraits.includes(trait.name));
return traits.length > 0 ? traits : undefined;
};
// Call both handlers in parallel
const traitsPromise = ((context.flags.copilotcppTraits as boolean) ?? false) ? getTraitsHandler() : Promise.resolve(undefined);
const includesPromise = getIncludesHandler();
return { entries: await includesPromise, traits: await traitsPromise };
catch {
// Intentionally swallow any exception.
}
telemetryProperties["error"] = "true";
throw exception; // Throw the exception for auto-retry.
} finally {
telemetryMetrics['duration'] = performance.now() - start;
telemetry.logCopilotEvent('RelatedFilesProvider', telemetryProperties, telemetryMetrics);
}
}
);
}
@@ -72,9 +157,9 @@ export async function registerRelatedFilesProvider(): Promise<void> {
}
}
async function getIncludesWithCancellation(maxDepth: number, token: vscode.CancellationToken): Promise<GetIncludesResult> {
async function getIncludes(maxDepth: number): Promise<GetIncludesResult> {
const activeClient = getActiveClient();
const includes = await activeClient.getIncludes(maxDepth, token);
const includes = await activeClient.getIncludes(maxDepth);
const wksFolder = activeClient.RootUri?.toString();
if (!wksFolder) {
+44 -11
View File
@@ -5,7 +5,9 @@
'use strict';
import * as fs from 'fs';
import { Minimatch } from 'minimatch';
import * as path from 'path';
import { isWindows } from '../constants';
export const cachedEditorConfigSettings: Map<string, any> = new Map<string, any>();
@@ -61,13 +63,25 @@ export function mapWrapToEditorConfig(value: string | undefined): string {
return "never";
}
function matchesSection(filePath: string, section: string): boolean {
const fileName: string = path.basename(filePath);
// Escape all regex special characters except '*' and '?'.
// Convert wildcards '*' to '.*' and '?' to '.'.
const sectionPattern = section.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.');
const regex: RegExp = new RegExp(`^${sectionPattern}$`);
return regex.test(fileName);
export function matchesSection(pathPrefix: string, filePath: string, section: string): boolean {
// The following code is copied from: https://github.com/editorconfig/editorconfig-core-js
const matchOptions = { matchBase: true, dot: true };
pathPrefix = pathPrefix.replace(/[?*+@!()|[\]{}]/g, '\\$&');
pathPrefix = pathPrefix.replace(/^#/, '\\#');
switch (section.indexOf('/')) {
case -1:
section = `**/${section}`;
break;
case 0:
section = section.substring(1);
break;
default:
break;
}
section = section.replace(/\\\\/g, '\\\\\\\\');
section = section.replace(/\*\*/g, '{*,**/**/**}');
const matcher = new Minimatch(`${pathPrefix}/${section}`, matchOptions);
return matcher.match(filePath);
}
function parseEditorConfigContent(content: string): Record<string, any> {
@@ -92,7 +106,17 @@ function parseEditorConfigContent(content: string): Record<string, any> {
const [key, ...values] = line.split('=');
if (key && values.length > 0) {
const trimmedKey = key.trim();
const value = values.join('=').trim();
let value: any = values.join('=').trim();
// Convert boolean-like and numeric values.
if (value === 'true') {
value = true;
} else if (value === 'false') {
value = false;
} else if (!isNaN(Number(value))) {
value = Number(value);
}
if (currentSection) {
// Ensure the current section is initialized.
if (!config[currentSection]) {
@@ -113,8 +137,12 @@ function getEditorConfig(filePath: string): any {
let currentDir: string = path.dirname(filePath);
const rootDir: string = path.parse(currentDir).root;
if (isWindows) {
filePath = filePath.replace(/\\/g, '/');
}
// Traverse from the file's directory to the root directory.
for (;;) {
for (; ;) {
const editorConfigPath: string = path.join(currentDir, '.editorconfig');
if (fs.existsSync(editorConfigPath)) {
const configFileContent: string = fs.readFileSync(editorConfigPath, 'utf-8');
@@ -128,9 +156,14 @@ function getEditorConfig(filePath: string): any {
};
}
let currentDirForwardSlashes: string = currentDir;
if (isWindows) {
currentDirForwardSlashes = currentDir.replace(/\\/g, '/');
}
// Match sections and combine configurations.
Object.keys(configData).forEach((section: string) => {
if (section !== '*' && matchesSection(filePath, section)) {
if (section !== '*' && matchesSection(currentDirForwardSlashes, filePath, section)) {
combinedConfig = {
...combinedConfig,
...configData[section]
@@ -139,7 +172,7 @@ function getEditorConfig(filePath: string): any {
});
// Check if the current .editorconfig is the root.
if (configData['*']?.root?.toLowerCase() === 'true') {
if (configData['*']?.root) {
break; // Stop searching after processing the root = true file.
}
}
+2 -2
View File
@@ -584,13 +584,13 @@ async function installCompiler(sender?: any): Promise<void> {
telemetry.logLanguageServerEvent('installCompiler', telemetryProperties);
}
async function onSelectConfiguration(): Promise<void> {
async function onSelectConfiguration(config?: string): Promise<void> {
if (!isFolderOpen()) {
void vscode.window.showInformationMessage(localize("configuration.select.first", 'Open a folder first to select a configuration.'));
} else {
// This only applies to the active client. You cannot change the configuration for
// a client that is not active since that client's UI will not be visible.
return clients.ActiveClient.handleConfigurationSelectCommand();
return clients.ActiveClient.handleConfigurationSelectCommand(config);
}
}
+174 -21
View File
@@ -5,13 +5,20 @@
'use strict';
import * as vscode from 'vscode';
import { localize } from 'vscode-nls';
import * as nls from 'vscode-nls';
import * as util from '../common';
import * as logger from '../logger';
import * as telemetry from '../telemetry';
import { ChatContextResult } from './client';
import { ChatContextResult, ProjectContextResult } from './client';
import { getClients } from './extension';
import { checkDuration } from './utils';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
const MSVC: string = 'MSVC';
const Clang: string = 'Clang';
const GCC: string = 'GCC';
const knownValues: { [Property in keyof ChatContextResult]?: { [id: string]: string } } = {
language: {
'c': 'C',
@@ -19,9 +26,9 @@ const knownValues: { [Property in keyof ChatContextResult]?: { [id: string]: str
'cuda-cpp': 'CUDA C++'
},
compiler: {
'msvc': 'MSVC',
'clang': 'Clang',
'gcc': 'GCC'
'msvc': MSVC,
'clang': Clang,
'gcc': GCC
},
standardVersion: {
'c++98': 'C++98',
@@ -44,6 +51,141 @@ const knownValues: { [Property in keyof ChatContextResult]?: { [id: string]: str
}
};
function formatChatContext(context: ChatContextResult | ProjectContextResult): void {
type KnownKeys = 'language' | 'standardVersion' | 'compiler' | 'targetPlatform';
for (const key in knownValues) {
const knownKey = key as KnownKeys;
if (knownValues[knownKey] && context[knownKey]) {
// Clear the value if it's not in the known values.
context[knownKey] = knownValues[knownKey][context[knownKey]] || "";
}
}
}
export interface ProjectContext {
language: string;
standardVersion: string;
compiler: string;
targetPlatform: string;
targetArchitecture: string;
compilerArguments: Record<string, string>;
}
export function getCompilerArgumentFilterMap(compiler: string, context: { flags: Record<string, unknown> }): Record<string, string> | undefined {
// The copilotcppXXXCompilerArgumentFilters are maps.
// The keys are regex strings and the values, if not empty, are the prompt text to use when no arguments are found.
let filterMap: Record<string, string> | undefined;
try {
switch (compiler) {
case MSVC:
if (context.flags.copilotcppMsvcCompilerArgumentFilter !== undefined) {
filterMap = JSON.parse(context.flags.copilotcppMsvcCompilerArgumentFilter as string);
}
break;
case Clang:
if (context.flags.copilotcppClangCompilerArgumentFilter !== undefined) {
filterMap = JSON.parse(context.flags.copilotcppClangCompilerArgumentFilter as string);
}
break;
case GCC:
if (context.flags.copilotcppGccCompilerArgumentFilter !== undefined) {
filterMap = JSON.parse(context.flags.copilotcppGccCompilerArgumentFilter as string);
}
break;
}
}
catch {
// Intentionally swallow any exception.
}
return filterMap;
}
function filterCompilerArguments(compiler: string, compilerArguments: string[], context: { flags: Record<string, unknown> }, telemetryProperties: Record<string, string>): Record<string, string> {
const filterMap = getCompilerArgumentFilterMap(compiler, context);
if (filterMap === undefined) {
return {};
}
const combinedArguments = compilerArguments.join(' ');
const result: Record<string, string> = {};
const filteredCompilerArguments: string[] = [];
for (const key in filterMap) {
if (!key) {
continue;
}
const filter = new RegExp(key, 'g');
const filtered = combinedArguments.match(filter);
if (filtered) {
filteredCompilerArguments.push(...filtered);
result[key] = filtered[filtered.length - 1];
}
}
if (filteredCompilerArguments.length > 0) {
// Telemetry to learn about the argument distribution. The filtered arguments are expected to be non-PII.
telemetryProperties["filteredCompilerArguments"] = filteredCompilerArguments.join(',');
telemetryProperties["filters"] = Object.keys(filterMap).filter(filter => !!filter).join(',');
}
return result;
}
export async function getProjectContext(uri: vscode.Uri, context: { flags: Record<string, unknown> }): Promise<ProjectContext | undefined> {
const telemetryProperties: Record<string, string> = {};
const telemetryMetrics: Record<string, number> = {};
try {
const projectContext = await checkDuration<ProjectContextResult | undefined>(async () => await getClients()?.ActiveClient?.getProjectContext(uri) ?? undefined);
telemetryMetrics["duration"] = projectContext.duration;
if (!projectContext.result) {
return undefined;
}
formatChatContext(projectContext.result);
const result: ProjectContext = {
language: projectContext.result.language,
standardVersion: projectContext.result.standardVersion,
compiler: projectContext.result.compiler,
targetPlatform: projectContext.result.targetPlatform,
targetArchitecture: projectContext.result.targetArchitecture,
compilerArguments: {}
};
if (projectContext.result.language) {
telemetryProperties["language"] = projectContext.result.language;
}
if (projectContext.result.compiler) {
telemetryProperties["compiler"] = projectContext.result.compiler;
}
if (projectContext.result.standardVersion) {
telemetryProperties["standardVersion"] = projectContext.result.standardVersion;
}
if (projectContext.result.targetPlatform) {
telemetryProperties["targetPlatform"] = projectContext.result.targetPlatform;
}
if (projectContext.result.targetArchitecture) {
telemetryProperties["targetArchitecture"] = projectContext.result.targetArchitecture;
}
telemetryMetrics["compilerArgumentCount"] = projectContext.result.fileContext.compilerArguments.length;
result.compilerArguments = filterCompilerArguments(projectContext.result.compiler, projectContext.result.fileContext.compilerArguments, context, telemetryProperties);
return result;
}
catch (exception) {
try {
const err: Error = exception as Error;
logger.getOutputChannelLogger().appendLine(localize("copilot.projectcontext.error", "Error while retrieving the project context. Reason: {0}", err.message));
}
catch {
// Intentionally swallow any exception.
}
telemetryProperties["error"] = "true";
throw exception; // Throw the exception for auto-retry.
} finally {
telemetry.logCopilotEvent('ProjectContext', telemetryProperties, telemetryMetrics);
}
}
export class CppConfigurationLanguageModelTool implements vscode.LanguageModelTool<void> {
public async invoke(options: vscode.LanguageModelToolInvocationOptions<void>, token: vscode.CancellationToken): Promise<vscode.LanguageModelToolResult> {
return new vscode.LanguageModelToolResult([
@@ -51,39 +193,50 @@ export class CppConfigurationLanguageModelTool implements vscode.LanguageModelTo
}
private async getContext(token: vscode.CancellationToken): Promise<string> {
const telemetryProperties: Record<string, string> = {};
try {
const currentDoc = vscode.window.activeTextEditor?.document;
if (!currentDoc || (!util.isCpp(currentDoc) && !util.isHeaderFile(currentDoc.uri))) {
return 'The active document is not a C, C++, or CUDA file.';
}
const chatContext: ChatContextResult | undefined = await (getClients()?.ActiveClient?.getChatContext(token) ?? undefined);
const chatContext: ChatContextResult | undefined = await (getClients()?.ActiveClient?.getChatContext(currentDoc.uri, token) ?? undefined);
if (!chatContext) {
return 'No configuration information is available for the active document.';
}
telemetry.logLanguageModelToolEvent(
'cpp',
{
"language": chatContext.language,
"compiler": chatContext.compiler,
"standardVersion": chatContext.standardVersion,
"targetPlatform": chatContext.targetPlatform,
"targetArchitecture": chatContext.targetArchitecture
});
formatChatContext(chatContext);
for (const key in knownValues) {
const knownKey = key as keyof ChatContextResult;
if (knownValues[knownKey] && chatContext[knownKey]) {
chatContext[knownKey] = knownValues[knownKey][chatContext[knownKey]] || chatContext[knownKey];
}
let contextString = "";
if (chatContext.language) {
contextString += `The user is working on a ${chatContext.language} project. `;
telemetryProperties["language"] = chatContext.language;
}
if (chatContext.standardVersion) {
contextString += `The project uses language version ${chatContext.standardVersion}. `;
telemetryProperties["standardVersion"] = chatContext.standardVersion;
}
if (chatContext.compiler) {
contextString += `The project compiles using the ${chatContext.compiler} compiler. `;
telemetryProperties["compiler"] = chatContext.compiler;
}
if (chatContext.targetPlatform) {
contextString += `The project targets the ${chatContext.targetPlatform} platform. `;
telemetryProperties["targetPlatform"] = chatContext.targetPlatform;
}
if (chatContext.targetArchitecture) {
contextString += `The project targets the ${chatContext.targetArchitecture} architecture. `;
telemetryProperties["targetArchitecture"] = chatContext.targetArchitecture;
}
return `The user is working on a ${chatContext.language} project. The project uses language version ${chatContext.standardVersion}, compiles using the ${chatContext.compiler} compiler, targets the ${chatContext.targetPlatform} platform, and targets the ${chatContext.targetArchitecture} architecture.`;
return contextString;
}
catch {
await this.reportError();
telemetryProperties["error"] = "true";
return "";
} finally {
telemetry.logCopilotEvent('Chat/Tool/cpp', telemetryProperties);
}
}
+8 -46
View File
@@ -15,17 +15,9 @@ import { shouldChangeFromCToCpp } from './utils';
export const RequestCancelled: number = -32800;
export const ServerCancelled: number = -32802;
let anyFileOpened: boolean = false;
export function createProtocolFilter(): Middleware {
// Disabling lint for invoke handlers
const invoke1 = (a: any, next: (a: any) => any): any => clients.ActiveClient.enqueue(() => next(a));
const invoke2 = (a: any, b: any, next: (a: any, b: any) => any): any => clients.ActiveClient.enqueue(() => next(a, b));
const invoke3 = (a: any, b: any, c: any, next: (a: any, b: any, c: any) => any): any => clients.ActiveClient.enqueue(() => next(a, b, c));
const invoke4 = (a: any, b: any, c: any, d: any, next: (a: any, b: any, c: any, d: any) => any): any => clients.ActiveClient.enqueue(() => next(a, b, c, d));
return {
didOpen: async (document, sendMessage) => clients.ActiveClient.enqueue(async () => {
didOpen: async (document, sendMessage) => {
if (!util.isCpp(document)) {
return;
}
@@ -41,62 +33,32 @@ export function createProtocolFilter(): Middleware {
const mappingString: string = baseFileName + "@" + document.fileName;
client.addFileAssociations(mappingString, "cpp");
client.sendDidChangeSettings();
document = await vscode.languages.setTextDocumentLanguage(document, "cpp");
// This will cause the file to be closed and reopened.
void vscode.languages.setTextDocumentLanguage(document, "cpp");
return;
}
// client.takeOwnership() will call client.TrackedDocuments.add() again, but that's ok. It's a Set.
client.onDidOpenTextDocument(document);
client.takeOwnership(document);
await sendMessage(document);
// For a file already open when we activate, sometimes we don't get any notifications about visible
// or active text editors, visible ranges, or text selection. As a workaround, we trigger
// onDidChangeVisibleTextEditors here, only for the first file opened.
if (!anyFileOpened) {
anyFileOpened = true;
const cppEditors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => util.isCpp(e.document));
await client.onDidChangeVisibleTextEditors(cppEditors);
}
void sendMessage(document);
}
}
}),
didChange: invoke1,
willSave: invoke1,
},
willSaveWaitUntil: async (event, sendMessage) => {
// await clients.ActiveClient.ready;
// Don't use awaitUntilLanguageClientReady.
// Otherwise, the message can be delayed too long.
const me: Client = clients.getClientFor(event.document.uri);
if (me.TrackedDocuments.has(event.document.uri.toString())) {
return sendMessage(event);
}
return [];
},
didSave: invoke1,
didClose: async (document, sendMessage) => clients.ActiveClient.enqueue(async () => {
didClose: async (document, sendMessage) => {
const me: Client = clients.getClientFor(document.uri);
const uriString: string = document.uri.toString();
if (me.TrackedDocuments.has(uriString)) {
me.onDidCloseTextDocument(document);
me.TrackedDocuments.delete(uriString);
await sendMessage(document);
void sendMessage(document);
}
}),
provideCompletionItem: invoke4,
resolveCompletionItem: invoke2,
provideHover: async (document, position, token, next: (document: any, position: any, token: any) => any) => clients.ActiveClient.enqueue(async () => {
const me: Client = clients.getClientFor(document.uri);
if (me.TrackedDocuments.has(document.uri.toString())) {
return next(document, position, token);
}
return null;
}),
provideSignatureHelp: invoke4,
provideDefinition: invoke3,
provideReferences: invoke4,
provideDocumentHighlights: invoke3,
provideDeclaration: invoke3,
workspace: {
didChangeConfiguration: invoke1
}
};
}
+6
View File
@@ -112,3 +112,9 @@ export async function withCancellation<T>(promise: Promise<T>, token: vscode.Can
});
});
}
export async function checkDuration<T>(fn: () => Promise<T>): Promise<{ result: T; duration: number }> {
const start = performance.now();
const result = await fn();
return { result, duration: performance.now() - start };
}
+2 -1
View File
@@ -478,5 +478,6 @@
"refactor_extract_reference_return_c_code": "The function would have to return a value by reference. C code cannot return references.",
"refactor_extract_xborder_jump": "Jumps between the selected code and the surrounding code are present.",
"refactor_extract_missing_return": "In the selected code, some control paths exit without setting the return value. This is supported only for scalar, numeric, and pointer return types.",
"expand_selection": "Expand selection (to enable 'Extract to function')"
"expand_selection": "Expand selection (to enable 'Extract to function')",
"file_not_found_in_path2": "\"{0}\" not found in compile_commands.json files. 'includePath' from c_cpp_properties.json in folder '{1}' will be used for this file instead."
}
+2 -2
View File
@@ -123,10 +123,10 @@ export function logLanguageServerEvent(eventName: string, properties?: Record<st
sendTelemetry();
}
export function logLanguageModelToolEvent(eventName: string, properties?: Record<string, string>, metrics?: Record<string, number>): void {
export function logCopilotEvent(eventName: string, properties?: Record<string, string>, metrics?: Record<string, number>): void {
const sendTelemetry = () => {
if (experimentationTelemetry) {
const eventNamePrefix: string = "C_Cpp/Copilot/Chat/Tool/";
const eventNamePrefix: string = "C_Cpp/Copilot/";
experimentationTelemetry.sendTelemetryEvent(eventNamePrefix + eventName, properties, metrics);
}
};
@@ -9,11 +9,14 @@ import * as proxyquire from 'proxyquire';
import * as sinon from 'sinon';
import * as vscode from 'vscode';
import * as util from '../../../../src/common';
import { ChatContextResult, DefaultClient, GetIncludesResult } from '../../../../src/LanguageServer/client';
import { DefaultClient, GetIncludesResult } from '../../../../src/LanguageServer/client';
import { CopilotApi, CopilotTrait } from '../../../../src/LanguageServer/copilotProviders';
import * as extension from '../../../../src/LanguageServer/extension';
import * as lmTool from '../../../../src/LanguageServer/lmTool';
import { ProjectContext } from '../../../../src/LanguageServer/lmTool';
import * as telemetry from '../../../../src/telemetry';
describe('registerRelatedFilesProvider', () => {
describe('copilotProviders Tests', () => {
let moduleUnderTest: any;
let mockCopilotApi: sinon.SinonStubbedInstance<CopilotApi>;
let getActiveClientStub: sinon.SinonStub;
@@ -21,6 +24,7 @@ describe('registerRelatedFilesProvider', () => {
let vscodeGetExtensionsStub: sinon.SinonStub;
let callbackPromise: Promise<{ entries: vscode.Uri[]; traits?: CopilotTrait[] }> | undefined;
let vscodeExtension: vscode.Extension<unknown>;
let telemetryStub: sinon.SinonStub;
const includedFiles = process.platform === 'win32' ?
['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] :
@@ -68,25 +72,28 @@ describe('registerRelatedFilesProvider', () => {
activeClientStub = sinon.createStubInstance(DefaultClient);
getActiveClientStub = sinon.stub(extension, 'getActiveClient').returns(activeClientStub);
activeClientStub.getIncludes.resolves({ includedFiles: [] });
telemetryStub = sinon.stub(telemetry, 'logCopilotEvent').returns();
});
afterEach(() => {
sinon.restore();
});
const arrange = ({ vscodeExtension, getIncludeFiles, chatContext, rootUri, flags }:
{ vscodeExtension?: vscode.Extension<unknown>; getIncludeFiles?: GetIncludesResult; chatContext?: ChatContextResult; rootUri?: vscode.Uri; flags?: Record<string, unknown> } =
{ vscodeExtension: undefined, getIncludeFiles: undefined, chatContext: undefined, rootUri: undefined, flags: {} }
const arrange = ({ vscodeExtension, getIncludeFiles, projectContext, rootUri, flags }:
{ vscodeExtension?: vscode.Extension<unknown>; getIncludeFiles?: GetIncludesResult; projectContext?: ProjectContext; rootUri?: vscode.Uri; flags?: Record<string, unknown> } =
{ vscodeExtension: undefined, getIncludeFiles: undefined, projectContext: undefined, rootUri: undefined, flags: {} }
) => {
activeClientStub.getIncludes.resolves(getIncludeFiles);
activeClientStub.getChatContext.resolves(chatContext);
sinon.stub(lmTool, 'getProjectContext').resolves(projectContext);
sinon.stub(activeClientStub, 'RootUri').get(() => rootUri);
mockCopilotApi.registerRelatedFilesProvider.callsFake((_providerId: { extensionId: string; languageId: string }, callback: (uri: vscode.Uri, context: { flags: Record<string, unknown> }, cancellationToken: vscode.CancellationToken) => Promise<{ entries: vscode.Uri[]; traits?: CopilotTrait[] }>) => {
const tokenSource = new vscode.CancellationTokenSource();
try {
callbackPromise = callback(vscode.Uri.parse('file:///test-extension-path'), { flags: flags ?? {} }, tokenSource.token);
} finally {
tokenSource.dispose();
if (_providerId.languageId === 'cpp') {
const tokenSource = new vscode.CancellationTokenSource();
try {
callbackPromise = callback(vscode.Uri.parse('file:///test-extension-path'), { flags: flags ?? {} }, tokenSource.token);
} finally {
tokenSource.dispose();
}
}
return {
@@ -97,7 +104,7 @@ describe('registerRelatedFilesProvider', () => {
vscodeGetExtensionsStub = sinon.stub(vscode.extensions, 'getExtension').returns(vscodeExtension);
};
it('should register provider', async () => {
it('should register provider.', async () => {
arrange(
{ vscodeExtension: vscodeExtension }
);
@@ -108,13 +115,13 @@ describe('registerRelatedFilesProvider', () => {
ok(mockCopilotApi.registerRelatedFilesProvider.calledWithMatch(sinon.match({ extensionId: 'test-extension-id', languageId: sinon.match.in(['c', 'cpp', 'cuda-cpp']) })), 'registerRelatedFilesProvider should be called with the correct providerId and languageId');
});
it('should not add #cpp traits when ChatContext isn\'t available.', async () => {
it('should not provide project context traits when project context isn\'t available.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles },
chatContext: undefined,
projectContext: undefined,
rootUri,
flags: { copilotcppTraits: true }
flags: {}
});
await moduleUnderTest.registerRelatedFilesProvider();
@@ -130,117 +137,83 @@ describe('registerRelatedFilesProvider', () => {
ok(result.traits === undefined, 'result.traits should be undefined');
});
it('should not add #cpp traits when copilotcppTraits flag is false.', async () => {
const projectContextNoArgs: ProjectContext = {
language: 'C++',
standardVersion: 'C++20',
compiler: 'MSVC',
targetPlatform: 'Windows',
targetArchitecture: 'x64',
compilerArguments: {}
};
it('provides standardVersion trait by default.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles },
chatContext: {
language: 'c++',
standardVersion: 'c++20',
compiler: 'msvc',
targetPlatform: 'windows',
targetArchitecture: 'x64'
},
projectContext: projectContextNoArgs,
rootUri,
flags: { copilotcppTraits: false }
flags: {}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(vscodeGetExtensionsStub.calledOnce, 'vscode.extensions.getExtension should be called once');
ok(mockCopilotApi.registerRelatedFilesProvider.calledWithMatch(sinon.match({ extensionId: 'test-extension-id', languageId: sinon.match.in(['c', 'cpp', 'cuda-cpp']) })), 'registerRelatedFilesProvider should be called with the correct providerId and languageId');
ok(getActiveClientStub.callCount !== 0, 'getActiveClient should be called');
ok(callbackPromise, 'callbackPromise should be defined');
ok(result, 'result should be defined');
ok(result.entries.length === 1, 'result.entries should have 1 included file');
ok(result.entries[0].toString() === expectedInclude, `result.entries should have "${expectedInclude}"`);
ok(result.traits === undefined, 'result.traits should be undefined');
});
it('should add #cpp traits when copilotcppTraits flag is true.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles },
chatContext: {
language: 'c++',
standardVersion: 'c++20',
compiler: 'msvc',
targetPlatform: 'windows',
targetArchitecture: 'x64'
},
rootUri,
flags: { copilotcppTraits: true }
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(vscodeGetExtensionsStub.calledOnce, 'vscode.extensions.getExtension should be called once');
ok(mockCopilotApi.registerRelatedFilesProvider.calledThrice, 'registerRelatedFilesProvider should be called three times');
ok(mockCopilotApi.registerRelatedFilesProvider.calledWithMatch(sinon.match({ extensionId: 'test-extension-id', languageId: sinon.match.in(['c', 'cpp', 'cuda-cpp']) })), 'registerRelatedFilesProvider should be called with the correct providerId and languageId');
ok(getActiveClientStub.callCount !== 0, 'getActiveClient should be called');
ok(callbackPromise, 'callbackPromise should be defined');
ok(result, 'result should be defined');
ok(result.entries.length === 1, 'result.entries should have 1 included file');
ok(result.entries[0].toString() === expectedInclude, `result.entries should have "${expectedInclude}"`);
ok(result.traits, 'result.traits should be defined');
ok(result.traits.length === 5, 'result.traits should have 5 traits');
ok(result.traits[0].name === 'language', 'result.traits[0].name should be "language"');
ok(result.traits[0].value === 'c++', 'result.traits[0].value should be "c++"');
ok(result.traits[0].includeInPrompt, 'result.traits[0].includeInPrompt should be true');
ok(result.traits[0].promptTextOverride === 'The language is c++.', 'result.traits[0].promptTextOverride should be "The language is c++."');
ok(result.traits[1].name === 'compiler', 'result.traits[1].name should be "compiler"');
ok(result.traits[1].value === 'msvc', 'result.traits[1].value should be "msvc"');
ok(result.traits[1].includeInPrompt, 'result.traits[1].includeInPrompt should be true');
ok(result.traits[1].promptTextOverride === 'This project compiles using msvc.', 'result.traits[1].promptTextOverride should be "This project compiles using msvc."');
ok(result.traits[2].name === 'standardVersion', 'result.traits[2].name should be "standardVersion"');
ok(result.traits[2].value === 'c++20', 'result.traits[2].value should be "c++20"');
ok(result.traits[2].includeInPrompt, 'result.traits[2].includeInPrompt should be true');
ok(result.traits[2].promptTextOverride === 'This project uses the c++20 language standard.', 'result.traits[2].promptTextOverride should be "This project uses the c++20 language standard."');
ok(result.traits[3].name === 'targetPlatform', 'result.traits[3].name should be "targetPlatform"');
ok(result.traits[3].value === 'windows', 'result.traits[3].value should be "windows"');
ok(result.traits[3].includeInPrompt, 'result.traits[3].includeInPrompt should be true');
ok(result.traits[3].promptTextOverride === 'This build targets windows.', 'result.traits[3].promptTextOverride should be "This build targets windows."');
ok(result.traits[4].name === 'targetArchitecture', 'result.traits[4].name should be "targetArchitecture"');
ok(result.traits[4].value === 'x64', 'result.traits[4].value should be "x64"');
ok(result.traits[4].includeInPrompt, 'result.traits[4].includeInPrompt should be true');
ok(result.traits[4].promptTextOverride === 'This build targets x64.', 'result.traits[4].promptTextOverride should be "This build targets x64."');
ok(result.traits.length === 1, 'result.traits should have 1 trait');
ok(result.traits.find((trait) => trait.name === 'standardVersion'), 'result.traits should have a standardVersion trait');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.value === 'C++20', 'result.traits should have a standardVersion trait with value "C++20"');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.includeInPrompt, 'result.traits should have a standardVersion trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.promptTextOverride === 'This project uses the C++20 language standard.', 'result.traits should have a standardVersion trait with promptTextOverride');
});
it('should exclude #cpp traits per copilotcppExcludeTraits.', async () => {
const excludeTraits = ['compiler', 'targetPlatform'];
it('provides traits per copilotcppIncludeTraits.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles },
chatContext: {
language: 'c++',
standardVersion: 'c++20',
compiler: 'msvc',
targetPlatform: 'windows',
targetArchitecture: 'x64'
},
projectContext: projectContextNoArgs,
rootUri,
flags: { copilotcppTraits: true, copilotcppExcludeTraits: excludeTraits }
flags: { copilotcppIncludeTraits: ['intelliSenseDisclaimer', 'intelliSenseDisclaimerBeginning', 'language', 'compiler', 'targetPlatform', 'targetArchitecture', 'intelliSenseDisclaimerEnd'] }
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(vscodeGetExtensionsStub.calledOnce, 'vscode.extensions.getExtension should be called once');
ok(mockCopilotApi.registerRelatedFilesProvider.calledThrice, 'registerRelatedFilesProvider should be called three times');
ok(mockCopilotApi.registerRelatedFilesProvider.calledWithMatch(sinon.match({ extensionId: 'test-extension-id', languageId: sinon.match.in(['c', 'cpp', 'cuda-cpp']) })), 'registerRelatedFilesProvider should be called with the correct providerId and languageId');
ok(getActiveClientStub.callCount !== 0, 'getActiveClient should be called');
ok(callbackPromise, 'callbackPromise should be defined');
ok(result, 'result should be defined');
ok(result.entries.length === 1, 'result.entries should have 1 included file');
ok(result.entries[0].toString() === expectedInclude, `result.entries should have "${expectedInclude}"`);
ok(result.traits, 'result.traits should be defined');
ok(result.traits.length === 3, 'result.traits should have 3 traits');
ok(result.traits.filter(trait => excludeTraits.includes(trait.name)).length === 0, 'result.traits should not include excluded traits');
ok(result.traits.length === 8, 'result.traits should have 8 traits if none are excluded');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimer'), 'result.traits should have a intellisense trait');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimer')?.includeInPrompt, 'result.traits should have a intellisense trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimer')?.promptTextOverride === 'IntelliSense is currently configured with the following compiler information. It reflects the active configuration, and the project may have more configurations targeting different platforms.', 'result.traits should have a intellisense trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerBeginning'), 'result.traits should have a intellisenseBegin trait');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerBeginning')?.includeInPrompt, 'result.traits should have a intellisenseBegin trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerBeginning')?.promptTextOverride === 'Beginning of IntelliSense information.', 'result.traits should have a intellisenseBegin trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'language'), 'result.traits should have a language trait');
ok(result.traits.find((trait) => trait.name === 'language')?.value === 'C++', 'result.traits should have a language trait with value "C++"');
ok(result.traits.find((trait) => trait.name === 'language')?.includeInPrompt, 'result.traits should have a language trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'language')?.promptTextOverride === 'The language is C++.', 'result.traits should have a language trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'compiler'), 'result.traits should have a compiler trait');
ok(result.traits.find((trait) => trait.name === 'compiler')?.value === 'MSVC', 'result.traits should have a compiler trait with value "MSVC"');
ok(result.traits.find((trait) => trait.name === 'compiler')?.includeInPrompt, 'result.traits should have a compiler trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'compiler')?.promptTextOverride === 'This project compiles using MSVC.', 'result.traits should have a compiler trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'standardVersion'), 'result.traits should have a standardVersion trait');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.value === 'C++20', 'result.traits should have a standardVersion trait with value "C++20"');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.includeInPrompt, 'result.traits should have a standardVersion trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'standardVersion')?.promptTextOverride === 'This project uses the C++20 language standard.', 'result.traits should have a standardVersion trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'targetPlatform'), 'result.traits should have a targetPlatform trait');
ok(result.traits.find((trait) => trait.name === 'targetPlatform')?.value === 'Windows', 'result.traits should have a targetPlatform trait with value "Windows"');
ok(result.traits.find((trait) => trait.name === 'targetPlatform')?.includeInPrompt, 'result.traits should have a targetPlatform trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'targetPlatform')?.promptTextOverride === 'This build targets Windows.', 'result.traits should have a targetPlatform trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'targetArchitecture'), 'result.traits should have a targetArchitecture trait');
ok(result.traits.find((trait) => trait.name === 'targetArchitecture')?.value === 'x64', 'result.traits should have a targetArchitecture trait with value "x64"');
ok(result.traits.find((trait) => trait.name === 'targetArchitecture')?.includeInPrompt, 'result.traits should have a targetArchitecture trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'targetArchitecture')?.promptTextOverride === 'This build targets x64.', 'result.traits should have a targetArchitecture trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerEnd'), 'result.traits should have a intellisenseEnd trait');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerEnd')?.includeInPrompt, 'result.traits should have a intellisenseEnd trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'intelliSenseDisclaimerEnd')?.promptTextOverride === 'End of IntelliSense information.', 'result.traits should have a intellisenseEnd trait with promptTextOverride');
});
it('should handle errors during provider registration', async () => {
it('handles errors during provider registration.', async () => {
arrange({});
await moduleUnderTest.registerRelatedFilesProvider();
@@ -248,4 +221,174 @@ describe('registerRelatedFilesProvider', () => {
ok(vscodeGetExtensionsStub.calledOnce, 'vscode.extensions.getExtension should be called once');
ok(mockCopilotApi.registerRelatedFilesProvider.notCalled, 'registerRelatedFilesProvider should not be called');
});
const projectContext: ProjectContext = {
language: 'C++',
standardVersion: 'C++17',
compiler: 'MSVC',
targetPlatform: 'Windows',
targetArchitecture: 'x64',
compilerArguments: { "/std:c++\d+": '/std:c++17', "/GR-?": '/GR-', "/EH[ascr-]+": '/EHs-c-', "/await": '/await' }
};
it('provides compiler argument traits.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: projectContext,
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['compilerArguments'],
copilotcppMsvcCompilerArgumentFilter: '{"/std:c++\d+": "", "/GR-?": "", "/EH[ascr-]+": "", "/await": ""}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'compilerArguments'), 'result.traits should have a compiler arguments trait');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.value === '/std:c++17, /GR-, /EHs-c-, /await', 'result.traits should have a compiler arguments trait with value "/std:c++17, /GR-, /EHs-c-, /await"');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.includeInPrompt, 'result.traits should have a compiler arguments trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.promptTextOverride === 'The compiler arguments include: /std:c++17, /GR-, /EHs-c-, /await.', 'result.traits should have a compiler arguments trait with promptTextOverride');
ok(!result.traits.find((trait) => trait.name === 'directAsks'), 'result.traits should not have a direct asks trait');
});
it('provide direct ask traits of compiler arguments.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: projectContext,
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['directAsks', 'compilerArguments'],
copilotcppMsvcCompilerArgumentFilter: '{"/std:c++\d+": "", "/await": "", "/GR-?": "", "/EH[ascr-]+": ""}',
copilotcppCompilerArgumentDirectAskMap: '{"/GR-": "Do not generate code using RTTI keywords.", "/EHs-c-": "Do not generate code using exception handling keywords."}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'compilerArguments'), 'result.traits should have a compiler arguments trait');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.value === '/std:c++17, /await', 'result.traits should have a compiler arguments trait with value "/std:c++17, /await"');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.includeInPrompt, 'result.traits should have a compiler arguments trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.promptTextOverride === 'The compiler arguments include: /std:c++17, /await.', 'result.traits should have a compiler arguments trait with promptTextOverride');
ok(result.traits.find((trait) => trait.name === 'directAsks'), 'result.traits should have a direct asks trait');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.value === 'Do not generate code using RTTI keywords. Do not generate code using exception handling keywords. ', 'result.traits should have a direct asks value');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.includeInPrompt, 'result.traits should have a direct asks trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.promptTextOverride === 'Do not generate code using RTTI keywords. Do not generate code using exception handling keywords. ', 'result.traits should have a direct ask trait with promptTextOverride');
ok(telemetryStub.calledOnce, 'Telemetry should be called once');
ok(telemetryStub.calledWithMatch('RelatedFilesProvider', sinon.match({
"includeTraits": 'directAsks,compilerArguments',
'traits': 'standardVersion,compilerArguments,directAsks'
}), sinon.match({
'duration': sinon.match.number
})));
});
it('ignore compilerArguments trait if empty.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: projectContext,
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['directAsks', 'compilerArguments'],
copilotcppMsvcCompilerArgumentFilter: '{"/std:c++\d+": "", "/await": "", "/GR-?": "", "/EH[ascr-]+": ""}',
copilotcppCompilerArgumentDirectAskMap: '{"/GR-": "abc.", "/EHs-c-": "def.", "/std:c++17": "ghi.", "/await": "jkl."}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'compilerArguments') === undefined, 'result.traits should not have a compiler arguments trait');
ok(result.traits.find((trait) => trait.name === 'directAsks'), 'result.traits should have a direct asks trait');
ok(telemetryStub.calledOnce, 'Telemetry should be called once');
ok(telemetryStub.calledWithMatch('RelatedFilesProvider', sinon.match({
"includeTraits": 'directAsks,compilerArguments',
'traits': 'standardVersion,directAsks'
})));
});
it('uses only last argument from the duplicates.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: {
language: 'C++',
standardVersion: 'C++20',
compiler: 'MSVC',
targetPlatform: 'Windows',
targetArchitecture: 'x64',
compilerArguments: { "/std:c++\d+": '/std:c++20', "/await": '/await' }
},
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['compilerArguments'],
copilotcppMsvcCompilerArgumentFilter: '{"/std:c++\d+": "", "/await": ""}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'compilerArguments'), 'result.traits should have a compiler arguments trait');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.value === '/std:c++20, /await', 'result.traits should have a compiler arguments trait with value "/std:c++20, /await"');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.includeInPrompt, 'result.traits should have a compiler arguments trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'compilerArguments')?.promptTextOverride === 'The compiler arguments include: /std:c++20, /await.', 'result.traits should have a compiler arguments trait with promptTextOverride');
});
it('provides direct asks trait for absence of arguments.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: projectContextNoArgs,
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['directAsks'],
copilotcppMsvcCompilerArgumentFilter:
'{"/FOO": "/FOO is not set.", "/BAR": "/BAR is not set."}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'directAsks'), 'result.traits should have a direct asks trait');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.value === '/FOO is not set. /BAR is not set. ', 'result.traits should have a direct asks value');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.includeInPrompt, 'result.traits should have a direct asks trait with includeInPrompt true');
ok(result.traits.find((trait) => trait.name === 'directAsks')?.promptTextOverride === "/FOO is not set. /BAR is not set. ", 'result.traits should have a direct ask trait with promptTextOverride');
});
it('does not accept empty regex.', async () => {
arrange({
vscodeExtension: vscodeExtension,
getIncludeFiles: { includedFiles: ['c:\\system\\include\\vector', 'c:\\system\\include\\string', 'C:\\src\\my_project\\foo.h'] },
projectContext: projectContextNoArgs,
rootUri: vscode.Uri.file('C:\\src\\my_project'),
flags: {
copilotcppIncludeTraits: ['directAsks'],
copilotcppMsvcCompilerArgumentFilter:
'{"": "Empty regex not allowed."}'
}
});
await moduleUnderTest.registerRelatedFilesProvider();
const result = await callbackPromise;
ok(result, 'result should be defined');
ok(result.traits, 'result.traits should be defined');
ok(result.traits.find((trait) => trait.name === 'directAsks') === undefined, 'result.traits should not have a direct asks trait');
});
});
@@ -0,0 +1,388 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { ok } from 'assert';
import { afterEach, beforeEach, describe, it } from 'mocha';
import * as sinon from 'sinon';
import * as vscode from 'vscode';
import * as util from '../../../../src/common';
import { ChatContextResult, DefaultClient, ProjectContextResult } from '../../../../src/LanguageServer/client';
import { ClientCollection } from '../../../../src/LanguageServer/clientCollection';
import * as extension from '../../../../src/LanguageServer/extension';
import { CppConfigurationLanguageModelTool, getProjectContext } from '../../../../src/LanguageServer/lmTool';
import * as telemetry from '../../../../src/telemetry';
describe('CppConfigurationLanguageModelTool Tests', () => {
let mockLanguageModelToolInvocationOptions: sinon.SinonStubbedInstance<vscode.LanguageModelToolInvocationOptions<void>>;
let activeClientStub: sinon.SinonStubbedInstance<DefaultClient>;
let mockTextEditorStub: MockTextEditor;
let mockTextDocumentStub: sinon.SinonStubbedInstance<vscode.TextDocument>;
let telemetryStub: sinon.SinonStub;
class MockLanguageModelToolInvocationOptions implements vscode.LanguageModelToolInvocationOptions<void> {
tokenizationOptions?: vscode.LanguageModelToolTokenizationOptions | undefined;
toolInvocationToken: undefined;
input: undefined;
}
class MockTextEditor implements vscode.TextEditor {
constructor(selection: vscode.Selection, selections: readonly vscode.Selection[], visibleRanges: readonly vscode.Range[], options: vscode.TextEditorOptions, document: vscode.TextDocument, viewColumn?: vscode.ViewColumn) {
this.selection = selection;
this.selections = selections;
this.visibleRanges = visibleRanges;
this.options = options;
this.viewColumn = viewColumn;
this.document = document;
}
selection: vscode.Selection;
selections: readonly vscode.Selection[];
visibleRanges: readonly vscode.Range[];
options: vscode.TextEditorOptions;
viewColumn: vscode.ViewColumn | undefined;
edit(_callback: (editBuilder: vscode.TextEditorEdit) => void, _options?: { readonly undoStopBefore: boolean; readonly undoStopAfter: boolean }): Thenable<boolean> {
throw new Error('Method not implemented.');
}
insertSnippet(_snippet: vscode.SnippetString, _location?: vscode.Position | vscode.Range | readonly vscode.Position[] | readonly vscode.Range[], _options?: { readonly undoStopBefore: boolean; readonly undoStopAfter: boolean }): Thenable<boolean> {
throw new Error('Method not implemented.');
}
setDecorations(_decorationType: vscode.TextEditorDecorationType, _rangesOrOptions: readonly vscode.Range[] | readonly vscode.DecorationOptions[]): void {
throw new Error('Method not implemented.');
}
revealRange(_range: vscode.Range, _revealType?: vscode.TextEditorRevealType): void {
throw new Error('Method not implemented.');
}
show(_column?: vscode.ViewColumn): void {
throw new Error('Method not implemented.');
}
hide(): void {
throw new Error('Method not implemented.');
}
document: vscode.TextDocument;
}
class MockTextDocument implements vscode.TextDocument {
uri: vscode.Uri;
constructor(uri: vscode.Uri, fileName: string, isUntitled: boolean, languageId: string, version: number, isDirty: boolean, isClosed: boolean, eol: vscode.EndOfLine, lineCount: number) {
this.uri = uri;
this.fileName = fileName;
this.isUntitled = isUntitled;
this.languageId = languageId;
this.version = version;
this.isDirty = isDirty;
this.isClosed = isClosed;
this.eol = eol;
this.lineCount = lineCount;
}
fileName: string;
isUntitled: boolean;
languageId: string;
version: number;
isDirty: boolean;
isClosed: boolean;
save(): Thenable<boolean> {
throw new Error('Method not implemented.');
}
eol: vscode.EndOfLine;
lineCount: number;
lineAt(line: number): vscode.TextLine;
// eslint-disable-next-line @typescript-eslint/unified-signatures
lineAt(position: vscode.Position): vscode.TextLine;
lineAt(_arg: number | vscode.Position): vscode.TextLine {
throw new Error('Method not implemented.');
}
offsetAt(_position: vscode.Position): number {
throw new Error('Method not implemented.');
}
positionAt(_offset: number): vscode.Position {
throw new Error('Method not implemented.');
}
getText(_range?: vscode.Range): string {
throw new Error('Method not implemented.');
}
getWordRangeAtPosition(_position: vscode.Position, _regex?: RegExp): vscode.Range | undefined {
throw new Error('Method not implemented.');
}
validateRange(_range: vscode.Range): vscode.Range {
throw new Error('Method not implemented.');
}
validatePosition(_position: vscode.Position): vscode.Position {
throw new Error('Method not implemented.');
}
}
beforeEach(() => {
sinon.stub(util, 'extensionContext').value({ extension: { id: 'test-extension-id' } });
mockTextDocumentStub = sinon.createStubInstance(MockTextDocument);
mockTextEditorStub = new MockTextEditor(new vscode.Selection(0, 0, 0, 0), [], [], { tabSize: 4 }, mockTextDocumentStub);
mockLanguageModelToolInvocationOptions = new MockLanguageModelToolInvocationOptions();
activeClientStub = sinon.createStubInstance(DefaultClient);
const clientsStub = sinon.createStubInstance(ClientCollection);
sinon.stub(extension, 'getClients').returns(clientsStub);
sinon.stub(clientsStub, 'ActiveClient').get(() => activeClientStub);
activeClientStub.getIncludes.resolves({ includedFiles: [] });
sinon.stub(vscode.window, 'activeTextEditor').get(() => mockTextEditorStub);
telemetryStub = sinon.stub(telemetry, 'logCopilotEvent').returns();
});
afterEach(() => {
sinon.restore();
});
const arrangeChatContextFromCppTools = ({ chatContextFromCppTools, isCpp, isHeaderFile }:
{ chatContextFromCppTools?: ChatContextResult; isCpp?: boolean; isHeaderFile?: boolean } =
{ chatContextFromCppTools: undefined, isCpp: undefined, isHeaderFile: false }
) => {
activeClientStub.getChatContext.resolves(chatContextFromCppTools);
sinon.stub(util, 'isCpp').returns(isCpp ?? true);
sinon.stub(util, 'isHeaderFile').returns(isHeaderFile ?? false);
};
const arrangeProjectContextFromCppTools = ({ projectContextFromCppTools, isCpp, isHeaderFile }:
{ projectContextFromCppTools?: ProjectContextResult; isCpp?: boolean; isHeaderFile?: boolean } =
{ projectContextFromCppTools: undefined, isCpp: undefined, isHeaderFile: false }
) => {
activeClientStub.getProjectContext.resolves(projectContextFromCppTools);
sinon.stub(util, 'isCpp').returns(isCpp ?? true);
sinon.stub(util, 'isHeaderFile').returns(isHeaderFile ?? false);
};
it('should log telemetry and provide #cpp chat context.', async () => {
arrangeChatContextFromCppTools({
chatContextFromCppTools: {
language: 'cpp',
standardVersion: 'c++20',
compiler: 'msvc',
targetPlatform: 'windows',
targetArchitecture: 'x64'
}
});
const result = await new CppConfigurationLanguageModelTool().invoke(mockLanguageModelToolInvocationOptions, new vscode.CancellationTokenSource().token);
ok(telemetryStub.calledOnce, 'Telemetry should be called once');
ok(telemetryStub.calledWithMatch('Chat/Tool/cpp', sinon.match({
"language": 'C++',
"compiler": 'MSVC',
"standardVersion": 'C++20',
"targetPlatform": 'Windows',
"targetArchitecture": 'x64'
})));
ok(result, 'result should not be undefined');
const text = result.content[0] as vscode.LanguageModelTextPart;
ok(text, 'result should contain a text part');
ok(text.value === 'The user is working on a C++ project. The project uses language version C++20. The project compiles using the MSVC compiler. The project targets the Windows platform. The project targets the x64 architecture. ');
});
const testGetProjectContext = async ({
compiler,
expectedCompiler,
context,
compilerArguments: compilerArguments,
expectedCompilerArguments
}: {
compiler: string;
expectedCompiler: string;
context: { flags: Record<string, unknown> };
compilerArguments: string[];
expectedCompilerArguments: Record<string, string>;
}) => {
arrangeProjectContextFromCppTools({
projectContextFromCppTools: {
language: 'cpp',
standardVersion: 'c++20',
compiler: compiler,
targetPlatform: 'windows',
targetArchitecture: 'x64',
fileContext: {
compilerArguments: compilerArguments
}
}
});
const result = await getProjectContext(mockTextDocumentStub.uri, context);
ok(result, 'result should not be undefined');
ok(result.language === 'C++');
ok(result.compiler === expectedCompiler);
ok(result.standardVersion === 'C++20');
ok(result.targetPlatform === 'Windows');
ok(result.targetArchitecture === 'x64');
ok(JSON.stringify(result.compilerArguments) === JSON.stringify(expectedCompilerArguments));
};
it('should provide compilerArguments based on copilotcppMsvcCompilerArgumentFilter.', async () => {
await testGetProjectContext({
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: { flags: { copilotcppMsvcCompilerArgumentFilter: '{"foo-?": ""}' } },
compilerArguments: ['foo', 'bar', 'abc', 'foo-'],
expectedCompilerArguments: { 'foo-?': 'foo-' }
});
});
it('should provide compilerArguments based on copilotcppClangCompilerArgumentFilter.', async () => {
await testGetProjectContext({
compiler: 'clang',
expectedCompiler: 'Clang',
context: { flags: { copilotcppClangCompilerArgumentFilter: '{"foo": "", "bar": ""}' } },
compilerArguments: ['foo', 'bar', 'abc'],
expectedCompilerArguments: { 'foo': 'foo', 'bar': 'bar' }
});
});
it('should support spaces between argument and value.', async () => {
await testGetProjectContext({
compiler: 'clang',
expectedCompiler: 'Clang',
context: { flags: { copilotcppClangCompilerArgumentFilter: '{"-std\\\\sc\\\\+\\\\+\\\\d+": ""}' } },
compilerArguments: ['-std', 'c++17', '-std', 'foo', '-std', 'c++11', '-std', 'bar'],
expectedCompilerArguments: { '-std\\sc\\+\\+\\d+': '-std c++11' }
});
});
it('should provide compilerArguments based on copilotcppGccCompilerArgumentFilter.', async () => {
await testGetProjectContext({
compiler: 'gcc',
expectedCompiler: 'GCC',
context: { flags: { copilotcppGccCompilerArgumentFilter: '{"foo": "", "bar": ""}' } },
compilerArguments: ['foo', 'bar', 'abc', 'bar', 'foo', 'bar'],
expectedCompilerArguments: { 'foo': 'foo', 'bar': 'bar' }
});
});
it('should provide empty array for each regex if nothing matches.', async () => {
await testGetProjectContext({
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: { flags: { copilotcppMsvcCompilerArgumentFilter: '{"foo": "", "bar": ""}' } },
compilerArguments: [],
expectedCompilerArguments: {}
});
});
it('should filter out all compilerArguments by default.', async () => {
await testGetProjectContext({
compiler: 'gcc',
expectedCompiler: 'GCC',
context: { flags: {} },
compilerArguments: ['foo', 'bar'],
expectedCompilerArguments: {}
});
});
it('should filter out all compilerArguments for empty regex.', async () => {
await testGetProjectContext({
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: { flags: { copilotcppMsvcCompilerArgumentFilter: '{"": ""}' } },
compilerArguments: ['foo', 'bar'],
expectedCompilerArguments: {}
});
});
it('should filter out all compilerArguments for empty copilotcppMsvcCompilerArgumentFilter.', async () => {
await testGetProjectContext({
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: {
flags: {
copilotcppMsvcCompilerArgumentFilter: ''
}
},
compilerArguments: ['foo', 'bar'],
expectedCompilerArguments: {}
});
});
it('should filter out all compilerArguments for invalid copilotcppMsvcCompilerArgumentFilter.', async () => {
await testGetProjectContext({
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: {
flags: {
copilotcppMsvcCompilerArgumentFilter: 'Not a map'
}
},
compilerArguments: ['foo', 'bar'],
expectedCompilerArguments: {}
});
});
it('should filter out all compilerArguments for unknown compilers.', async () => {
await testGetProjectContext({
compiler: 'unknown',
expectedCompiler: '',
context: {
flags: {
copilotcppMsvcCompilerArgumentFilter: '{"(foo|bar)": ""}',
copilotcppClangCompilerArgumentFilter: '{"(foo|bar)": ""}',
copilotcppGccCompilerArgumentFilter: '{"(foo|bar)": ""}'
}
},
compilerArguments: ['foo', 'bar'],
expectedCompilerArguments: {}
});
});
it('should send telemetry.', async () => {
const input = {
compiler: 'msvc',
expectedCompiler: 'MSVC',
context: { flags: { copilotcppMsvcCompilerArgumentFilter: '{"foo-?": "", "": "", "bar": "", "xyz": ""}' } },
compilerArguments: ['foo', 'bar', 'foo-', 'abc'],
expectedCompilerArguments: { 'foo-?': 'foo-', 'bar': 'bar' }
};
await testGetProjectContext(input);
ok(telemetryStub.calledOnce, 'Telemetry should be called once');
ok(telemetryStub.calledWithMatch('ProjectContext', sinon.match({
"language": 'C++',
"compiler": input.expectedCompiler,
"standardVersion": 'C++20',
"targetPlatform": 'Windows',
"targetArchitecture": 'x64',
"filteredCompilerArguments": "foo,foo-,bar",
"filters": "foo-?,bar,xyz"
}), sinon.match({
"compilerArgumentCount": input.compilerArguments.length,
'duration': sinon.match.number
})));
});
it('should not send telemetry for unknown values', async () => {
arrangeProjectContextFromCppTools({
projectContextFromCppTools: {
language: 'java',
standardVersion: 'gnu++17',
compiler: 'javac',
targetPlatform: 'arduino',
targetArchitecture: 'bar',
fileContext: {
compilerArguments: []
}
}
});
const result = await getProjectContext(mockTextDocumentStub.uri, { flags: {} });
ok(telemetryStub.calledOnce, 'Telemetry should be called once');
ok(telemetryStub.calledWithMatch('ProjectContext', sinon.match({
"targetArchitecture": 'bar'
}), sinon.match({
"compilerArgumentCount": 0
})));
ok(telemetryStub.calledWithMatch('ProjectContext', sinon.match(property =>
property['language'] === undefined &&
property['compiler'] === undefined &&
property['standardVersion'] === undefined &&
property['targetPlatform'] === undefined)));
ok(result, 'result should not be undefined');
ok(result.language === '');
ok(result.compiler === '');
ok(result.standardVersion === '');
ok(result.targetPlatform === '');
ok(result.targetArchitecture === 'bar');
ok(Object.keys(result.compilerArguments).length === 0);
});
});
+11 -4
View File
@@ -448,7 +448,7 @@
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
integrity sha1-B1CLRXl8uB7D8nMBGwVM0HVe3co=
"@types/minimatch@^3.0.3", "@types/minimatch@^3.0.5":
"@types/minimatch@^3.0.3":
version "3.0.5"
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
integrity sha1-EAHMXmo3BLg8I2An538vWOoBD0A=
@@ -1428,9 +1428,9 @@ create-require@^1.1.0:
integrity sha1-wdfo8eX2z8n/ZfnNNS03NIdWwzM=
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha1-9zqFudXUHQRVUcF34ogtSshXKKY=
version "7.0.6"
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha1-ilj+ePANzXDDcEUXWd+/rwPo7p8=
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
@@ -3278,6 +3278,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@^4.2.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.3.tgz#b4dcece1d674dee104bb0fb833ebb85a78cbbca6"
integrity sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1, minimatch@^5.1.0, minimatch@^5.1.6:
version "5.1.6"
resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"