From df58934ca061e30b67efa2a0b7ddfb1f59ebc33d Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Fri, 26 Jun 2026 16:01:26 -0700 Subject: [PATCH 01/12] Fix TypeScript compilation errors in common.ts (#14551) * Fix TypeScript errors. --- Extension/.scripts/common.ts | 2 +- Extension/src/common.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Extension/.scripts/common.ts b/Extension/.scripts/common.ts index 29758c269..c40e94398 100644 --- a/Extension/.scripts/common.ts +++ b/Extension/.scripts/common.ts @@ -39,7 +39,7 @@ chdir($root); // dump unhandled async errors to the console and exit. process.on('unhandledRejection', (reason: any, _promise) => { - error(`${reason?.stack?.split(/\r?\n/).filter(l => !l.includes('node:internal') && !l.includes('node_modules')).join('\n')}`); + error(`${reason?.stack?.split(/\r?\n/).filter((l: string) => !l.includes('node:internal') && !l.includes('node_modules')).join('\n')}`); process.exit(1); }); diff --git a/Extension/src/common.ts b/Extension/src/common.ts index 60a8ff72e..7bfda0ec8 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -14,12 +14,12 @@ import * as vscode from 'vscode'; import { DocumentFilter, Range } from 'vscode-languageclient'; import * as nls from 'vscode-nls'; import { TargetPopulation } from 'vscode-tas-client'; -import * as which from "which"; import { ManualPromise } from './Utility/Async/manualPromise'; import { isWindows } from './constants'; import { getOutputChannelLogger, showOutputChannel } from './logger'; import { PlatformInformation } from './platform'; import * as Telemetry from './telemetry'; +import which = require('which'); nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -1528,7 +1528,7 @@ export interface ISshLocalForwardInfo { export function whichAsync(name: string, path?: string): Promise { return new Promise(resolve => { - which(name, path ? { path } : {}, (err, resolved) => { + which(name, path ? { path } : {}, (err: Error | null, resolved: string | undefined) => { if (err) { resolve(undefined); } else { From 53dd88fd195b2aa3b7d2b265f78f4fdf62f6f532 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Mon, 29 Jun 2026 16:32:42 -0700 Subject: [PATCH 02/12] Fix clang-format/clang-tidy version check failing on Windows (and paths with spaces) (#14552) * Fix clang-format/clang-tidy version check failing on Windows (and paths with spaces) --- Extension/src/LanguageServer/settings.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index e3e02e6e5..71f6730bd 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -4,11 +4,10 @@ * ------------------------------------------------------------------------------------------ */ 'use strict'; -import { execSync } from 'child_process'; +import { execFileSync } from 'child_process'; import * as os from 'os'; import * as path from 'path'; import * as semver from 'semver'; -import { quote } from 'shell-quote'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as which from 'which'; @@ -297,7 +296,7 @@ export class CppSettings extends Settings { let bundledVersion: string; try { const bundledPath: string = getExtensionFilePath(`./LLVM/bin/${clangName}`); - const output: string = execSync(quote([bundledPath, '--version'])).toString(); + const output: string = execFileSync(bundledPath, ['--version']).toString(); bundledVersion = output.match(/(\d+\.\d+\.\d+)/)?.[1] ?? ""; if (!semver.valid(bundledVersion)) { return path; @@ -309,7 +308,7 @@ export class CppSettings extends Settings { // Invoke the version on the system to compare versions. Use ours if it's more recent. try { - const output: string = execSync(`"${path}" --version`).toString(); + const output: string = execFileSync(path, ['--version']).toString(); const userVersion = output.match(/(\d+\.\d+\.\d+)/)?.[1] ?? ""; if (semver.ltr(userVersion, bundledVersion)) { path = ""; From fe18c4af958b190f8d4c120202640f03489afb59 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 30 Jun 2026 13:55:08 -0700 Subject: [PATCH 03/12] Improve crash call stack data. (#14555) * Improve crash call stack data. --- Extension/src/LanguageServer/extension.ts | 84 +++++++++++++---------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 55516f626..91584f13c 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -1165,13 +1165,10 @@ export function watchForCrashes(crashDirectory: string): void { let previousCrashData: string; let previousCrashCount: number = 0; -function logCrashTelemetry(data: string, type: string, offsetData?: string, crashLog?: string): void { +function logCrashTelemetry(data: string, type: string, crashLog?: string): void { const crashObject: Record = {}; const crashCountObject: Record = {}; crashObject.CrashingThreadCallStack = data; - if (offsetData !== undefined) { - crashObject.CrashingThreadCallStackOffsets = offsetData; - } if (crashLog !== undefined) { crashObject.CrashLog = crashLog; } @@ -1185,8 +1182,8 @@ function logMacCrashTelemetry(data: string): void { logCrashTelemetry(data, "MacCrash"); } -function logCppCrashTelemetry(data: string, offsetData?: string, crashLog?: string): void { - logCrashTelemetry(data, "CppCrash", offsetData, crashLog); +function logCppCrashTelemetry(data: string, crashLog?: string): void { + logCrashTelemetry(data, "CppCrash", crashLog); } function handleMacCrashFileRead(err: NodeJS.ErrnoException | undefined | null, data: string): void { @@ -1292,6 +1289,39 @@ function containsFilteredTelemetryData(str: string): boolean { return regex.test(str); } +// Non-null fault addresses are randomized by ASLR (and use-after-free/wild pointers vary run to +// run), so embedding the raw value in CrashingThreadCallStack would fragment crash buckets and +// make CrashCount meaningless. Preserve near-null addresses (typical null-pointer dereferences, +// which are stable and useful for bucketing), but replace arbitrary addresses with a stable +// placeholder so identical crashes still de-duplicate. +function bucketSignalAddress(address: string): string { + let value: bigint; + try { + value = BigInt(address.trim()); + } catch { + return address; // Not a parseable address; leave it untouched. + } + // 0x10000 (64 KB) covers null plus small member/array offsets off a null pointer. + return value < 0x10000n ? address : ""; +} + +// An unsymbolized frame is reported as a raw runtime address. Addresses in the fixed-base main +// executable (non-PIE on Linux) stay constant across runs and are useful for bucketing, but +// addresses in the ASLR-randomized shared-library/mmap region (Linux 0x7f..., and on macOS the +// PIE main image and dyld shared cache) shift every launch and would fragment crash buckets. Keep +// the low, fixed addresses but replace high (relocated) ones with a stable placeholder. 4 GB is a +// safe cut: a non-PIE executable's own code loads well below it, while the relocated region is far +// above it. +function bucketFrameAddress(address: string): string { + let value: bigint; + try { + value = BigInt(address.trim()); + } catch { + return address; // Not a parseable address; leave it untouched. + } + return value < 0x100000000n ? address : ""; +} + async function handleCrashFileRead(crashDirectory: string, crashFile: string, crashDate: Date, err: NodeJS.ErrnoException | undefined | null, data: string): Promise { if (err) { if (err.code === "ENOENT") { @@ -1301,16 +1331,15 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr } const lines: string[] = data.split("\n"); - let addressData: string; - const isCppToolsSrv2: boolean = crashFile.startsWith("cpptools-srv2"); - const isCppToolsSrv: boolean = crashFile.startsWith("cpptools-srv"); - const telemetryHeader: string = (isCppToolsSrv2 ? "cpptools-srv2.txt" : isCppToolsSrv ? "cpptools-srv.txt" : crashFile) + "\n"; + let signalInfo: string; + const processName: string = (crashFile.startsWith("cpptools-srv2") ? "cpptools-srv2 process" : + crashFile.startsWith("cpptools-srv") ? "cpptools-srv process" : + crashFile.startsWith("cpptools-wordexp") ? "cpptools-wordexp process" : "cpptools process") + "\n"; const filtPath: string | null = which.sync("c++filt", { nothrow: true }); const isMac: boolean = process.platform === "darwin"; const startStr: string = isMac ? " _" : "<"; const offsetStr: string = isMac ? " + " : "+"; const endOffsetStr: string = isMac ? " " : " <"; - const dotStr: string = "…\n"; let signalType: string; let crashLog: string = ""; let crashStackStartLine: number = 0; @@ -1333,16 +1362,16 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr } if (lines[crashStackStartLine].startsWith("SIG")) { signalType = `${lines[crashStackStartLine]}\n`; - addressData = `${lines[crashStackStartLine + 1]}:${lines[crashStackStartLine + 2]}\n`; // signalCode:signalAddr + signalInfo = `si_code=${lines[crashStackStartLine + 1]}, si_addr=${bucketSignalAddress(lines[crashStackStartLine + 2])}\n`; crashStackStartLine += 3; } else { // The signal type may fail to be written. // Intentionally different from SIGUNKNOWN from cpptools, // and not SIG-? to avoid matching the regex in containsFilteredTelemetryData. signalType = "SIGMISSING\n"; - addressData = ".\n"; + signalInfo = ""; } - data = telemetryHeader + signalType; + data = processName + signalType + signalInfo; let crashCallStack: string = ""; let validFrameFound: boolean = false; for (let lineNum: number = crashStackStartLine; lineNum < lines.length - 3; ++lineNum) { // skip last lines @@ -1350,23 +1379,21 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr const startPos: number = line.indexOf(startStr); let pendingCallStack: string = ""; if (startPos === -1 || line[startPos + (isMac ? 1 : 4)] === "+") { - pendingCallStack = dotStr; const startAddressPos: number = line.indexOf("0x"); const endAddressPos: number = line.indexOf(endOffsetStr, startAddressPos + 2); if (startAddressPos === -1 || endAddressPos === -1 || startAddressPos >= endAddressPos) { - addressData += "Unexpected offset\n"; + pendingCallStack = "Unexpected offset\n"; } else { - let pendingAddressData: string = line.substring(startAddressPos, endAddressPos) + "\n"; + let pendingAddressData: string = bucketFrameAddress(line.substring(startAddressPos, endAddressPos)) + "\n"; if (containsFilteredTelemetryData(pendingAddressData)) { pendingAddressData = "?\n"; } - addressData += pendingAddressData; + pendingCallStack = pendingAddressData; } } else { const offsetPos: number = line.indexOf(offsetStr, startPos + startStr.length); if (offsetPos === -1) { pendingCallStack = "Missing offsetStr\n"; - addressData += "\n"; } else { const startPos2: number = startPos + 1; let funcStr: string = line.substring(startPos2, offsetPos); @@ -1397,18 +1424,6 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr // Compute pendingOffset. if (isMac) { pendingOffset += line.substring(offsetPos2); - const startAddressPos: number = line.indexOf("0x"); - if (startAddressPos === -1 || startAddressPos >= startPos) { - // unexpected - pendingOffset += ""; - addressData += "\n"; - } else { - let pendingAddressData: string = line.substring(startAddressPos, startPos) + "\n"; - if (containsFilteredTelemetryData(pendingAddressData)) { - pendingAddressData = "?\n"; - } - addressData += pendingAddressData; - } } else { const endPos: number = line.indexOf(">", offsetPos2); if (endPos === -1) { @@ -1416,8 +1431,6 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr } else { pendingOffset += line.substring(offsetPos2, endPos); } - addressData += "\n"; - // TODO: It seems like addressData should be obtained on Linux in case the function is filtered. } pendingOffset += "\n"; pendingCallStack = funcStr + pendingOffset; @@ -1447,19 +1460,18 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr } crashCallStack = crashCallStack.trimEnd(); - addressData = addressData.trimEnd(); if (crashCallStack !== prevCppCrashCallStackData) { prevCppCrashCallStackData = crashCallStack; if (lines.length >= 6 && util.getLoggingLevel() >= 1) { - getCrashCallStacksChannel().appendLine(`\n${isCppToolsSrv2 ? "cpptools-srv2" : isCppToolsSrv ? "cpptools-srv" : "cpptools"}\n${crashDate.toLocaleString()}\n${signalType}${crashCallStack}${crashLog.length > 0 ? "\n\n" + crashLog : ""}`); + getCrashCallStacksChannel().appendLine(`\n${processName}${crashDate.toLocaleString()}\n${signalType}${signalInfo}${crashCallStack}${crashLog.length > 0 ? "\n\n" + crashLog : ""}`); } } data += crashCallStack; - logCppCrashTelemetry(data, addressData, crashLog); + logCppCrashTelemetry(data, crashLog); await util.deleteFile(path.resolve(crashDirectory, crashFile)).catch(logAndReturn.undefined); if (crashFile === "cpptools.txt") { From 8e68bbba5dd226fd8334c15b491959d609a1145f Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 30 Jun 2026 15:31:44 -0700 Subject: [PATCH 04/12] Fix Windows backslash paths being mangled when adding an SSH target (#14554) * Fix Windows backslash paths being mangled when adding an SSH target --- Extension/ThirdPartyNotices.txt | 34 ------- Extension/package.json | 2 - Extension/src/SSH/sshCommandToConfig.ts | 75 ++++++++++++++- .../test/unit/sshCommandToConfig.test.ts | 95 +++++++++++++++++++ Extension/yarn.lock | 10 -- 5 files changed, 166 insertions(+), 50 deletions(-) create mode 100644 Extension/test/unit/sshCommandToConfig.test.ts diff --git a/Extension/ThirdPartyNotices.txt b/Extension/ThirdPartyNotices.txt index 06f108394..6c9ba6d3a 100644 --- a/Extension/ThirdPartyNotices.txt +++ b/Extension/ThirdPartyNotices.txt @@ -3241,40 +3241,6 @@ 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. ---------------------------------------------------------- - ---------------------------------------------------------- - -shell-quote 1.8.4 - MIT -https://github.com/ljharb/shell-quote - -Copyright (c) 2013 James Halliday (mail@substack.net) - -The MIT License - -Copyright (c) 2013 James Halliday (mail@substack.net) - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------------------------------------------------- --------------------------------------------------------- diff --git a/Extension/package.json b/Extension/package.json index cca7c7cc5..e697ba4e2 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -6870,7 +6870,6 @@ "@types/plist": "^3.0.5", "@types/proxyquire": "^1.3.31", "@types/semver": "^7.5.8", - "@types/shell-quote": "^1.7.5", "@types/sinon": "^21.0.0", "@types/tmp": "^0.2.6", "@types/which": "^2.0.2", @@ -6926,7 +6925,6 @@ "node-vswhere": "^1.0.2", "plist": "^3.1.0", "posix-getopt": "^1.2.1", - "shell-quote": "1.8.4", "ssh-config": "^4.4.4", "tmp": "^0.2.7", "vscode-cpptools": "^7.1.1", diff --git a/Extension/src/SSH/sshCommandToConfig.ts b/Extension/src/SSH/sshCommandToConfig.ts index e60463bd6..ce5bfc0e0 100644 --- a/Extension/src/SSH/sshCommandToConfig.ts +++ b/Extension/src/SSH/sshCommandToConfig.ts @@ -4,7 +4,6 @@ * ------------------------------------------------------------------------------------------ */ import { BasicParser, IParsedOption } from 'posix-getopt'; -import { parse } from 'shell-quote'; /** * Mapping of flags to functions that add the relevant flag to the map of @@ -124,7 +123,11 @@ export class CommandParseError extends Error { } * Attempts to convert an SSH command to an SSH config entry. */ export function sshCommandToConfig(command: string, name?: string): { [key: string]: string } { - const parts: string[] = parse(command) as string[]; + // Split the command line into arguments. We deliberately use shell-like tokenization that + // strips single and double quotes and lets an unquoted backslash escape a following space, + // while keeping backslashes before other characters literal, so both Unix paths with escaped + // spaces (e.g. /home/me/my\ key) and Windows paths (e.g. C:\Users\me\key) are preserved. + const parts: string[] = splitArgs(command); // ignore 'ssh' if the user entered that as their first word if (parts[0] === 'ssh') { @@ -167,6 +170,70 @@ export function sshCommandToConfig(command: string, name?: string): { [key: stri return { Host, HostName, ...options }; } +/** + * Splits a command line into arguments using shell-like tokenization that behaves + * consistently across platforms. Both single and double quotes group their contents + * and are removed, and unquoted whitespace separates arguments. + * + * Outside of quotes, a backslash escapes only a following whitespace character (so a + * Unix path such as `/home/me/my\ key` keeps its space as a single argument). Before + * any other character a backslash is kept literal, so Windows paths such as + * `C:\Users\me\key` are preserved rather than being consumed as escape sequences. + * + * This tokenizer is intentionally lenient for a single-line input box: an unterminated + * quote is not treated as an error but simply runs to the end of the string. + */ +export function splitArgs(command: string): string[] { + const args: string[] = []; + let current: string = ''; + let inToken: boolean = false; + let quoteChar: string | undefined; + for (let i: number = 0; i < command.length; i++) { + const c: string = command[i]; + if (quoteChar !== undefined) { + if (c === quoteChar) { + quoteChar = undefined; + } else { + current += c; + } + continue; + } + if (c === '"' || c === '\'') { + quoteChar = c; + inToken = true; + continue; + } + if (c === '\\') { + const next: string | undefined = command[i + 1]; + // Only escape a following whitespace character; otherwise keep the backslash + // literal so Windows path separators survive. + if (next === ' ' || next === '\t' || next === '\r' || next === '\n') { + current += next; + inToken = true; + i++; + continue; + } + current += c; + inToken = true; + continue; + } + if (c === ' ' || c === '\t' || c === '\r' || c === '\n') { + if (inToken) { + args.push(current); + current = ''; + inToken = false; + } + continue; + } + current += c; + inToken = true; + } + if (inToken) { + args.push(current); + } + return args; +} + /** * Parses flags from the given array of arguments, returning the index of the * next non-flag in the input (or the total length of the input if none are found). @@ -218,8 +285,8 @@ function parseFlags(input: string[], entries: { [key: string]: string }): number * are not mentioned on the ssh(1) man page and don't seem to have use in the * wild. In the OpenSSH source, they appear to be ignored[3]. * - * The `shell-quote` library, like libc does for OpenSSH, takes care of dealing - * with quotations for for us. + * The `splitArgs` tokenizer has already stripped any surrounding quotes before this + * function sees a token, so it only has to deal with the unquoted connection string. * * 1. https://github.com/openssh/openssh-portable/blob/e3b6c966b79c3ea5d51b923c3bbdc41e13b96ea0/ssh.c#L999 * 2. https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04#section-3.3 diff --git a/Extension/test/unit/sshCommandToConfig.test.ts b/Extension/test/unit/sshCommandToConfig.test.ts new file mode 100644 index 000000000..81e84a321 --- /dev/null +++ b/Extension/test/unit/sshCommandToConfig.test.ts @@ -0,0 +1,95 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import { deepStrictEqual, strictEqual } from 'assert'; +import { describe, it } from 'mocha'; +import { splitArgs, sshCommandToConfig } from '../../src/SSH/sshCommandToConfig'; + +// eslint-disable-next-line import/no-unassigned-import +require('source-map-support/register'); + +describe('splitArgs', () => { + // [description, input, expected tokens] + const cases: [string, string, string[]][] = [ + ['empty string', '', []], + ['whitespace only', ' \t ', []], + ['simple words', 'ssh user@host', ['ssh', 'user@host']], + ['collapses runs of whitespace', 'ssh \t user@host', ['ssh', 'user@host']], + ['trims leading/trailing whitespace', ' ssh user@host ', ['ssh', 'user@host']], + + // Windows paths: backslashes must stay literal (the original bug). + ['bare Windows path', 'ssh -i C:\\Users\\me\\key user@host', ['ssh', '-i', 'C:\\Users\\me\\key', 'user@host']], + ['double-quoted Windows path with spaces', 'ssh -i "C:\\Program Files\\me\\key" user@host', ['ssh', '-i', 'C:\\Program Files\\me\\key', 'user@host']], + ['single-quoted Windows path with spaces', "ssh -i 'C:\\Program Files\\me\\key' user@host", ['ssh', '-i', 'C:\\Program Files\\me\\key', 'user@host']], + ['single-quoted Windows path without spaces', "ssh -i 'C:\\Users\\me\\key' user@host", ['ssh', '-i', 'C:\\Users\\me\\key', 'user@host']], + + // Quote handling. + ['strips double quotes', '"a b" c', ['a b', 'c']], + ['strips single quotes', "'a b' c", ['a b', 'c']], + ['quotes joined to adjacent text', 'a"b c"d', ['ab cd']], + ['single quotes inside double quotes are literal', '"it\'s here"', ["it's here"]], + ['double quotes inside single quotes are literal', "'say \"hi\"'", ['say "hi"']], + ['empty double-quoted token is preserved', 'a "" b', ['a', '', 'b']], + ['empty single-quoted token is preserved', "a '' b", ['a', '', 'b']], + + // Forward-slash (POSIX-style) paths are unaffected. + ['forward-slash path', 'ssh -i /home/me/.ssh/id_rsa user@host', ['ssh', '-i', '/home/me/.ssh/id_rsa', 'user@host']], + + // An unquoted backslash escapes a following whitespace character (POSIX behavior), so a + // Unix path with an escaped space stays a single argument. + ['backslash escapes a space', 'ssh -i /home/me/my\\ key user@host', ['ssh', '-i', '/home/me/my key', 'user@host']], + ['backslash escapes multiple spaces', 'ssh -i /home/me/key\\ with\\ spaces user@host', ['ssh', '-i', '/home/me/key with spaces', 'user@host']], + ['backslash escapes a tab', 'a\\\tb', ['a\tb']], + ['trailing backslash is literal', 'foo\\', ['foo\\']], + ['backslash before a letter stays literal (Windows path)', 'C:\\Users\\me', ['C:\\Users\\me']], + ['UNC path keeps doubled backslashes', '\\\\server\\share', ['\\\\server\\share']], + // A backslash that ends a quoted segment is literal and must not escape the following + // separator (only an unquoted backslash directly before whitespace escapes). + ['quoted path ending in backslash is not joined to the next arg', '"C:\\Program Files\\" next', ['C:\\Program Files\\', 'next']], + + // Lenient handling of an unterminated quote: runs to end of string. + ['unterminated double quote runs to end', 'ssh -i "C:\\Users\\me', ['ssh', '-i', 'C:\\Users\\me']], + ['unterminated single quote runs to end', "ssh -i 'C:\\Users\\me", ['ssh', '-i', 'C:\\Users\\me']] + ]; + + for (const [description, input, expected] of cases) { + it(`${description}: ${JSON.stringify(input)}`, () => { + deepStrictEqual(splitArgs(input), expected); + }); + } +}); + +describe('sshCommandToConfig', () => { + it('preserves a bare Windows identity-file path', () => { + const config = sshCommandToConfig('ssh -i C:\\Users\\me\\.ssh\\id_rsa user@host'); + strictEqual(config.IdentityFile, 'C:\\Users\\me\\.ssh\\id_rsa'); + strictEqual(config.HostName, 'host'); + strictEqual(config.User, 'user'); + }); + + it('preserves a single-quoted Windows identity-file path with spaces', () => { + const config = sshCommandToConfig("ssh -i 'C:\\Program Files\\me\\key' user@host"); + strictEqual(config.IdentityFile, 'C:\\Program Files\\me\\key'); + }); + + it('preserves a double-quoted Windows identity-file path with spaces', () => { + const config = sshCommandToConfig('ssh -i "C:\\Program Files\\me\\key" user@host'); + strictEqual(config.IdentityFile, 'C:\\Program Files\\me\\key'); + }); + + it('preserves a Unix identity-file path with a backslash-escaped space', () => { + const config = sshCommandToConfig('ssh -i /home/me/my\\ key user@host'); + strictEqual(config.IdentityFile, '/home/me/my key'); + strictEqual(config.HostName, 'host'); + strictEqual(config.User, 'user'); + }); + + it('parses host, user, and port from the connection string', () => { + const config = sshCommandToConfig('ssh -p 2222 user@host'); + strictEqual(config.HostName, 'host'); + strictEqual(config.User, 'user'); + strictEqual(config.Port, '2222'); + }); +}); diff --git a/Extension/yarn.lock b/Extension/yarn.lock index 0e9de11fe..d37a5ed84 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -896,11 +896,6 @@ resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" integrity sha1-POOvGlUk7zJ9Lank/YttlcjXBSg= -"@types/shell-quote@^1.7.5": - version "1.7.5" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/shell-quote/-/shell-quote-1.7.5.tgz#6db4704742d307cd6d604e124e3ad6cd5ed943f3" - integrity sha1-bbRwR0LTB81tYE4STjrWzV7ZQ/M= - "@types/sinon@^21.0.0": version "21.0.0" resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/@types/sinon/-/sinon-21.0.0.tgz#3a598a29b3aec0512a21e57ae0fd4c09aa013ca9" @@ -5508,11 +5503,6 @@ shebang-regex@^3.0.0: resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= -shell-quote@1.8.4: - version "1.8.4" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/shell-quote/-/shell-quote-1.8.4.tgz#2edd9a4dcefc96649e2e2cb12f637b1f1d92a190" - integrity sha1-Lt2aTc78lmSeLiyxL2N7Hx2SoZA= - side-channel-list@^1.0.0: version "1.0.0" resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" From 03ee07113aca9748f87ed92bf2dbee83f171cb2a Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 30 Jun 2026 15:54:00 -0700 Subject: [PATCH 05/12] Fix format settings. (#14558) * Fix format settings. --- Extension/.vscode/settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extension/.vscode/settings.json b/Extension/.vscode/settings.json index ed43fe6a3..74f06e7f6 100644 --- a/Extension/.vscode/settings.json +++ b/Extension/.vscode/settings.json @@ -27,12 +27,14 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "vscode.json-language-features", "editor.tabSize": 4, + "editor.detectIndentation": true, "files.insertFinalNewline": false }, "[jsonc]": { "editor.formatOnSave": true, "editor.defaultFormatter": "vscode.json-language-features", "editor.tabSize": 4, + "editor.detectIndentation": true, "files.insertFinalNewline": true }, "[typescript]": { From dd1902a8dc2f004518afbb0213c27c12846fc69f Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 30 Jun 2026 16:16:30 -0700 Subject: [PATCH 06/12] Update .npmrc (#14557) --- .github/actions/.npmrc | 4 ++++ Extension/.npmrc | 4 ++++ ExtensionPack/.npmrc | 4 ++++ Themes/.npmrc | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/actions/.npmrc b/.github/actions/.npmrc index fdfca0176..a3422e06d 100644 --- a/.github/actions/.npmrc +++ b/.github/actions/.npmrc @@ -1,3 +1,7 @@ registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/ # Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust ignore-scripts=true + +min-release-age=7 +audit=true +audit-level=high diff --git a/Extension/.npmrc b/Extension/.npmrc index fdfca0176..a3422e06d 100644 --- a/Extension/.npmrc +++ b/Extension/.npmrc @@ -1,3 +1,7 @@ registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/ # Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust ignore-scripts=true + +min-release-age=7 +audit=true +audit-level=high diff --git a/ExtensionPack/.npmrc b/ExtensionPack/.npmrc index 0446fca08..000257fdf 100644 --- a/ExtensionPack/.npmrc +++ b/ExtensionPack/.npmrc @@ -2,3 +2,7 @@ registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_Public always-auth=true # Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust ignore-scripts=true + +min-release-age=7 +audit=true +audit-level=high diff --git a/Themes/.npmrc b/Themes/.npmrc index 0446fca08..000257fdf 100644 --- a/Themes/.npmrc +++ b/Themes/.npmrc @@ -2,3 +2,7 @@ registry=https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_Public always-auth=true # Disable postinstall scripts for supply chain security. Allowlist exceptions with npm trust: https://docs.npmjs.com/cli/v11/commands/npm-trust ignore-scripts=true + +min-release-age=7 +audit=true +audit-level=high From 3203386c6e409ced185d1b2850526caf30ef02a1 Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Tue, 30 Jun 2026 16:39:00 -0700 Subject: [PATCH 07/12] Localization for 1.33.3 (#14553) * Localization - Translated Strings --- Extension/i18n/chs/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/chs/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/cht/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/cht/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/csy/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/csy/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/deu/package.i18n.json | 31 ++++++++++--------- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/deu/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/esn/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/esn/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/fra/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/fra/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/ita/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/ita/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/jpn/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/jpn/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/kor/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/kor/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/plk/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/plk/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/ptb/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/ptb/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/rus/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/rus/src/nativeStrings.i18n.json | 2 ++ Extension/i18n/trk/package.i18n.json | 3 +- .../debugAdapterDescriptorFactory.i18n.json | 7 ++--- .../src/LanguageServer/extension.i18n.json | 1 + .../i18n/trk/src/nativeStrings.i18n.json | 2 ++ 52 files changed, 118 insertions(+), 79 deletions(-) diff --git a/Extension/i18n/chs/package.i18n.json b/Extension/i18n/chs/package.i18n.json index 39f8d259b..f7842d1f8 100644 --- a/Extension/i18n/chs/package.i18n.json +++ b/Extension/i18n/chs/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "用于控制如何找到和加载符号(.pdb 文件)的选项。", "c_cpp.debuggers.unknownBreakpointHandling.description": "控制在命中时如何处理(通常通过原始 GDB 命令)外部设置的断点。\n允许的值为 \"throw\" (好像应用程序抛出了异常)和 \"stop\" (只会暂停调试会话)。默认值为 \"throw\"。", "c_cpp.debuggers.debuginfod.description": "控制 GDB 的 debuginfod 行为,以从 debuginfod 服务器下载调试符号。", - "c_cpp.debuggers.debuginfod.enabled.description": "如果为 true (默认值),则启用 GDB 的 debuginfod 支持。设置为 false 可阻止 GDB 联系 debuginfod 服务器。", + "c_cpp.debuggers.debuginfod.enabled.description": "如果为 false (默认值),GDB 将不会连接 debuginfod 服务器。设置为 true 以启用 debuginfod 支持。", "c_cpp.debuggers.debuginfod.timeout.description": "debuginfod 服务器请求的超时(以秒为单位)。默认值为 30。设置为 0 可使用 GDB/libdebuginfod 默认值(无替代)。", "c_cpp.debuggers.VSSymbolOptions.description": "提供用于找到符号并将其加载到调试适配器的配置。", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "在其中搜索 .pdb 文件的符号服务器 URL (例如 http​://MyExampleSymbolServer)或目录(例如 /build/symbols)的数组。除了默认位置,还将搜索这些目录 - 在模块以及 pdb 最初放置到的路径的旁边。", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "调试程序不得为其加载符号的模块数组。支持通配符(例如: MyCompany.*.dll)。\n\n会忽略此属性,除非“模式”设置为 \"loadAllButExcluded\"。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "调试程序应为其加载符号的模块数组。支持通配符(例如: MyCompany.*.dll)。\n\n会忽略此属性,除非“模式”设置为 \"loadOnlyIncluded\"。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "如果为 true,则对于未在 \"includedModules\" 数组中的任何模块,调试程序将在模块本身和启动可执行文件旁边进行检查,但它将不检查符号搜索列表上的路径。此选项默认为 \"true\"\n\n会忽略此属性,除非“模式”设置为 \"loadOnlyIncluded\"。", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "如果为 true,那么在运行但不调试的情况下,当未能在终端中启动程序时不会记录任何警告。", "c_cpp.semanticTokenTypes.referenceType.description": "C++/CLI 引用类型的样式。", "c_cpp.semanticTokenTypes.cliProperty.description": "C++/CLI 属性的样式。", "c_cpp.semanticTokenTypes.genericType.description": "C++/CLI 泛型类型的样式。", diff --git a/Extension/i18n/chs/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/chs/src/Debugger/debugAdapterDescriptorFactory.i18n.json index f72734b58..8792abdc0 100644 --- a/Extension/i18n/chs/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/chs/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "调试程序类型“{0}”不适用于非 Windows 计算机。", "debugger.noDebug.requestType.not.supported": "仅启动配置支持“运行但不调试”。", - "debugger.noDebug.pipeTransport.not.supported": "已设置 \"pipeTransport\" 的配置不支持“运行但不调试”。", - "debugger.noDebug.debugServerPath.not.supported": "已设置 \"debugServerPath\" 的配置不支持“运行但不调试”。", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "已设置 \"miDebuggerServerAddress\" 的配置不支持“运行但不调试”。", - "debugger.noDebug.coreDumpPath.not.supported": "已设置 \"coreDumpPath\" 的配置不支持“运行但不调试”。" + "debugger.unsupported.properties": "具有以下属性的启动配置无法直接在终端中运行: {0}", + "debugger.fallback.message": "程序输出将改为显示在调试控制台中。", + "debugger.fallback.message2": "若要取消显示此警告,请在启动配置中将 'ignoreRunWithoutDebuggingWarnings' 属性设置为 true。" } \ No newline at end of file diff --git a/Extension/i18n/chs/src/LanguageServer/extension.i18n.json b/Extension/i18n/chs/src/LanguageServer/extension.i18n.json index ff227bece..8c6e17d99 100644 --- a/Extension/i18n/chs/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/chs/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "了解如何使用 vcpkg 为此标头安装库", "copy.vcpkg.command": "将用于安装“{0}”的 vcpkg 命令复制到剪贴板", "on.disabled.command": "当 `C_Cpp.intelliSenseEngine` 设置为 `disabled` 时,无法执行与 IntelliSense 相关的命令。", + "switch.header.source": "正在切换标头/源...", "client.not.found": "未找到客户端", "ok": "确定", "install.compiler.mac.title": "现在将安装 clang 编译器", diff --git a/Extension/i18n/chs/src/nativeStrings.i18n.json b/Extension/i18n/chs/src/nativeStrings.i18n.json index c46073f95..8c9972e38 100644 --- a/Extension/i18n/chs/src/nativeStrings.i18n.json +++ b/Extension/i18n/chs/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "用户拒绝了授权。", "auth_unexpected_error": "轮询期间发生意外错误: {0}", "auth_login_failed": "GitHub 登录失败。尝试从命令行使用 --login 运行以登录。", + "auth_login_failed_plugin": "GitHub 登录失败。运行 npx @microsoft/cpp-language-server --login", "auth_eula_required": "必须接受 EULA 才能继续。请使用 --accept-eula 运行。", + "auth_eula_required_plugin": "必须接受 EULA 才能继续。运行 npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "已通过 GitHub 身份验证。使用 --force-login 重新进行身份验证。", "config_unsupported_version": "初始化失败: 配置版本不受支持。仅支持版本 1。", "config_file_not_found": "初始化失败: 未找到配置文件“{0}”。", diff --git a/Extension/i18n/cht/package.i18n.json b/Extension/i18n/cht/package.i18n.json index aee7fcbc1..3898c51af 100644 --- a/Extension/i18n/cht/package.i18n.json +++ b/Extension/i18n/cht/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "控制如何找到並載入符號 (.pdb 檔案) 的選項。", "c_cpp.debuggers.unknownBreakpointHandling.description": "控制叫用時如何處理在外部設定的中斷點 (通常是透過原始 GDB 命令)。\n允許的值為 \"throw\",其作用就像應用程式擲出例外,以及 \"stop\",其只會暫停偵錯工作階段。預設值為 \"throw\"。", "c_cpp.debuggers.debuginfod.description": "控制從 debuginfod 伺服器下載偵錯符號的 GDB debuginfod 行為。", - "c_cpp.debuggers.debuginfod.enabled.description": "如果為 true (預設值),則會啟用 GDB 的 debuginfod 支援。設定為 False 以防止 GDB 聯繫 debuginfod 伺服器。", + "c_cpp.debuggers.debuginfod.enabled.description": "如果為 false (預設),GDB 將不會連線到 debuginfod 伺服器。設定為 true 以啟用 debuginfod 支援。", "c_cpp.debuggers.debuginfod.timeout.description": "debuginfod 伺服器要求的逾時秒數。預設值為 30。設定為 0 以使用 GDB/libdebuginfod 預設值 (無覆寫)。", "c_cpp.debuggers.VSSymbolOptions.description": "提供將符號尋找及載入至偵錯介面卡的設定。", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "符號陣列伺服器 URL (範例: http​://MyExampleSymbolServer) 或目錄 (範例: /build/symbols) 搜尋 .pdb 檔案。除了預設位置 (位於模組旁和 pdb 原先放置的路徑),也會搜尋這些目錄。", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "偵錯工具不應為其載入符號的模組陣列。支援萬用字元 (範例: MyCompany.*.dll)。\n\n除非 '模式' 設定為 'loadAllButExcluded',否則會忽略此屬性。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "偵錯工具應該為其載入符號的模組陣列。支援萬用字元 (範例: MyCompany.*.dll)。\n\n除非 '模式' 設定為 'loadOnlyIncluded',否則會忽略此屬性。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "若為 True,針對不在 'includedModules' 陣列中的任何模組,偵錯工具仍會檢查模組本身和啟動可執行檔的旁邊,但不會檢查符號搜尋清單上的路徑。此選項預設為 'true'。\n\n除非 '模式' 設定為 'loadOnlyIncluded',否則會忽略此屬性。", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "如果為 true,當不偵錯執行無法在終端機中啟動程式時,就不會記錄警告。", "c_cpp.semanticTokenTypes.referenceType.description": "C++/CLI 參考類型的樣式。", "c_cpp.semanticTokenTypes.cliProperty.description": "C++/CLI 屬性的樣式。", "c_cpp.semanticTokenTypes.genericType.description": "C++/CLI 泛型類型的樣式。", diff --git a/Extension/i18n/cht/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/cht/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 0a4a105c5..37348b6d1 100644 --- a/Extension/i18n/cht/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/cht/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "非 Windows 電腦無法使用偵錯工具類型 '{0}'。", "debugger.noDebug.requestType.not.supported": "僅啟動設定才支援「執行但不進行偵錯」。", - "debugger.noDebug.pipeTransport.not.supported": "設定 'pipeTransport' 的設定不支援「執行但不進行偵錯」。", - "debugger.noDebug.debugServerPath.not.supported": "設定 'debugServerPath' 的設定不支援「執行但不進行偵錯」。", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "設定 'miDebuggerServerAddress' 的設定不支援「執行但不進行偵錯」。", - "debugger.noDebug.coreDumpPath.not.supported": "設定 'coreDumpPath' 的設定不支援「執行但不進行偵錯」。" + "debugger.unsupported.properties": "具有下列屬性的啟動設定無法直接在終端機中執行: {0}", + "debugger.fallback.message": "程式輸出將會顯示在偵錯主控台中。", + "debugger.fallback.message2": "若要隱藏此警告,請在啟動設定中將 'ignoreRunWithoutDebuggingWarnings' 屬性設為 true。" } \ No newline at end of file diff --git a/Extension/i18n/cht/src/LanguageServer/extension.i18n.json b/Extension/i18n/cht/src/LanguageServer/extension.i18n.json index 9bc0c4495..af7a16235 100644 --- a/Extension/i18n/cht/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/cht/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "了解如何使用 vcpkg 安裝此標頭的程式庫", "copy.vcpkg.command": "將用於安裝 '{0}' 的 vcpkg 命令複製到剪貼簿", "on.disabled.command": "當 `C_Cpp.intelliSenseEngine` 設為 `disabled` 時,無法執行IntelliSense 的相關命令。", + "switch.header.source": "正在切換標頭/來源...", "client.not.found": "找不到用戶端", "ok": "確定", "install.compiler.mac.title": "現在將安裝 clang 編譯器", diff --git a/Extension/i18n/cht/src/nativeStrings.i18n.json b/Extension/i18n/cht/src/nativeStrings.i18n.json index 60580063f..7ba38b8ea 100644 --- a/Extension/i18n/cht/src/nativeStrings.i18n.json +++ b/Extension/i18n/cht/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "使用者拒絕授權。", "auth_unexpected_error": "輪詢期間發生未預期的錯誤: {0}", "auth_login_failed": "GitHub 登入失敗。請嘗試使用命令列中的 --login 進行登入。", + "auth_login_failed_plugin": "GitHub 登入失敗。請執行 npx @microsoft/cpp-language-server --login", "auth_eula_required": "必須接受 EULA 才能繼續。請使用 --accept-eula 執行。", + "auth_eula_required_plugin": "必須接受 EULA 才能繼續。請執行 npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "已使用 GitHub 驗證。使用 --force-login 重新驗證。", "config_unsupported_version": "初始化失敗: 不支援的設定版本。僅支援版本 1。", "config_file_not_found": "初始化失敗: 找不到設定檔 '{0}'。", diff --git a/Extension/i18n/csy/package.i18n.json b/Extension/i18n/csy/package.i18n.json index 045b5ca0a..b4ac6910e 100644 --- a/Extension/i18n/csy/package.i18n.json +++ b/Extension/i18n/csy/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Možnosti kontroly způsobu, jakým se hledají a načítají symboly (soubory .pdb).", "c_cpp.debuggers.unknownBreakpointHandling.description": "Určuje, jak se mají zarážky nastavené externě (obvykle prostřednictvím nezpracovaných příkazů GDB) zpracovávat při průchodu.\nPovolené hodnoty jsou throw, která se chová, jako by aplikace vyvolala výjimku, a stop, která pouze pozastaví ladicí relaci. Výchozí hodnota je throw.", "c_cpp.debuggers.debuginfod.description": "Řídí chování debuginfod v GDB při stahování symbolů ladění ze serverů debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Při hodnotě true (výchozí) je podpora debuginfod v GDB povolená. Pokud chcete zabránit GDB v kontaktování serverů debuginfod, nastavte hodnotu false.", + "c_cpp.debuggers.debuginfod.enabled.description": "Pokud je false (výchozí), GDB nebude kontaktovat servery debuginfod. Pokud chcete povolit debuginfod, nastavte na true.", "c_cpp.debuggers.debuginfod.timeout.description": "Časový limit v sekundách pro žádosti serveru debuginfod. Výchozí hodnota je 30. Pokud chcete použít výchozí hodnoty GDB/libdebuginfod, nastavte hodnotu 0 (bez přepsání).", "c_cpp.debuggers.VSSymbolOptions.description": "Poskytuje konfiguraci pro vyhledávání a načítání symbolů do ladicího adaptéru.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Pole adres URL serveru symbolů (například: http​://MyExampleSymbolServer) nebo adresářů (například: /build/symbols) k vyhledávání souborů .pdb. Tyto adresáře budou prohledány kromě výchozích umístění – vedle modulu a cesty, kam byl soubor pdb původně přemístěn.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Pole modulů, pro které by ladicí program neměl načítat symboly. Zástupné znaky (například: MyCompany. *.DLL) jsou podporovány.\n\nTato vlastnost je ignorována, pokud není „mode“ nastaven na hodnotu „loadAllButExcluded“.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Pole modulů, pro které má ladicí program načíst symboly. Zástupné znaky (například: MyCompany. *.DLL) jsou podporovány.\n\nTato vlastnost je ignorována, pokud není „mode“ nastaven na hodnotu „loadOnlyIncluded“.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Pokud má hodnotu true, u libovolného modulu, který není v poli „includedModules“, bude ladicí program stále provádět kontrolu vedle samotného modulu a spouštěcího souboru, ale nebude kontrolovat cesty v seznamu hledání symbolů. Tato možnost je standardně nastavena na hodnotu true.\n\nTato vlastnost je ignorována, pokud není „mode“ nastaven na hodnotu „loadOnlyIncluded“.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "Pokud je nastavena hodnota true, při neúspěšném spuštění programu v terminálu bez ladění se nezaznamená žádné upozornění.", "c_cpp.semanticTokenTypes.referenceType.description": "Styl pro referenční typy jazyka C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Styl pro vlastnosti jazyka C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Styl pro obecné typy jazyka C++/CLI.", diff --git a/Extension/i18n/csy/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/csy/src/Debugger/debugAdapterDescriptorFactory.i18n.json index bf28c08df..947f2eaba 100644 --- a/Extension/i18n/csy/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/csy/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Typ ladicího programu {0} není pro počítače, které nepoužívají Windows, k dispozici.", "debugger.noDebug.requestType.not.supported": "Spuštění bez ladění je podporováno pouze pro konfigurace spuštění.", - "debugger.noDebug.pipeTransport.not.supported": "Spuštění bez ladění není podporováno pro konfigurace s nastavenou hodnotou pipeTransport.", - "debugger.noDebug.debugServerPath.not.supported": "Spuštění bez ladění není podporováno pro konfigurace s nastavenou hodnotou debugServerPath.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Spuštění bez ladění není podporováno pro konfigurace s nastavenou hodnotou miDebuggerServerAddress.", - "debugger.noDebug.coreDumpPath.not.supported": "Spuštění bez ladění není podporováno pro konfigurace s nastavenou hodnotou coreDumpPath." + "debugger.unsupported.properties": "Konfigurace spuštění s následujícími vlastnostmi nelze spustit přímo v terminálu: {0}", + "debugger.fallback.message": "Výstup programu se místo toho zobrazí v konzole ladění.", + "debugger.fallback.message2": "Chcete-li toto upozornění potlačit, nastavte v konfiguraci spuštění vlastnost ignoreRunWithoutDebuggingWarnings na hodnotu true." } \ No newline at end of file diff --git a/Extension/i18n/csy/src/LanguageServer/extension.i18n.json b/Extension/i18n/csy/src/LanguageServer/extension.i18n.json index 114ba9c5a..22f72c4ac 100644 --- a/Extension/i18n/csy/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/csy/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Jak nainstalovat knihovnu pro tuto hlavičku pomocí vcpkg", "copy.vcpkg.command": "Zkopírovat příkaz vcpkg pro instalaci {0} do schránky", "on.disabled.command": "Příkazy související s IntelliSense se nedají spustit, když je `C_Cpp.intelliSenseEngine` nastavené na `disabled`.", + "switch.header.source": "Přepínání záhlaví/zdroje...", "client.not.found": "klient se nenašel", "ok": "OK", "install.compiler.mac.title": "Kompilátor clang se teď nainstaluje.", diff --git a/Extension/i18n/csy/src/nativeStrings.i18n.json b/Extension/i18n/csy/src/nativeStrings.i18n.json index 66c190532..bab4d474a 100644 --- a/Extension/i18n/csy/src/nativeStrings.i18n.json +++ b/Extension/i18n/csy/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Uživatel zamítl autorizaci.", "auth_unexpected_error": "Během dotazování došlo k neočekávané chybě: {0}", "auth_login_failed": "Nepovedlo se přihlásit ke GitHubu. Zkuste se přihlásit spuštěním příkazu --login z příkazového řádku.", + "auth_login_failed_plugin": "Nepovedlo se přihlásit ke GitHubu. Spusťte npx @microsoft/cpp-language-server --login", "auth_eula_required": "Aby bylo možné pokračovat, musí být přijata smlouva EULA. Spusťte příkaz --accept-eula.", + "auth_eula_required_plugin": "Aby bylo možné pokračovat, musí být přijata smlouva EULA. Spusťte npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Už ověřeno pomocí GitHubu. K opětovnému ověření použijte --force-login.", "config_unsupported_version": "Inicializace se nezdařila: Nepodporovaná verze konfigurace. Podporuje se jenom verze 1.", "config_file_not_found": "Inicializace se nezdařila: Konfigurační soubor {0} nebyl nalezen.", diff --git a/Extension/i18n/deu/package.i18n.json b/Extension/i18n/deu/package.i18n.json index 8f35de49b..630aa3a7b 100644 --- a/Extension/i18n/deu/package.i18n.json +++ b/Extension/i18n/deu/package.i18n.json @@ -283,17 +283,17 @@ "c_cpp.debuggers.pipeTransport.pipeEnv.description": "Umgebungsvariablen, die an das Pipeprogramm übergeben werden.", "c_cpp.debuggers.pipeTransport.quoteArgs.description": "Gibt an, ob Anführungszeichen gesetzt werden sollen, wenn die einzelnen pipeProgram-Argumente Zeichen enthalten (z. B. Leerzeichen oder Tabstopps). Bei Einstellung auf \"false\" wird der Debuggerbefehl nicht mehr automatisch in Anführungszeichen gesetzt. Der Standardwert ist \"true\".", "c_cpp.debuggers.logging.description": "Optionale Flags zum Festlegen, welche Nachrichtentypen in der Debugging-Konsole protokolliert werden sollen.", - "c_cpp.debuggers.logging.exceptions.description": "Optionales Flag zum Festlegen, ob Ausnahmemeldungen in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist TRUE.", - "c_cpp.debuggers.logging.moduleLoad.description": "Optionales Flag zum Festlegen, ob Modulladeereignisse in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist TRUE.", - "c_cpp.debuggers.logging.programOutput.description": "Optionales Flag zum Festlegen, ob die Programmausgabe in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist TRUE.", - "c_cpp.debuggers.logging.engineLogging.description": "Optionales Flag zum Festlegen, ob Nachrichten der Diagnosedebug-Engine in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist FALSE.", - "c_cpp.debuggers.logging.trace.description": "Optionales Flag zum Festlegen, ob die Befehlsablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist FALSE.", - "c_cpp.debuggers.logging.traceResponse.description": "Optionales Flag zum Festlegen, ob die Befehls- und Antwortablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist FALSE.", + "c_cpp.debuggers.logging.exceptions.description": "Optionales Flag zum Festlegen, ob Ausnahmemeldungen in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist \"true\".", + "c_cpp.debuggers.logging.moduleLoad.description": "Optionales Flag zum Festlegen, ob Modulladeereignisse in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist \"true\".", + "c_cpp.debuggers.logging.programOutput.description": "Optionales Flag zum Festlegen, ob die Programmausgabe in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist \"true\".", + "c_cpp.debuggers.logging.engineLogging.description": "Optionales Flag zum Festlegen, ob Nachrichten der Diagnosedebug-Engine in der Debugging-Konsole protokolliert werden sollen. Der Standardwert ist \"false\".", + "c_cpp.debuggers.logging.trace.description": "Optionales Flag zum Festlegen, ob die Befehlsablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist \"false\".", + "c_cpp.debuggers.logging.traceResponse.description": "Optionales Flag zum Festlegen, ob die Befehls- und Antwortablaufverfolgung des Diagnoseadapters in der Debugging-Konsole protokolliert werden soll. Der Standardwert ist \"false\".", "c_cpp.debuggers.cppvsdbg.logging.threadExit.description": "Optionales Flag zum Bestimmen, ob Meldungen zum Beenden des Threads in der Debugging-Konsole protokolliert werden sollen. Standardwert: \"false\".", "c_cpp.debuggers.cppvsdbg.logging.processExit.description": "Optionale Kennzeichnung zum Bestimmen, ob Meldungen zum Beenden des Zielprozesses in der Debugging-Konsole protokolliert werden sollen. Standardwert: \"true\".", "c_cpp.debuggers.text.description": "Der auszuführende Debuggerbefehl.", "c_cpp.debuggers.description.description": "Optionale Beschreibung des Befehls.", - "c_cpp.debuggers.ignoreFailures.description": "Wenn dieser Wert auf TRUE festgelegt ist, werden durch den Befehl verursachte Fehler ignoriert. Der Standardwert ist FALSE.", + "c_cpp.debuggers.ignoreFailures.description": "Wenn dieser Wert auf \"true\" festgelegt ist, werden durch den Befehl verursachte Fehler ignoriert. Der Standardwert ist \"false\".", "c_cpp.debuggers.program.description": "Vollständiger Pfad zur ausführbaren Programmdatei.", "c_cpp.debuggers.args.description": "Befehlszeilenargumente, die an das Programm übergeben werden.", "c_cpp.debuggers.targetArchitecture.description": "Die Architektur der zu debuggenden Komponente. Falls dieser Parameter nicht festgelegt ist, wird die Architektur automatisch erkannt. Zulässige Werte sind \"x86\", \"arm\", \"arm64\", \"mips\", \"x64\", \"amd64\" und \"x86_64\".", @@ -322,23 +322,23 @@ "c_cpp.debuggers.filterStderr.description": "stderr-Stream für ein vom Server gestartetes Muster suchen und stderr in der Debugausgabe protokollieren. Der Standardwert ist \"false\".", "c_cpp.debuggers.serverLaunchTimeout.description": "Optionale Zeit in Millisekunden, während der der Debugger auf den Start von debugServer wartet. Der Standardwert ist 10.000.", "c_cpp.debuggers.coreDumpPath.description": "Optionaler vollständiger Pfad zu einer Kern-Speicherabbilddatei für das angegebene Programm. Der Standardwert ist \"NULL\".", - "c_cpp.debuggers.cppdbg.externalConsole.description": "Wenn dieser Wert auf TRUE festgelegt ist, wird eine Konsole für die zu debuggende Komponente gestartet. Bei FALSE wird die Komponente unter Linux und Windows in der integrierten Konsole angezeigt.", - "c_cpp.debuggers.cppvsdbg.externalConsole.description": "[Veraltet für \"console\"] Wenn dieser Wert auf TRUE festgelegt ist, wird eine Konsole für die zu debuggende Komponente gestartet. Bei FALSE wird keine Konsole gestartet.", + "c_cpp.debuggers.cppdbg.externalConsole.description": "Wenn dieser Wert auf \"true\" festgelegt ist, wird eine Konsole für die zu debuggende Komponente gestartet. Bei \"false\" wird die Komponente unter Linux und Windows in der integrierten Konsole angezeigt.", + "c_cpp.debuggers.cppvsdbg.externalConsole.description": "[Veraltet für \"console\"] Wenn dieser Wert auf \"true\" festgelegt ist, wird eine Konsole für die zu debuggende Komponente gestartet. Bei \"false\" wird keine Konsole gestartet.", "c_cpp.debuggers.cppvsdbg.console.description": "Gibt an, wo das Debugziel gestartet wird. Wenn keine Angabe vorliegt, wird standardmäßig „internalConsole“ verwendet.", "c_cpp.debuggers.cppvsdbg.console.internalConsole.description": "Die Ausgabe an die Debugging-Konsole von VS Code. Das Lesen von Konsoleneingaben (z. B. `std::cin` oder `scanf`) wird nicht unterstützt.", "c_cpp.debuggers.cppvsdbg.console.integratedTerminal.description": "Das integrierte Terminal von VS Code.", "c_cpp.debuggers.cppvsdbg.console.externalTerminal.description": "Konsolenanwendungen werden in einem externen Terminalfenster gestartet. Das Fenster wird in Neustartszenarien erneut verwendet und beim Beenden der Anwendung nicht automatisch ausgeblendet.", "c_cpp.debuggers.cppvsdbg.console.newExternalWindow.description": "Konsolenanwendungen werden in ihrem eigenen externen Konsolenfenster gestartet, das beim Beenden der Anwendung ebenfalls beendet wird. Nicht-Konsolenanwendungen werden ohne Terminal ausgeführt, und stdout/stderr wird ignoriert.", - "c_cpp.debuggers.avoidWindowsConsoleRedirection.description": "Wenn dieser Wert auf TRUE festgelegt ist, wird für die zu debuggende Komponente die Konsolenumleitung deaktiviert, die für die Unterstützung des integrierten Terminals erforderlich ist.", + "c_cpp.debuggers.avoidWindowsConsoleRedirection.description": "Wenn dieser Wert auf \"true\" festgelegt ist, wird für die zu debuggende Komponente die Konsolenumleitung deaktiviert, die für die Unterstützung des integrierten Terminals erforderlich ist.", "c_cpp.debuggers.sourceFileMap.markdownDescription": "Optionale Quelldateizuordnungen, die an die Debug-Engine übergeben werden. Beispiel: `{ \"\": \"\" }`.", "c_cpp.debuggers.processId.anyOf.markdownDescription": "Optionale Prozess-ID, an die der Debugger angefügt werden soll. Verwenden Sie `${command:pickProcess}`, um eine Liste der lokalen ausgeführten Prozesse abzurufen, an die das Anfügen möglich ist. Beachten Sie, dass für einige Plattformen Administratorrechte erforderlich sind, damit an einen Prozess angefügt werden kann.", "c_cpp.debuggers.program.attach.markdownDescription": "Vollständiger Pfad zur ausführbaren Programmdatei. Der Debugger sucht nach einem laufenden Prozess, der diesem ausführbaren Pfad entspricht, und bindet ihn an. Wenn mehrere Prozesse übereinstimmen, wird eine Auswahlaufforderung angezeigt. Dieses Feld ist erforderlich, um Debugsymbole für den angehängten Prozess zu laden.", "c_cpp.debuggers.symbolSearchPath.description": "Durch Semikolons getrennte Liste von Verzeichnissen, die für die Suche nach Symboldateien (d. h. PDB- oder .so-Dateien) verwendet werden sollen. Beispiel: „c:\\dir1;c:\\dir2“.", "c_cpp.debuggers.dumpPath.description": "Optionaler vollständiger Pfad zu einer Dumpdatei für das angegebene Programm. Beispiel: \"c:\\temp\\app.dmp\". Standardwert ist NULL.", - "c_cpp.debuggers.enableDebugHeap.description": "Wenn dieser Wert auf FALSE festgelegt ist, wird der Prozess mit deaktiviertem Debug-Heap gestartet. Hiermit wird die Umgebungsvariable \"_NO_DEBUG_HEAP\" auf \"1\" festgelegt.", + "c_cpp.debuggers.enableDebugHeap.description": "Wenn dieser Wert auf \"false\" festgelegt ist, wird der Prozess mit deaktiviertem Debug-Heap gestartet. Hiermit wird die Umgebungsvariable \"_NO_DEBUG_HEAP\" auf \"1\" festgelegt.", "c_cpp.debuggers.symbolLoadInfo.description": "Explizite Steuerung des Symbolladevorgangs.", - "c_cpp.debuggers.symbolLoadInfo.loadAll.description": "Bei TRUE werden Symbole für alle Bibliotheken geladen, andernfalls werden keine solib-Symbole geladen. Der Standardwert ist TRUE.", - "c_cpp.debuggers.symbolLoadInfo.exceptionList.description": "Liste mit Dateinamen (Platzhalter zulässig), getrennt durch Semikolons `;`. Ändert das Verhalten von „LoadAll“. Wenn „LoadAll“ auf `TRUE` festgelegt ist, werden keine Symbole für Bibliotheken geladen, die einem beliebigen Namen in der Liste entsprechen. Andernfalls werden nur Symbole für übereinstimmende Bibliotheken geladen. Beispiel: `foo.so;bar.so`.", + "c_cpp.debuggers.symbolLoadInfo.loadAll.description": "Bei \"true\" werden Symbole für alle Bibliotheken geladen, andernfalls werden keine solib-Symbole geladen. Der Standardwert ist \"true\".", + "c_cpp.debuggers.symbolLoadInfo.exceptionList.description": "Liste mit Dateinamen (Platzhalter zulässig), getrennt durch Semikolons `;`. Ändert das Verhalten von „LoadAll“. Wenn „LoadAll“ auf \"true\" festgelegt ist, werden keine Symbole für Bibliotheken geladen, die einem beliebigen Namen in der Liste entsprechen. Andernfalls werden nur Symbole für übereinstimmende Bibliotheken geladen. Beispiel: `foo.so;bar.so`.", "c_cpp.debuggers.requireExactSource.description": "Optionales Flag, um anzufordern, dass der aktuelle Quellcode mit der PDB-Datei übereinstimmt.", "c_cpp.debuggers.stopAtConnect.description": "Wenn \"true\", sollte der Debugger nach dem Herstellen einer Verbindung mit dem Ziel beendet werden. Wenn \"false\" wird der Debugger nach dem Herstellen der Verbindung fortgesetzt. Entspricht standardmäßig \"false\".", "c_cpp.debuggers.hardwareBreakpoints.description": "Explizite Steuerung des Hardwarehaltepunktverhaltens für Remoteziele.", @@ -388,11 +388,11 @@ "c_cpp.taskDefinitions.detail.description": "Zusätzliche Details zur Aufgabe.", "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.description": "Dies sind die Pfade zu denselben Quellstrukturen – einmal aktuell und einmal zur Kompilierzeit. Im EditorPath gefundene Dateien werden zum Haltepunktabgleich dem CompileTimePath-Pfad zugeordnet. Bei der Anzeige von Speicherorten für die Stapelüberwachung erfolgt die Zuordnung vom CompileTimePath zum EditorPath.", "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.editorPath.description": "Der Pfad zur Quellstruktur, die vom Editor verwendet wird.", - "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.useForBreakpoints.description": "FALSE, wenn dieser Eintrag nur für eine Stapelrahmen-Speicherortzuordnung verwendet wird. TRUE, wenn dieser Eintrag auch zum Angeben von Haltepunktpositionen verwendet werden soll.", + "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.useForBreakpoints.description": "\"false\", wenn dieser Eintrag nur für eine Stapelrahmen-Speicherortzuordnung verwendet wird. \"true\", wenn dieser Eintrag auch zum Angeben von Haltepunktpositionen verwendet werden soll.", "c_cpp.debuggers.symbolOptions.description": "Optionen zum Steuern, wie Symbole (PDB-Dateien) gefunden und geladen werden.", "c_cpp.debuggers.unknownBreakpointHandling.description": "Steuert, wie extern gesetzte Haltepunkte (normalerweise über rohe GDB-Befehle) behandelt werden, wenn ihnen begegnet wird.\nErlaubte Werte sind \"throw\", was sich so verhält, als ob eine Ausnahme von der Anwendung ausgelöst würde, und \"stop\", was die Debugsitzung nur pausiert. Der Standardwert ist \"throw\".", "c_cpp.debuggers.debuginfod.description": "Steuert das debuginfod-Verhalten von GDB beim Herunterladen von Debugsymbolen von debuginfod-Servern.", - "c_cpp.debuggers.debuginfod.enabled.description": "Wenn auf TRUE (Standard) festgelegt, ist die debuginfod-Unterstützung in GDB aktiviert. Legen Sie den Wert auf FALSE fest, um zu verhindern, dass GDB debuginfod-Server kontaktiert.", + "c_cpp.debuggers.debuginfod.enabled.description": "Wenn \"false\" (Standard), kann GDB keine Verbindung mit debuginfod-Servern herstellen. Legen Sie den Wert auf \"true\" fest, um den debuginfod-Support zu aktivieren.", "c_cpp.debuggers.debuginfod.timeout.description": "Das Zeitlimit in Sekunden für debuginfod-Serveranforderungen. Standardwert ist 30. Auf 0 festlegen, um die Standardwerte von GDB/libdebuginfod zu verwenden (keine Überschreibung).", "c_cpp.debuggers.VSSymbolOptions.description": "Stellt eine Konfiguration zum Suchen und Laden von Symbolen in den Debugadapter bereit.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Ein Array von Symbolserver-URLs (Beispiel: http​://MyExampleSymbolServer) oder Verzeichnisse (Beispiel:/Build/Symbols) für die Suche nach PDB-Dateien. Diese Verzeichnisse werden zusätzlich zu den Standardspeicherorten durchsucht – neben dem Modul und dem Pfad, in dem die PDB ursprünglich abgelegt wurde.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Ein Array von Modulen, für das der Debugger keine Symbole laden soll. Platzhalter (Beispiel: MyCompany. *. dll) werden unterstützt.\n\nDiese Eigenschaft wird ignoriert, wenn „Modus“ nicht auf „loadAllButExcluded“ festgelegt ist.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Ein Array von Modulen, für das der Debugger keine Symbole laden soll. Platzhalter (Beispiel: MyCompany. *. dll) werden unterstützt.\n\nDiese Eigenschaft wird ignoriert, wenn „Modus“ nicht auf „loadOnlyIncluded“ festgelegt ist.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Wenn „true“, wird der Debugger für ein beliebiges Modul, das sich NICHT im Array „includedModules“ befindet, weiterhin neben dem Modul selbst und der ausführbaren Datei, die gestartet wird, überprüfen. Die Pfade in der Symbolsuchliste werden jedoch nicht überprüft. Diese Option ist standardmäßig auf „true“ eingestellt.\n\nDiese Eigenschaft wird ignoriert, wenn „Modus“ nicht auf „loadOnlyIncluded“ festgelegt ist.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "If true, no warning will be logged when run without debugging fails to launch the program in the terminal.", "c_cpp.semanticTokenTypes.referenceType.description": "Stil für C++-/CLI-Referenztypen.", "c_cpp.semanticTokenTypes.cliProperty.description": "Stil für C++-/CLI-Eigenschaften.", "c_cpp.semanticTokenTypes.genericType.description": "Stil für generische C++-/CLI-Typen.", diff --git a/Extension/i18n/deu/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/deu/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 72016e1b3..d0801e204 100644 --- a/Extension/i18n/deu/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/deu/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Der Debuggertyp \"{0}\" ist für Nicht-Windows-Computer nicht verfügbar.", "debugger.noDebug.requestType.not.supported": "„Ausführen ohne Debuggen“ wird nur für Startkonfigurationen unterstützt.", - "debugger.noDebug.pipeTransport.not.supported": "„Ausführen ohne Debuggen“ wird für Konfigurationen mit festgelegtem „pipeTransport“ nicht unterstützt.", - "debugger.noDebug.debugServerPath.not.supported": "„Ausführen ohne Debuggen“ wird für Konfigurationen, für die „debugServerPath“ festgelegt ist, nicht unterstützt.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Das Ausführen ohne Debuggen wird für Konfigurationen mit festgelegter „miDebuggerServerAddress“ nicht unterstützt.", - "debugger.noDebug.coreDumpPath.not.supported": "„Ausführen ohne Debuggen“ wird für Konfigurationen, für die „coreDumpPath“ festgelegt ist, nicht unterstützt." + "debugger.unsupported.properties": "Startkonfigurationen mit den folgenden Eigenschaften können nicht direkt im Terminal ausgeführt werden: {0}", + "debugger.fallback.message": "Die Programmausgabe wird stattdessen in der Debugging-Konsole angezeigt.", + "debugger.fallback.message2": "Um diese Warnung zu unterdrücken, legen Sie die Eigenschaft „ignoreRunWithoutDebuggingWarnings“ in Ihrer Startkonfiguration auf \"true\" fest." } \ No newline at end of file diff --git a/Extension/i18n/deu/src/LanguageServer/extension.i18n.json b/Extension/i18n/deu/src/LanguageServer/extension.i18n.json index 45c9a387f..bfa4312dc 100644 --- a/Extension/i18n/deu/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/deu/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Erfahren Sie, wie Sie mit vcpkg eine Bibliothek für diesen Header installieren.", "copy.vcpkg.command": "vcpkg-Befehl zum Installieren von \"{0}\" in die Zwischenablage kopieren", "on.disabled.command": "IntelliSense-bezogene Befehle können nicht ausgeführt werden, wenn `C_Cpp.intelliSenseEngine` auf `disabled` festgelegt ist.", + "switch.header.source": "Header/Quelle wird gewechselt...", "client.not.found": "Client nicht gefunden.", "ok": "OK", "install.compiler.mac.title": "Der Clang-Compiler wird jetzt installiert.", diff --git a/Extension/i18n/deu/src/nativeStrings.i18n.json b/Extension/i18n/deu/src/nativeStrings.i18n.json index a5b61c554..e4bb84e16 100644 --- a/Extension/i18n/deu/src/nativeStrings.i18n.json +++ b/Extension/i18n/deu/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Die Autorisierung wurde vom Benutzer verweigert.", "auth_unexpected_error": "Unerwarteter Fehler beim Abrufen: {0}", "auth_login_failed": "Die GitHub-Anmeldung ist fehlgeschlagen. --login über die Befehlszeile ausführen, um sich anzumelden.", + "auth_login_failed_plugin": "Die GitHub-Anmeldung ist fehlgeschlagen. Führen Sie npx @microsoft/cpp-language-server --login aus.", "auth_eula_required": "EULA muss akzeptiert werden, um den Vorgang fortzusetzen. Mit --accept-eula ausführen.", + "auth_eula_required_plugin": "EULA muss akzeptiert werden, um den Vorgang fortzusetzen. Führen Sie npx @microsoft/cpp-language-server --accept-eula aus.", "auth_already_authenticated": "Bereits bei GitHub authentifiziert. Verwenden Sie „--force-login“, um sich erneut zu authentifizieren.", "config_unsupported_version": "Initialisierungsfehler: Nicht unterstützte Konfigurationsversion. Es wird nur Version 1 unterstützt.", "config_file_not_found": "Initialisierungsfehler: Die Konfigurationsdatei „{0}“ wurde nicht gefunden.", diff --git a/Extension/i18n/esn/package.i18n.json b/Extension/i18n/esn/package.i18n.json index d0fe8d350..40adb0b6a 100644 --- a/Extension/i18n/esn/package.i18n.json +++ b/Extension/i18n/esn/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Opciones para controlar cómo se encuentran y se cargan los símbolos (archivos .pdb).", "c_cpp.debuggers.unknownBreakpointHandling.description": "Controla cómo se controlan los puntos de interrupción establecidos externamente (normalmente a través de comandos GDB sin procesar) cuando se alcanzan.\nLos valores permitidos son \"throw\", que actúa como si la aplicación iniciara una excepción y \"stop\", que solo pausa la sesión de depuración. El valor predeterminado es \"throw\".", "c_cpp.debuggers.debuginfod.description": "Controla el comportamiento de debuginfod de GDB para descargar símbolos de depuración de servidores debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Si es true (valor predeterminado), la compatibilidad con debuginfod de GDB está habilitada. Se establece en false para evitar que GDB se ponga en contacto con los servidores debuginfod.", + "c_cpp.debuggers.debuginfod.enabled.description": "Si es false (valor predeterminado), GDB no se pondrá en contacto con los servidores debuginfod. Establézcalo en true para habilitar la compatibilidad con debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "Tiempo de espera, en segundos, para las solicitudes al servidor debuginfod. El valor predeterminado es 30. Se establece en 0 para usar los valores predeterminados de GDB/libdebuginfod (sin invalidación).", "c_cpp.debuggers.VSSymbolOptions.description": "Proporciona la configuración para buscar y cargar símbolos en el adaptador de depuración.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Matriz de direcciones URL del servidor de símbolos (ejemplo: http​://MiServidordeSímblosdeEjemplo) o de directorios (ejemplo: /compilar/symbols) para buscar archivos. pdb. Se buscarán estos directorios además de las ubicaciones predeterminadas, junto al módulo y la ruta de acceso en la que se anuló originalmente el archivo pdb.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Matriz de módulos para los que el depurador NO debería cargar símbolos. Se admiten los caracteres comodín (ejemplo: MiEmpresa.*.dll).\n\nEsta propiedad se ignora a menos que «modo» se establezca como «loadAllButExcluded».", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Matriz de módulos para los que el depurador debería cargar símbolos. Se admiten los caracteres comodín (ejemplo: MiEmpresa.*.dll).\n\nEsta propiedad se ignora a menos que «modo» se establezca como «loadOnlyIncluded».", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Si es verdadero, para cualquier módulo que NO esté en la matriz «includedModules», el depurador seguirá comprobando junto al propio módulo y el ejecutable de inicio, pero no comprobará las rutas en la lista de búsqueda de símbolos. Esta opción tiene el valor predeterminado «verdadero».\n\nEsta propiedad se omite a menos que «modo» esté establecido como «loadOnlyIncluded».", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "Si es true, no se registrará ninguna advertencia cuando la ejecución sin depuración no pueda iniciar el programa en el terminal.", "c_cpp.semanticTokenTypes.referenceType.description": "Estilo para tipos de referencia de C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Estilo para las propiedades de C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Estilo para tipos genéricos de C++/CLI.", diff --git a/Extension/i18n/esn/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/esn/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 0d10aae8c..a6c393224 100644 --- a/Extension/i18n/esn/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/esn/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "El tipo de depurador '{0}' no está disponible para equipos que no son de Windows.", "debugger.noDebug.requestType.not.supported": "Ejecutar sin depuración solo se admite para las configuraciones de inicio.", - "debugger.noDebug.pipeTransport.not.supported": "No se admite ejecutar sin depuración para configuraciones con \"pipeTransport\" establecido.", - "debugger.noDebug.debugServerPath.not.supported": "No se admite ejecutar sin depuración para configuraciones con el valor \"debugServerPath\" establecido.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "No se admite ejecutar sin depuración para configuraciones con el conjunto \"miDebuggerServerAddress\".", - "debugger.noDebug.coreDumpPath.not.supported": "No se admite ejecutar sin depuración para configuraciones con \"coreDumpPath\" establecido." + "debugger.unsupported.properties": "Las configuraciones de inicio con las siguientes propiedades no se pueden ejecutar directamente en el terminal: {0}", + "debugger.fallback.message": "En su lugar, la salida del programa aparecerá en la Consola de depuración.", + "debugger.fallback.message2": "Para suprimir esta advertencia, establezca la propiedad \"ignoreRunWithoutDebuggingWarnings\" en true en la configuración de inicio." } \ No newline at end of file diff --git a/Extension/i18n/esn/src/LanguageServer/extension.i18n.json b/Extension/i18n/esn/src/LanguageServer/extension.i18n.json index 3ba65ca3e..5b405224f 100644 --- a/Extension/i18n/esn/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/esn/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Más información sobre el modo de instalar una biblioteca para este encabezado con vcpkg", "copy.vcpkg.command": "Copie el comando vcpkg para instalar \"{0}\" en el Portapapeles", "on.disabled.command": "Los comandos relacionados con IntelliSense no se pueden ejecutar cuando `C_Cpp.intelliSenseEngine` está establecido en `disabled`.", + "switch.header.source": "Cambiando encabezado/origen...", "client.not.found": "No se encuentra el cliente", "ok": "Aceptar", "install.compiler.mac.title": "El compilador Clang se instalará ahora", diff --git a/Extension/i18n/esn/src/nativeStrings.i18n.json b/Extension/i18n/esn/src/nativeStrings.i18n.json index 39869996e..f46e26836 100644 --- a/Extension/i18n/esn/src/nativeStrings.i18n.json +++ b/Extension/i18n/esn/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "El usuario denegó la autorización.", "auth_unexpected_error": "Error inesperado durante el sondeo: {0}", "auth_login_failed": "Error de inicio de sesión de GitHub. Intente ejecutar con --login desde la línea de comandos para iniciar sesión.", + "auth_login_failed_plugin": "Error de inicio de sesión de GitHub. Ejecute npx @microsoft/cpp-language-server --login", "auth_eula_required": "Se debe aceptar el EULA para continuar. Se ejecuta con --accept-eula.", + "auth_eula_required_plugin": "Se debe aceptar el EULA para continuar. Ejecute npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Ya se ha autenticado con GitHub. Use --force-login para volver a autenticarse.", "config_unsupported_version": "Error de inicialización: versión de configuración no admitida. Solo se admite la versión 1.", "config_file_not_found": "Error de inicialización: no se encontró el archivo de configuración ''{0}\".", diff --git a/Extension/i18n/fra/package.i18n.json b/Extension/i18n/fra/package.i18n.json index 3d46e19b8..40d297719 100644 --- a/Extension/i18n/fra/package.i18n.json +++ b/Extension/i18n/fra/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Options permettant de contrôler la façon dont les symboles (fichiers .pdb) sont trouvés et chargés.", "c_cpp.debuggers.unknownBreakpointHandling.description": "Contrôle la façon dont les points d’arrêt définis en externe (généralement via des commandes GDB brutes) sont gérés en cas d’accès.\nLes valeurs autorisées sont « throw », qui agit comme si une exception était levée par l’application, et « stop », qui suspend uniquement la session de débogage. La valeur par défaut est « throw ».", "c_cpp.debuggers.debuginfod.description": "Permet de contrôler le comportement de debuginfod par GDB pour télécharger les symboles de débogage à partir de serveurs debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Si la valeur est true (par défaut), la prise en charge de debuginfod par GDB est activée. Définissez-la sur false pour empêcher GDB de contacter des serveurs debuginfod.", + "c_cpp.debuggers.debuginfod.enabled.description": "Si la valeur est false (par défaut), GDB ne contacte pas les serveurs debuginfod. Définissez sur la valeur true pour activer debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "Délai d’expiration en secondes pour les requêtes du serveur debuginfod. La valeur par défaut est 30. Définissez sur 0 pour utiliser les valeurs par défaut de GDB/libdebuginfod (aucune substitution).", "c_cpp.debuggers.VSSymbolOptions.description": "Fournit la configuration pour localiser et charger des symboles sur l’adaptateur de débogage.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Tableau d’URL de serveur de symboles (exemple : http​://MyExampleSymbolServer) ou répertoires (exemple : /build/symbols) pour rechercher des fichiers .pdb. Ces répertoires seront recherchés en plus des emplacements par défaut, en regard du module et du chemin d’accès vers lequel le fichier pdb a été supprimé à l’origine.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Tableau de modules pour lequel le débogueur ne doit PAS charger de symboles. Les caractères génériques (exemple : MonEntreprise.*.dll) sont pris en charge.\n\nCette propriété est ignorée, sauf si « mode » a la valeur «loadAllButExcluded».", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Tableau de modules pour lequel le débogueur doit charger des symboles. Les caractères génériques (exemple : MonEntreprise.*.dll) sont pris en charge.\n\nCette propriété est ignorée, sauf si « mode » a la valeur «loadOnlyIncluded».", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Si la valeur est true, pour tout module qui ne figure pas dans le tableau « includedModules », le débogueur vérifie toujours en regard du module lui-même et de l’exécutable de lancement, mais il ne vérifie pas les chemins d’accès dans la liste de recherche de symboles. Cette option a la valeur par défaut « true ».\n\nCette propriété est ignorée, sauf si « mode » a la valeur «loadOnlyIncluded».", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "Si la valeur est true, aucun avertissement ne sera consigné quand l’exécution sans débogage échoue à lancer le programme dans le terminal.", "c_cpp.semanticTokenTypes.referenceType.description": "Style pour les types référence C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Style pour les propriétés C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Style pour les types génériques C++/CLI.", diff --git a/Extension/i18n/fra/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/fra/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 2e42f9a27..8fc2c4329 100644 --- a/Extension/i18n/fra/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/fra/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Le type de débogueur '{0}' n’est pas disponible pour les machines non Windows.", "debugger.noDebug.requestType.not.supported": "L’exécution sans débogage n’est prise en charge que pour les configurations de lancement.", - "debugger.noDebug.pipeTransport.not.supported": "L’exécution sans débogage n’est pas prise en charge pour les configurations où « pipeTransport » est défini.", - "debugger.noDebug.debugServerPath.not.supported": "L’exécution sans débogage n’est pas prise en charge pour les configurations où « debugServerPath » est défini.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "L’exécution sans débogage n’est pas prise en charge pour les configurations où « miDebuggerServerAddress » est défini.", - "debugger.noDebug.coreDumpPath.not.supported": "L’exécution sans débogage n’est pas prise en charge pour les configurations où « coreDumpPath » est défini." + "debugger.unsupported.properties": "Les configurations de lancement avec les propriétés suivantes ne peuvent pas être exécutées directement dans le terminal : {0}", + "debugger.fallback.message": "La sortie du programme s’affichera dans la Console de débogage à la place.", + "debugger.fallback.message2": "Pour supprimer cet avertissement, définissez la propriété « ignoreRunWithoutDebuggingWarnings » sur true dans votre configuration de lancement." } \ No newline at end of file diff --git a/Extension/i18n/fra/src/LanguageServer/extension.i18n.json b/Extension/i18n/fra/src/LanguageServer/extension.i18n.json index 168c6f64b..a3c98f85d 100644 --- a/Extension/i18n/fra/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/fra/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Découvrir comment installer une bibliothèque pour cet en-tête avec vcpkg", "copy.vcpkg.command": "Copier la commande vcpkg pour installer '{0}' dans le Presse-papiers", "on.disabled.command": "Les commandes liées à IntelliSense ne peuvent pas être exécutées quand `C_Cpp.intelliSenseEngine` a la valeur `disabled`.", + "switch.header.source": "Changement d’en-tête/source en cours... Merci de patienter.", "client.not.found": "client introuvable", "ok": "OK", "install.compiler.mac.title": "Le compilateur clang va maintenant être installé", diff --git a/Extension/i18n/fra/src/nativeStrings.i18n.json b/Extension/i18n/fra/src/nativeStrings.i18n.json index 83ce896b1..71dc9a6c2 100644 --- a/Extension/i18n/fra/src/nativeStrings.i18n.json +++ b/Extension/i18n/fra/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "L’autorisation a été refusée par l’utilisateur(-trice).", "auth_unexpected_error": "Erreur inattendue lors de l’interrogation : {0}", "auth_login_failed": "Nous n’avons pas pu effectuer la connexion à GitHub. Essayez d’exécuter la commande avec --login depuis la ligne de commande pour vous connecter.", + "auth_login_failed_plugin": "Nous n’avons pas pu effectuer la connexion à GitHub. Exécutez npx @microsoft/cpp-language-server --login", "auth_eula_required": "Le CLUF doit être accepté pour continuer. Exécutez avec --accept-eula.", + "auth_eula_required_plugin": "Le CLUF doit être accepté pour continuer. Exécutez npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Déjà authentifié auprès de GitHub. Utilisez --force-login pour vous réauthentifier.", "config_unsupported_version": "Échec de l’initialisation : version de configuration non prise en charge. Seule la version 1 est prise en charge.", "config_file_not_found": "Échec de l’initialisation : le fichier de configuration « {0} » est introuvable.", diff --git a/Extension/i18n/ita/package.i18n.json b/Extension/i18n/ita/package.i18n.json index 1a73943f9..61697d161 100644 --- a/Extension/i18n/ita/package.i18n.json +++ b/Extension/i18n/ita/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Opzioni per controllare il modo in cui vengono trovati e caricati i simboli (file PDB).", "c_cpp.debuggers.unknownBreakpointHandling.description": "Controllare la modalità di gestione dei punti di interruzione impostati esternamente (in genere tramite comandi GDB non elaborati) quando vengono selezionati.\nI valori consentiti sono \"throw\", che funziona come se fosse stata generata un'eccezione dall'applicazione e \"stop\", che sospende solo la sessione di debug. Il valore predefinito è \"throw\".", "c_cpp.debuggers.debuginfod.description": "Controllare il comportamento di debuginfod in GDB per il download dei simboli di debug dai server debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Se true (impostazione predefinita), il supporto a debuginfod di GDB è abilitato. Impostare su false per impedire a GDB di contattare i server debuginfod.", + "c_cpp.debuggers.debuginfod.enabled.description": "Se è false (impostazione predefinita), GDB non contatterà i server debuginfod. Impostarlo su true per abilitare debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "Il timeout in secondi per le richieste al server debuginfod. Il valore predefinito è 30. Impostare su 0 per usare le impostazioni predefinite di GDB/libdebuginfod (senza override).", "c_cpp.debuggers.VSSymbolOptions.description": "Fornisce la configurazione per l'individuazione e il caricamento dei simboli nell'adattatore di debug.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Matrice di URL del server dei simboli, ad esempio http​://MyExampleSymbolServer, o di directory, ad esempio /build/symbols, in cui eseguire la ricerca dei file PDB. La ricerca verrà eseguita in queste directory oltre che nei percorsi predefiniti, in aggiunta al modulo e al percorso in cui è stato rilasciato originariamente il file PDB.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Matrice di moduli per cui il debugger non deve caricare i simboli. I caratteri jolly, ad esempio MyCompany.*.dll, sono supportati.\n\nQuesta proprietà viene ignorata a meno che 'mode' non sia impostato su 'loadAllButExcluded'.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Matrice di moduli per cui il debugger deve caricare i simboli. I caratteri jolly, ad esempio MyCompany.*.dll, sono supportati.\n\nQuesta proprietà viene ignorata a meno che 'mode' non sia impostato su 'loadOnlyIncluded'.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Se è true, per qualsiasi modulo non presente nella matrice 'includedModules', il debugger eseguirà comunque il controllo in aggiunta al modulo stesso e all'eseguibile di avvio, ma non controllerà nei percorsi dell'elenco di ricerca dei simboli. L'impostazione predefinita di questa opzione è 'true'.\n\nQuesta proprietà viene ignorata a meno che 'mode' non sia impostato su 'loadOnlyIncluded'.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "If true, no warning will be logged when run without debugging fails to launch the program in the terminal.", "c_cpp.semanticTokenTypes.referenceType.description": "Stile per i tipi di riferimento C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Stile per le proprietà C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Stile per tipi generici C++/CLI.", diff --git a/Extension/i18n/ita/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/ita/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 3af87b013..6e26d0fcc 100644 --- a/Extension/i18n/ita/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/ita/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Il tipo di debugger '{0}' non è disponibile per computer non Windows.", "debugger.noDebug.requestType.not.supported": "L'opzione Esegui senza debug è supportata solo per le configurazioni di avvio.", - "debugger.noDebug.pipeTransport.not.supported": "L'opzione Esegui senza debug non è supportata per le configurazioni con \"pipeTransport\" impostato.", - "debugger.noDebug.debugServerPath.not.supported": "L'opzione Esegui senza debug non è supportata per le configurazioni con \"debugServerPath\" impostato.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "L'opzione Esegui senza debug non è supportata per le configurazioni con \"miDebuggerServerAddress\" impostato.", - "debugger.noDebug.coreDumpPath.not.supported": "L'opzione Esegui senza debug non è supportata per le configurazioni con \"coreDumpPath\" impostato." + "debugger.unsupported.properties": "Le configurazioni di avvio con le proprietà seguenti non possono essere eseguite direttamente nel terminale: {0}", + "debugger.fallback.message": "L'output del programma verrà invece visualizzato nella Console di debug.", + "debugger.fallback.message2": "Per eliminare questo avviso, impostare la proprietà 'ignoreRunWithoutDebuggingWarnings' su vero nella configurazione di avvio." } \ No newline at end of file diff --git a/Extension/i18n/ita/src/LanguageServer/extension.i18n.json b/Extension/i18n/ita/src/LanguageServer/extension.i18n.json index a18f3637e..a2056f16b 100644 --- a/Extension/i18n/ita/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/ita/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Informazioni su come installare una libreria per questa intestazione con vcpkg", "copy.vcpkg.command": "Copiare il comando vcpkg per installare '{0}' negli Appunti", "on.disabled.command": "Non è possibile eseguire comandi correlati a IntelliSense quando `C_Cpp.intelliSenseEngine` è impostato su `disabled`.", + "switch.header.source": "Scambio intestazione/origine in corso...", "client.not.found": "client non trovato", "ok": "OK", "install.compiler.mac.title": "Il compilatore clang verrà ora installato", diff --git a/Extension/i18n/ita/src/nativeStrings.i18n.json b/Extension/i18n/ita/src/nativeStrings.i18n.json index 50c5fd083..21ecb0b5f 100644 --- a/Extension/i18n/ita/src/nativeStrings.i18n.json +++ b/Extension/i18n/ita/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Autorizzazione negata dall'utente.", "auth_unexpected_error": "Errore imprevisto durante il polling: {0}", "auth_login_failed": "Accesso a GitHub non riuscito. Per eseguire l'accesso, provare a eseguire --login dalla riga di comando.", + "auth_login_failed_plugin": "Accesso a GitHub non riuscito. Esegui npx @microsoft/cpp-language-server --login", "auth_eula_required": "Per continuare, è necessario accettare il contratto di licenza con l'utente finale. Eseguire con --accept-eula.", + "auth_eula_required_plugin": "Per continuare, è necessario accettare il contratto di licenza con l'utente finale. Esegui npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Autenticazione con GitHub già eseguita. Usare --force-login per ripetere l'autenticazione.", "config_unsupported_version": "Inizializzazione non riuscita: versione di configurazione non supportata. È supportata solo la versione 1.", "config_file_not_found": "Inizializzazione non riuscita: file di configurazione '{0}' non trovato.", diff --git a/Extension/i18n/jpn/package.i18n.json b/Extension/i18n/jpn/package.i18n.json index 991cc75fb..de9119374 100644 --- a/Extension/i18n/jpn/package.i18n.json +++ b/Extension/i18n/jpn/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "シンボル (.pdb ファイル) の検索と読み込みの方法を制御するオプションです。", "c_cpp.debuggers.unknownBreakpointHandling.description": "ヒットしたときに外部で設定されたブレークポイント (通常は生の GDB コマンドを使用) を処理する方法を制御します。\n許容される値は、アプリケーションによって例外がスローされたかのように動作する \"throw\" と、デバッグ セッションを一時停止するだけの \"stop\" です。既定値は \"throw\" です。", "c_cpp.debuggers.debuginfod.description": "debuginfod サーバーからデバッグ シンボルをダウンロードする際の GDB の debuginfod の動作を制御します。", - "c_cpp.debuggers.debuginfod.enabled.description": "true (既定値) の場合、GDB の debuginfod サポートは有効です。GDB が debuginfod サーバーに接続できないようにするには、false に設定します。", + "c_cpp.debuggers.debuginfod.enabled.description": "false (既定値) の場合、GDB は debuginfod サーバーに接続しません。debuginfod のサポートを有効にするには、true に設定します。", "c_cpp.debuggers.debuginfod.timeout.description": "debuginfod サーバー要求のタイムアウト (秒)。既定値は 30 です。GDB/libdebuginfod の既定値 (オーバーライドなし) を使用する場合は 0 に設定します。", "c_cpp.debuggers.VSSymbolOptions.description": "デバッグ アダプターへのシンボルの検索と読み込みのための構成を提供します。", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": ".pdb ファイルを検索するためのシンボル サーバー URL (例: http​://MyExampleSymbolServer) の配列またはディレクトリ (例: /build/symbols) の配列です。これらのディレクトリは、既定の場所 (すなわちモジュールと、 pdb が最初にドロップされたパスの横) に加えて、検索されます。", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "デバッガーがシンボルを読み込んではいけないモジュールの配列です。ワイルドカード (例: MyCompany.*.dll) がサポートされています。\n\n'mode' が 'loadAllButExcluded' に設定されていない限り、このプロパティは無視されます。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "デバッガーがシンボルを読み込むべきモジュールの配列です。ワイルドカード (例: MyCompany.*.dll) がサポートされています。\n\n'mode' が 'loadOnlyIncluded' に設定されていない限り、このプロパティは無視されます。", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "True の場合、'includedModules' 配列にないモジュールの場合、デバッガーはモジュール自体と起動中の実行可能ファイルの横を確認しますが、シンボル検索リストのパスはチェックしません。このオプションの既定値は 'true' です。\n\n'mode' が 'loadOnlyIncluded' に設定されていない限り、このプロパティは無視されます。", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "\"true\" の場合、デバッグなしで実行してもターミナルでプログラムを起動できない場合、警告はログに記録されません。", "c_cpp.semanticTokenTypes.referenceType.description": "C++/CLI 参照型のスタイルです。", "c_cpp.semanticTokenTypes.cliProperty.description": "C++/CLI プロパティのスタイルです。", "c_cpp.semanticTokenTypes.genericType.description": "C++/CLI ジェネリック型のスタイルです。", diff --git a/Extension/i18n/jpn/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/jpn/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 20002ae62..f6064b0f0 100644 --- a/Extension/i18n/jpn/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/jpn/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "デバッガーのタイプ '{0}' は、Windows 以外のコンピューターでは使用できません。", "debugger.noDebug.requestType.not.supported": "デバッグなしで実行は、起動構成でのみサポートされています。", - "debugger.noDebug.pipeTransport.not.supported": "'pipeTransport' が設定された構成では、デバッグなしで実行はサポートされていません。", - "debugger.noDebug.debugServerPath.not.supported": "'debugServerPath' が設定された構成では、デバッグなしで実行はサポートされていません。", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "'miDebuggerServerAddress' が設定された構成では、デバッグなしで実行はサポートされていません。", - "debugger.noDebug.coreDumpPath.not.supported": "'coreDumpPath' が設定された構成では、デバッグなしで実行はサポートされていません。" + "debugger.unsupported.properties": "次のプロパティを持つ起動構成をターミナルで直接実行することはできません: {0}", + "debugger.fallback.message": "代わりに、プログラムの出力がデバッグ コンソールに表示されます。", + "debugger.fallback.message2": "この警告を抑制するには、起動構成で \"ignoreRunWithoutDebuggingWarnings\" プロパティを \"true\" に設定します。" } \ No newline at end of file diff --git a/Extension/i18n/jpn/src/LanguageServer/extension.i18n.json b/Extension/i18n/jpn/src/LanguageServer/extension.i18n.json index 7eacea0df..c7a6b8095 100644 --- a/Extension/i18n/jpn/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/jpn/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "このヘッダーのライブラリを vcpkg でインストールする方法の詳細", "copy.vcpkg.command": "'{0}' をインストールするための vcpkg コマンドをクリップボードにコピーする", "on.disabled.command": "`C_Cpp.intelliSenseEngine` が `disabled` に設定されている場合、IntelliSense 関連のコマンドは実行できません。", + "switch.header.source": "ヘッダー/ソースを切り替えています...", "client.not.found": "クライアントが見つかりませんでした", "ok": "OK", "install.compiler.mac.title": "clang コンパイラがインストールされます", diff --git a/Extension/i18n/jpn/src/nativeStrings.i18n.json b/Extension/i18n/jpn/src/nativeStrings.i18n.json index a4492c59a..cb28423c2 100644 --- a/Extension/i18n/jpn/src/nativeStrings.i18n.json +++ b/Extension/i18n/jpn/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "ユーザーによって承認が拒否されました。", "auth_unexpected_error": "ポーリング中に予期しないエラーが発生しました: {0}", "auth_login_failed": "GitHub ログインに失敗しました。ログインするには、コマンド ラインから --login を使用して実行してみてください。", + "auth_login_failed_plugin": "GitHub ログインに失敗しました。npx @microsoft/cpp-language-server --login を実行する", "auth_eula_required": "続行するには、EULA に同意する必要があります。--accept-eula を使用して実行します。", + "auth_eula_required_plugin": "続行するには、EULA に同意する必要があります。npx @microsoft/cpp-language-server --accept-eula を実行する", "auth_already_authenticated": "GitHub で既に認証されています。--force-login を使用して再認証してください。", "config_unsupported_version": "初期化に失敗しました: サポートされていない構成バージョンです。バージョン 1 のみサポートされています。", "config_file_not_found": "初期化に失敗しました: 構成ファイル '{0}' が見つかりません。", diff --git a/Extension/i18n/kor/package.i18n.json b/Extension/i18n/kor/package.i18n.json index c9edc3bf4..c1cdbeec1 100644 --- a/Extension/i18n/kor/package.i18n.json +++ b/Extension/i18n/kor/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "기호(.pdb 파일)를 찾아서 로드하는 방법을 제어하는 옵션입니다.", "c_cpp.debuggers.unknownBreakpointHandling.description": "적중 시 외부에서 설정되는 중단점이(일반적으로 원시 GDB 명령을 통해) 처리되는 방식을 제어합니다.\n허용 값은 애플리케이션에서 예외가 발생한 것처럼 동작하는 \"throw\"와 디버그 세션만 일시 중지하는 \"stop\"입니다. 기본값은 \"throw\"입니다.", "c_cpp.debuggers.debuginfod.description": "debuginfod 서버에서 디버그 기호를 다운로드할 때 GDB의 debuginfod 동작을 제어합니다.", - "c_cpp.debuggers.debuginfod.enabled.description": "true(기본값)이면 GDB의 debuginfod 지원이 활성화됩니다. GDB가 debuginfod 서버에 연결하지 않게 하려면 false로 설정하세요.", + "c_cpp.debuggers.debuginfod.enabled.description": "false(기본값)인 경우 GDB는 debuginfod 서버에 연결하지 않습니다. debuginfod 지원을 활성화하려면 true로 설정합니다.", "c_cpp.debuggers.debuginfod.timeout.description": "debuginfod 서버 요청에 대한 시간 제한(초)입니다. 기본값은 30입니다. GDB/libdebuginfod 기본값(재정의하지 않음)을 사용하려면 0으로 설정하세요.", "c_cpp.debuggers.VSSymbolOptions.description": "디버그 어댑터에 기호를 찾고 로드하기 위한 구성을 제공합니다.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": ".pdb 파일을 검색하는 기호 서버 URL(예: http​://MyExampleSymbolServer) 또는 디렉터리(예: /build/symbols)의 배열입니다. 이러한 디렉터리가 모듈 및 pdb가 원래 삭제된 경로 옆에 있는 기본 위치 외에 검색됩니다.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "디버거에서 기호를 로드하지 않아야 하는 모듈의 배열입니다. 와일드카드(예: MyCompany.*.dll)가 지원됩니다.\n\n'모드'가 'loadAllButExcluded'로 설정되어 있지 않으면 이 속성은 무시됩니다.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "디버거에서 기호를 로드해야 하는 모듈의 배열입니다. 와일드카드(예: MyCompany.*.dll)가 지원됩니다.\n\n'모드'가 'loadOnlyIncluded'로 설정되어 있지 않으면 이 속성은 무시됩니다.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "True 이면 'includedModules' 배열에 없는 모듈에 대해 디버거는 모듈 자체 및 시작 실행 파일 옆을 계속 확인하지만 기호 검색 목록의 경로는 확인하지 않습니다. 이 옵션의 기본값은 'true'입니다.\n\n'모드'가 'loadOnlyIncluded'로 설정되어 있지 않으면 이 속성은 무시됩니다.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "값이 true이면 디버깅하지 않고 실행할 때 터미널에서 프로그램을 시작하지 못해도 경고가 기록되지 않습니다.", "c_cpp.semanticTokenTypes.referenceType.description": "C++/CLI 참조 형식의 스타일입니다.", "c_cpp.semanticTokenTypes.cliProperty.description": "C++/CLI 속성의 스타일입니다.", "c_cpp.semanticTokenTypes.genericType.description": "C++/CLI 제네릭 형식의 스타일입니다.", diff --git a/Extension/i18n/kor/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/kor/src/Debugger/debugAdapterDescriptorFactory.i18n.json index d73248987..dbc35b1b3 100644 --- a/Extension/i18n/kor/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/kor/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Windows가 아닌 머신에서는 '{0}' 디버거 형식을 사용할 수 없습니다.", "debugger.noDebug.requestType.not.supported": "디버깅하지 않고 실행은 시작 구성에만 지원됩니다.", - "debugger.noDebug.pipeTransport.not.supported": "'pipeTransport'가 설정된 구성에는 디버깅 없이 실행이 지원되지 않습니다.", - "debugger.noDebug.debugServerPath.not.supported": "'debugServerPath'가 설정된 구성에는 디버깅 없이 실행이 지원되지 않습니다.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "'miDebuggerServerAddress'가 설정된 구성에는 디버깅 없이 실행이 지원되지 않습니다.", - "debugger.noDebug.coreDumpPath.not.supported": "'coreDumpPath'가 설정된 구성에는 디버깅 없이 실행이 지원되지 않습니다." + "debugger.unsupported.properties": "다음 속성이 있는 시작 구성은 터미널에서 직접 실행할 수 없습니다. {0}", + "debugger.fallback.message": "프로그램 출력이 대신 디버그 콘솔 표시됩니다.", + "debugger.fallback.message2": "이 경고를 표시하지 않으려면 시작 구성에서 'ignoreRunWithoutDebuggingWarnings' 속성을 true로 설정하세요." } \ No newline at end of file diff --git a/Extension/i18n/kor/src/LanguageServer/extension.i18n.json b/Extension/i18n/kor/src/LanguageServer/extension.i18n.json index d7dfb9d83..73c82a1d1 100644 --- a/Extension/i18n/kor/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/kor/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "vcpkg를 사용하여 이 헤더의 라이브러리를 설치하는 방법 알아보기", "copy.vcpkg.command": "'{0}'을(를) 설치할 vcpkg 명령을 클립보드에 복사", "on.disabled.command": "IntelliSense 관련 명령은 `C_Cpp.intelliSenseEngine`이 `disabled`로 설정된 경우 실행할 수 없습니다.", + "switch.header.source": "헤더/원본을 전환하는 중...", "client.not.found": "클라이언트를 찾을 수 없음", "ok": "확인", "install.compiler.mac.title": "이제 Clang 컴파일러가 설치됩니다.", diff --git a/Extension/i18n/kor/src/nativeStrings.i18n.json b/Extension/i18n/kor/src/nativeStrings.i18n.json index 6c9f950d3..b846a98cd 100644 --- a/Extension/i18n/kor/src/nativeStrings.i18n.json +++ b/Extension/i18n/kor/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "사용자가 권한 부여를 거부했습니다.", "auth_unexpected_error": "폴링하는 동안 예기치 않은 오류가 발생함: {0}", "auth_login_failed": "GitHub 로그인에 실패했습니다. 명령줄에서 --login으로 실행하여 로그인해 보세요.", + "auth_login_failed_plugin": "GitHub 로그인에 실패했습니다. npx @microsoft/cpp-language-server --login 실행", "auth_eula_required": "계속하려면 EULA에 동의해야 합니다. --accept-eula를 사용하여 실행합니다.", + "auth_eula_required_plugin": "계속하려면 EULA에 동의해야 합니다. npx @microsoft/cpp-language-server --accept-eula 실행", "auth_already_authenticated": "이미 GitHub로 인증되었습니다. --force-login을 사용하여 다시 인증합니다.", "config_unsupported_version": "초기화 실패: 지원되지 않는 구성 버전입니다. 버전 1만 지원됩니다.", "config_file_not_found": "초기화 실패: 구성 파일 '{0}'을(를) 찾을 수 없습니다.", diff --git a/Extension/i18n/plk/package.i18n.json b/Extension/i18n/plk/package.i18n.json index 1a389ce31..05a143a3e 100644 --- a/Extension/i18n/plk/package.i18n.json +++ b/Extension/i18n/plk/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Opcje umożliwiające kontrolowanie sposobu znajdowania i ładowania symboli (plików PDB).", "c_cpp.debuggers.unknownBreakpointHandling.description": "Steruje sposobem obsługi punktów przerwania ustawianych zewnętrznie (zwykle za pośrednictwem nieprzetworzonych poleceń GDB) po trafieniu.\nDozwolone wartości to „throw”, które działają tak, jakby aplikacja zgłosiła wyjątek, i „stop”, co tylko wstrzymuje sesję debugowania. Wartość domyślna to „throw”.", "c_cpp.debuggers.debuginfod.description": "Steruje zachowaniem debuginfod bazy danych GDB na potrzeby pobierania symboli debugowania z serwerów debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Jeśli wartość to true (wartość domyślna), obsługa żądań debuginfod bazy danych GDB jest włączona. Ustaw wartość false, aby uniemożliwić bazie danych GDB kontaktowanie się z serwerami debuginfod.", + "c_cpp.debuggers.debuginfod.enabled.description": "Jeśli wartość to false (wartość domyślna), narzędzie GDB nie będzie kontaktować się z serwerami debuginfod. Ustaw wartość true, aby włączyć obsługę debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "Limit czasu w sekundach dla żądań debuginfod serwera. Wartość domyślna to 30. Ustaw wartość 0, aby używać domyślnych ustawień GDB/libdebuginfod (bez przesłonięcia).", "c_cpp.debuggers.VSSymbolOptions.description": "Zapewnia konfigurację umożliwiającą lokalizowanie i ładowanie symboli do adaptera debugowania.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Tablica adresów URL serwera symboli (przykład: http:​//MyExampleSymbolServer) lub katalogów (przykład:/build/Symbols) w celu wyszukania plików PDB. Te katalogi zostaną wyszukane jako uzupełnienie lokalizacji domyślnych — obok modułu i ścieżki, do której plik PDB został pierwotnie porzucony.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Tablica modułów, dla których debuger NIE powinien ładować symboli. Symbole wieloznaczne (przykład: MojaFirma.*.dll) są obsługiwane.\n\nTa właściwość jest ignorowana, chyba że właściwość „mode” jest ustawiona na wartość „loadAllButExcluded”.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Tablica modułów, dla których debuger powinien ładować symbole. Symbole wieloznaczne (przykład: MojaFirma.*.dll) są obsługiwane.\n\nTa właściwość jest ignorowana, chyba że właściwość „mode” jest ustawiona na wartość „loadOnlyIncluded”.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Jeśli ma wartość true, w przypadku każdego modułu NIE BĘDĄCEGO w tablicy „includedModules” debuger będzie nadal sprawdzał obok modułu i uruchamianego pliku wykonywalnego, ale nie będzie sprawdzał ścieżek na liście wyszukiwania symboli. Ta opcja ma wartość domyślną „true”.\n\nTa właściwość jest ignorowana, chyba że właściwość „mode” jest ustawiona na wartość „loadOnlyIncluded”.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "W przypadku wartości true żadne ostrzeżenie nie zostanie zarejestrowane, gdy uruchomienie bez debugowania nie powiedzie się, aby uruchomić program w terminalu.", "c_cpp.semanticTokenTypes.referenceType.description": "Styl dla typów referencyjnych języka C++/interfejsu wiersza polecenia.", "c_cpp.semanticTokenTypes.cliProperty.description": "Styl dla właściwości języka C++/interfejsu wiersza polecenia.", "c_cpp.semanticTokenTypes.genericType.description": "Styl dla typów ogólnych języka C++/interfejsu wiersza polecenia.", diff --git a/Extension/i18n/plk/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/plk/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 670edd14b..545c39dfc 100644 --- a/Extension/i18n/plk/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/plk/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Typ debugera „{0}” nie jest dostępny dla maszyn z systemem innym niż Windows.", "debugger.noDebug.requestType.not.supported": "Uruchamianie bez debugowania jest obsługiwane tylko dla konfiguracji uruchamiania.", - "debugger.noDebug.pipeTransport.not.supported": "Uruchamianie bez debugowania nie jest obsługiwane dla konfiguracji z ustawionym parametrem „pipeTransport”.", - "debugger.noDebug.debugServerPath.not.supported": "Uruchamianie bez debugowania nie jest obsługiwane dla konfiguracji z ustawionym parametrem „debugServerPath”.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Uruchamianie bez debugowania nie jest obsługiwane dla konfiguracji z ustawionym parametrem „miDebuggerServerAddress”.", - "debugger.noDebug.coreDumpPath.not.supported": "Uruchamianie bez debugowania nie jest obsługiwane dla konfiguracji z ustawionym parametrem „coreDumpPath”." + "debugger.unsupported.properties": "Nie można uruchomić konfiguracji uruchamiania z następującymi właściwościami bezpośrednio w terminalu: {0}", + "debugger.fallback.message": "Zamiast tego dane wyjściowe programu będą wyświetlane w konsoli debugowania.", + "debugger.fallback.message2": "Aby pominąć to ostrzeżenie, ustaw właściwość „ignoreRunWithoutDebuggingWarnings” na wartość true w konfiguracji uruchamiania." } \ No newline at end of file diff --git a/Extension/i18n/plk/src/LanguageServer/extension.i18n.json b/Extension/i18n/plk/src/LanguageServer/extension.i18n.json index b434aa693..ad0c69a30 100644 --- a/Extension/i18n/plk/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/plk/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Dowiedz się, jak zainstalować bibliotekę dla tego nagłówka przy użyciu menedżera vcpkg", "copy.vcpkg.command": "Skopiuj polecenie vcpkg, aby zainstalować element „{0}” w schowku", "on.disabled.command": "Nie można wykonywać poleceń związanych z funkcją IntelliSense, gdy właściwość `C_Cpp.intelliSenseEngine` ma wartość `disabled`.", + "switch.header.source": "Trwa przełączanie nagłówka/źródła...", "client.not.found": "nie znaleziono klienta", "ok": "OK", "install.compiler.mac.title": "Kompilator clang zostanie teraz zainstalowany", diff --git a/Extension/i18n/plk/src/nativeStrings.i18n.json b/Extension/i18n/plk/src/nativeStrings.i18n.json index e2b920e83..d4e5f556e 100644 --- a/Extension/i18n/plk/src/nativeStrings.i18n.json +++ b/Extension/i18n/plk/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Użytkownik odmówił autoryzacji.", "auth_unexpected_error": "Nieoczekiwany błąd podczas sondowania: {0}", "auth_login_failed": "Logowanie do GitHub nie powiodło się. Spróbuj uruchomić polecenie --login z wiersza polecenia, aby się zalogować.", + "auth_login_failed_plugin": "Logowanie do usługi GitHub nie powiodło się. Uruchom polecenie npx @microsoft/cpp-language-server --login", "auth_eula_required": "Aby kontynuować, należy zaakceptować umowę EULA. Uruchom z parametrem --accept-eula.", + "auth_eula_required_plugin": "Aby kontynuować, należy zaakceptować umowę EULA. Uruchom polecenie npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Uwierzytelniono już za pomocą usługi GitHub. Użyj polecenia --force-login, aby przeprowadzić ponowne uwierzytelnienie.", "config_unsupported_version": "Inicjowanie nie powiodło się: nieobsługiwana wersja konfiguracji. Obsługiwana jest tylko wersja 1.", "config_file_not_found": "Inicjowanie nie powiodło się: nie znaleziono pliku konfiguracji „{0}”.", diff --git a/Extension/i18n/ptb/package.i18n.json b/Extension/i18n/ptb/package.i18n.json index ac53a14d5..09563b7c6 100644 --- a/Extension/i18n/ptb/package.i18n.json +++ b/Extension/i18n/ptb/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Opções para controlar como os símbolos (arquivos .pdb) são encontrados e carregados.", "c_cpp.debuggers.unknownBreakpointHandling.description": "Controla como os pontos de interrupção definidos externamente (geralmente por meio de comandos GDB brutos) são tratados quando atingidos.\nOs valores permitidos são \"throw\", que age como se uma exceção fosse lançada pelo aplicativo, e \"stop\", que apenas pausa a sessão de depuração. O valor padrão é \"throw\".", "c_cpp.debuggers.debuginfod.description": "Controla o comportamento do debuginfod do GDB ao baixar símbolos de depuração dos servidores debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Se true (padrão), o suporte de debuginfod do GDB está habilitado. Defina como false para impedir que o GDB entre em contato com servidores depurados.", + "c_cpp.debuggers.debuginfod.enabled.description": "Se false (padrão), o GDB não entrará em contato com servidores debuginfod. Defina como true para habilitar o suporte a debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "O tempo limite em segundos para solicitações de servidor debuginfod. O padrão é 30. Defina como 0 para usar os padrões GDB/libdebuginfod (sem substituição).", "c_cpp.debuggers.VSSymbolOptions.description": "Fornece configuração para localizar e carregar símbolos no adaptador de depuração.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Matriz de URLs do servidor de símbolos (exemplo: http​://MyExampleSymbolServer) ou diretórios (exemplo: /build/symbols) para pesquisar arquivos .pdb. Esses diretórios serão pesquisados além dos locais padrão, ao lado do módulo e do caminho em que o pdb foi removido originalmente.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Matriz de módulos para a qual o depurador NÃO deve carregar símbolos. Há suporte para curingas (exemplo: MyCompany.*.dll).\n\nEssa propriedade será ignorada, a menos que 'mode' esteja definido como 'loadAllButExcluded'.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Matriz de módulos para a qual o depurador deve carregar símbolos. Há suporte para curingas (exemplo: MyCompany.*.dll).\n\nessa propriedade será ignorada, a menos que 'mode' esteja definido como 'loadOnlyIncluded'.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Se for verdadeira, para qualquer módulo NOT na matriz 'includedModules', o depurador ainda verificará ao lado do próprio módulo e do executável de inicialização, mas não verificará os caminhos na lista de pesquisa de símbolo. Esta opção é padronizada como 'true'.\n\nessa propriedade será ignorada, a menos que 'mode' esteja definido como 'loadOnlyIncluded'.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "If true, no warning will be logged when run without debugging fails to launch the program in the terminal.", "c_cpp.semanticTokenTypes.referenceType.description": "Estilo para tipos de referência C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Estilo para propriedades C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Estilo para tipos genéricos C++/CLI.", diff --git a/Extension/i18n/ptb/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/ptb/src/Debugger/debugAdapterDescriptorFactory.i18n.json index dab24487f..774223192 100644 --- a/Extension/i18n/ptb/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/ptb/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "O tipo de depurador '{0}' não está disponível para máquinas que não sejam Windows.", "debugger.noDebug.requestType.not.supported": "A execução sem depuração só tem suporte para configurações de inicialização.", - "debugger.noDebug.pipeTransport.not.supported": "Não há suporte para Executar Sem Depuração para configurações com \"pipeTransport\" definido.", - "debugger.noDebug.debugServerPath.not.supported": "Não há suporte para Executar sem Depuração em configurações com \"debugServerPath\" definido.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Não há suporte para Executar sem Depuração para configurações com \"miDebuggerServerAddress\" definido.", - "debugger.noDebug.coreDumpPath.not.supported": "Não há suporte para Executar sem Depuração para configurações com o conjunto \"coreDumpPath\"." + "debugger.unsupported.properties": "As configurações de inicialização com as seguintes propriedades não podem ser executadas diretamente no terminal: {0}", + "debugger.fallback.message": "Em vez disso, a saída do programa será exibida no Console de Depuração.", + "debugger.fallback.message2": "Para suprimir esse aviso, defina a propriedade 'ignoreRunWithoutDebuggingWarnings' como verdadeira na configuração de inicialização." } \ No newline at end of file diff --git a/Extension/i18n/ptb/src/LanguageServer/extension.i18n.json b/Extension/i18n/ptb/src/LanguageServer/extension.i18n.json index 596850296..af6df3cf4 100644 --- a/Extension/i18n/ptb/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/ptb/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Saiba como instalar uma biblioteca para este cabeçalho com vcpkg", "copy.vcpkg.command": "Copiar o comando vcpkg para instalar '{0}' para a área de transferência", "on.disabled.command": "Comandos relacionados ao IntelliSense não podem ser executados quando `C_Cpp.intelliSenseEngine` está definido como `disabled`.", + "switch.header.source": "Alternando cabeçalho/origem...", "client.not.found": "o cliente não foi encontrado", "ok": "OK", "install.compiler.mac.title": "O compilador clang agora será instalado", diff --git a/Extension/i18n/ptb/src/nativeStrings.i18n.json b/Extension/i18n/ptb/src/nativeStrings.i18n.json index 06cfe131b..93232ecbd 100644 --- a/Extension/i18n/ptb/src/nativeStrings.i18n.json +++ b/Extension/i18n/ptb/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "A autorização foi negada pelo usuário.", "auth_unexpected_error": "Erro inesperado durante a sondagem: {0}", "auth_login_failed": "Falha no logon do GitHub. Tente executar com --login na linha de comando para fazer logon.", + "auth_login_failed_plugin": "Falha no logon do GitHub. Executar npx @microsoft/cpp-language-server --login", "auth_eula_required": "O EULA deve ser aceito para continuar. Execute com --accept-eula.", + "auth_eula_required_plugin": "O EULA deve ser aceito para continuar. Executar npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Já autenticado com o GitHub. Use --force-login para autenticar novamente.", "config_unsupported_version": "Falha na inicialização: versão de configuração sem suporte. Há suporte apenas para a versão 1.", "config_file_not_found": "Falha na inicialização: arquivo de configuração ''{0}'' não encontrado.", diff --git a/Extension/i18n/rus/package.i18n.json b/Extension/i18n/rus/package.i18n.json index e4c8dd257..63d29bb0f 100644 --- a/Extension/i18n/rus/package.i18n.json +++ b/Extension/i18n/rus/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Параметры, управляющие поиском и загрузкой символов (PDB-файлов).", "c_cpp.debuggers.unknownBreakpointHandling.description": "Управляет тем, как точки останова, установленные извне (обычно через необработанные команды GDB), обрабатываются при попадании.\nДопустимые значения: \"throw\", который действует так, как если бы приложение выдало исключение, и \"stop\", который только приостанавливает сеанс отладки. Значение по умолчанию — \"throw\".", "c_cpp.debuggers.debuginfod.description": "Управляет поведением debuginfod в GDB при скачивании символов отладки с серверов debuginfod.", - "c_cpp.debuggers.debuginfod.enabled.description": "Если задано значение true (по умолчанию), поддержка debuginfod в GDB включена. Задайте значение false, чтобы запретить GDB обращение к серверам debuginfod.", + "c_cpp.debuggers.debuginfod.enabled.description": "Если задано значение false (по умолчанию), GDB не будет обращаться к серверам debuginfod. Задайте значение true, чтобы включить поддержку debuginfod.", "c_cpp.debuggers.debuginfod.timeout.description": "Время ожидания запросов к серверу debuginfod в секундах. Значение по умолчанию: 30. Чтобы использовать значения по умолчанию GDB/libdebuginfod (без переопределения), задайте 0.", "c_cpp.debuggers.VSSymbolOptions.description": "Предоставляет конфигурацию для поиска и загрузки символов в адаптер отладки.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": "Массив URL-адресов сервера символов (например, http​://MyExampleSymbolServer) или каталогов (например: /build/symbols) для поиска PDB-файлов. Поиск в этих каталогах осуществляется в дополнение к расположениям по умолчанию — рядом с модулем и путем первоначального удаления PDB-файла.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Массив модулей, для которых отладчик не должен загружать символы. Поддерживаются подстановочные знаки (например: MyCompany.*.dll)\n\nЭто свойство игнорируется, если для \"mode\" задано значение \"loadAllButExcluded\".", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Массив модулей, для которых отладчик должен загружать символы. Поддерживаются подстановочные знаки (например: MyCompany.*.dll)\n\nЭто свойство игнорируется, если для \"mode\" задано значение \"loadOnlyIncluded\".", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "Если значение равно true, для любого модуля, НЕ входящего в массив \"includedModules\", отладчик по-прежнему будет проверять рядом с самим модулем и запускаемым исполняемым файлом, но он не будет проверять пути в списке поиска символов. По умолчанию для этого параметра установлено значение \"true\".\n\nЭто свойство игнорируется, если для параметра \"mode\" установлено значение \"loadOnlyIncluded\".", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "Если значение равно true, предупреждение не будет записано в журнал, если при запуске без отладки не удастся запустить программу в терминале.", "c_cpp.semanticTokenTypes.referenceType.description": "Стиль для ссылочных типов C++/CLI.", "c_cpp.semanticTokenTypes.cliProperty.description": "Стиль для свойств C++/CLI.", "c_cpp.semanticTokenTypes.genericType.description": "Стиль для универсальных типов C++/CLI.", diff --git a/Extension/i18n/rus/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/rus/src/Debugger/debugAdapterDescriptorFactory.i18n.json index 3cd62d94b..d9a0ee2d8 100644 --- a/Extension/i18n/rus/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/rus/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "Тип отладчика \"{0}\" недоступен для компьютеров с операционной системой, отличной от Windows.", "debugger.noDebug.requestType.not.supported": "Запуск без отладки поддерживается только для конфигураций запуска.", - "debugger.noDebug.pipeTransport.not.supported": "Запуск без отладки не поддерживается для конфигураций с настроенным параметром \"pipeTransport\".", - "debugger.noDebug.debugServerPath.not.supported": "Запуск без отладки не поддерживается для конфигураций с настроенным параметром \"debugServerPath\".", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Запуск без отладки не поддерживается для конфигураций с настроенным параметром \"miDebuggerServerAddress\".", - "debugger.noDebug.coreDumpPath.not.supported": "Запуск без отладки не поддерживается для конфигураций с настроенным параметром \"coreDumpPath\"." + "debugger.unsupported.properties": "Конфигурации запуска со следующими свойствами нельзя запускать напрямую в терминале: {0}", + "debugger.fallback.message": "Выходные данные программы будут отображаться на консоли отладки.", + "debugger.fallback.message2": "Чтобы скрыть это предупреждение, задайте для свойства ignoreRunWithoutDebuggingWarnings значение true в конфигурации запуска." } \ No newline at end of file diff --git a/Extension/i18n/rus/src/LanguageServer/extension.i18n.json b/Extension/i18n/rus/src/LanguageServer/extension.i18n.json index 8e8494534..29d8d8cc6 100644 --- a/Extension/i18n/rus/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/rus/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "Сведения об установке библиотеки для этого заголовка с помощью vcpkg", "copy.vcpkg.command": "Копировать команду vcpkg для установки \"{0}\" в буфер обмена", "on.disabled.command": "Команды, связанные с IntelliSense, не могут быть выполнены, если для `C_Cpp.intelliSenseEngine` установлено значение `disabled`.", + "switch.header.source": "Переключение заголовка/источника...", "client.not.found": "Клиент не найден.", "ok": "ОК", "install.compiler.mac.title": "Будет установлен компилятор clang", diff --git a/Extension/i18n/rus/src/nativeStrings.i18n.json b/Extension/i18n/rus/src/nativeStrings.i18n.json index 8e1912085..c2c8eb39a 100644 --- a/Extension/i18n/rus/src/nativeStrings.i18n.json +++ b/Extension/i18n/rus/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Пользователь отклонил авторизацию.", "auth_unexpected_error": "Непредвиденная ошибка во время опроса: {0}", "auth_login_failed": "Не удалось войти в GitHub. Попробуйте использовать --login из командной строки, чтобы войти в систему.", + "auth_login_failed_plugin": "Не удалось войти в GitHub. Запустите npx @microsoft/cpp-language-server --login", "auth_eula_required": "Чтобы продолжить, примите условия лицензионного соглашения с конечным пользователем. Это можно сделать с помощью --accept-eula.", + "auth_eula_required_plugin": "Для продолжения необходимо принять EULA. Запустите npx @microsoft/cpp-language-server --accept-eula", "auth_already_authenticated": "Аутентификация в GitHub уже выполнена. Используйте --force-login для повторной аутентификации.", "config_unsupported_version": "Сбой инициализации: неподдерживаемая версия конфигурации. Поддерживается только версия 1.", "config_file_not_found": "Сбой инициализации: файл конфигурации \"{0}\" не найден.", diff --git a/Extension/i18n/trk/package.i18n.json b/Extension/i18n/trk/package.i18n.json index c27d22f81..302e370ef 100644 --- a/Extension/i18n/trk/package.i18n.json +++ b/Extension/i18n/trk/package.i18n.json @@ -392,7 +392,7 @@ "c_cpp.debuggers.symbolOptions.description": "Simgelerin (.pdb dosyaları) nasıl bulunup yüklendiğini denetleme seçenekleri.", "c_cpp.debuggers.unknownBreakpointHandling.description": "İsabet ettiğinde harici olarak (genellikle ham GDB komutları aracılığıyla) ayarlanan kesme noktalarının nasıl işlendiğini kontrol eder.\nİzin verilen değerler, uygulama tarafından bir istisna oluşturulmuş gibi davranan \"throw\" ve yalnızca hata ayıklama oturumunu duraklatan \"stop\" değerleridir. Varsayılan değer \"throw\"dur.", "c_cpp.debuggers.debuginfod.description": "debuginfod sunucularından hata ayıklama sembollerini indirmek için GDB'nin debuginfod davranışını denetler.", - "c_cpp.debuggers.debuginfod.enabled.description": "True ise (varsayılan), GDB’nin debuginfod desteği etkindir. GDB'nin debuginfod sunucularıyla iletişim kurmasını önlemek için false olarak ayarlayın.", + "c_cpp.debuggers.debuginfod.enabled.description": "false ise (varsayılan), GDB debuginfod sunucularıyla iletişim kurmaz. debuginfod desteğini etkinleştirmek için true olarak ayarlayın.", "c_cpp.debuggers.debuginfod.timeout.description": "debuginfod sunucu istekleri için saniye cinsinden zaman aşımı. Varsayılan değer 30'dur. GDB/libdebuginfod varsayılanlarını kullanmak için 0 değerine ayarlayın (geçersiz kılma yok).", "c_cpp.debuggers.VSSymbolOptions.description": "Sembolleri bulup hata ayıklama bağdaştırıcısına yüklemeye yönelik yapılandırma sağlar.", "c_cpp.debuggers.VSSymbolOptions.searchPaths.description": ".pdb dosyalarını aramak için sembol sunucusu URL’si (ör: http​://MyExampleSymbolServer) veya dizin (ör. /build/symbols) dizisi. Bu dizinler, modülün yanındaki varsayılan konumların yanı sıra, pdb'nin bırakıldığı yolda arama yapar.", @@ -406,6 +406,7 @@ "c_cpp.debuggers.VSSymbolOptionsModuleFilter.excludedModules.description": "Hata ayıklayıcısının, sembolleri YÜKLEMEMESİ gereken modül dizisi. Joker karakterler (ör. MyCompany.*.dll) desteklenir.\n\n'Mode' değeri 'loadAllButExcluded' olarak ayarlanmadıkça bu özellik yoksayılır.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includedModules.description": "Hata ayıklayıcısının, sembolleri yüklemesi gereken modül dizisi. Joker karakterler (ör. MyCompany.*.dll) desteklenir.\n\n'Mode' değeri 'loadOnlyIncluded' olarak ayarlanmadıkça bu özellik yoksayılır.", "c_cpp.debuggers.VSSymbolOptionsModuleFilter.includeSymbolsNextToModules.description": "True ise hata ayıklayıcısı, 'includedModules' dizisinde OLMAYAN herhangi bir modül için modülün ve başlatılan yürütülebilir dosyanın yanında denetlemeye devam eder ancak sembol arama listesindeki yolları denetlemez.\n\nBu seçenek varsayılan olarak 'true' şeklinde ayarlanır. 'Mode', 'loadOnlyIncluded' olarak ayarlanmadıkça bu özellik yoksayılır.", + "c_cpp.debuggers.ignoreRunWithoutDebuggingWarnings.description": "true ise hata ayıklama olmadan çalıştırma terminalde programı başlatamadığında günlüğe hiçbir uyarı kaydedilmez.", "c_cpp.semanticTokenTypes.referenceType.description": "C++/CLI başvuru türleri için kullanılacak stil.", "c_cpp.semanticTokenTypes.cliProperty.description": "C++/CLI özellikleri için kullanılacak stil.", "c_cpp.semanticTokenTypes.genericType.description": "C++/CLI genel türleri için kullanılacak stil.", diff --git a/Extension/i18n/trk/src/Debugger/debugAdapterDescriptorFactory.i18n.json b/Extension/i18n/trk/src/Debugger/debugAdapterDescriptorFactory.i18n.json index b9c6616f9..be872db10 100644 --- a/Extension/i18n/trk/src/Debugger/debugAdapterDescriptorFactory.i18n.json +++ b/Extension/i18n/trk/src/Debugger/debugAdapterDescriptorFactory.i18n.json @@ -6,8 +6,7 @@ { "debugger.not.available": "'{0}' hata ayıklayıcısı türü, Windows dışı makinelerde kullanılamaz.", "debugger.noDebug.requestType.not.supported": "Hata Ayıklama Olmadan Çalıştırma yalnızca başlatma yapılandırmaları için destekleniyor.", - "debugger.noDebug.pipeTransport.not.supported": "Hata Ayıklama Olmadan Çalıştırma, 'pipeTransport' ayarlı yapılandırmalar için desteklenmiyor.", - "debugger.noDebug.debugServerPath.not.supported": "Hata Ayıklama Olmadan Çalıştırma, 'debugServerPath' ayarlı yapılandırmalar için desteklenmiyor.", - "debugger.noDebug.miDebuggerServerAddress.not.supported": "Hata Ayıklama Olmadan Çalıştırma, 'miDebuggerServerAddress' ayarlı yapılandırmalar için desteklenmiyor.", - "debugger.noDebug.coreDumpPath.not.supported": "Hata Ayıklama Olmadan Çalıştırma, 'coreDumpPath' ayarlı yapılandırmalar için desteklenmiyor." + "debugger.unsupported.properties": "Aşağıdaki özelliklere sahip başlatma yapılandırmaları doğrudan terminalde çalıştırılamaz: {0}", + "debugger.fallback.message": "Program çıktısı bunun yerine Hata Ayıklama Konsolu'nda görünecek.", + "debugger.fallback.message2": "Bu uyarıyı gizlemek için başlatma yapılandırmanızda 'ignoreRunWithoutDebuggingWarnings' özelliğini true olarak ayarlayın." } \ No newline at end of file diff --git a/Extension/i18n/trk/src/LanguageServer/extension.i18n.json b/Extension/i18n/trk/src/LanguageServer/extension.i18n.json index 1456a43e4..404ce5d60 100644 --- a/Extension/i18n/trk/src/LanguageServer/extension.i18n.json +++ b/Extension/i18n/trk/src/LanguageServer/extension.i18n.json @@ -7,6 +7,7 @@ "learn.how.to.install.a.library": "vcpkg ile bu üst bilgi için bir kitaplık yüklemeyi öğrenin", "copy.vcpkg.command": "'{0}' yükleme vcpkg komutunu panoya kopyalayın", "on.disabled.command": "`C_Cpp.intelliSenseEngine` `disabled` olarak ayarlandığında IntelliSense ile ilgili komutlar yürütülemez.", + "switch.header.source": "Başlık/Kaynak Değiştiriliyor...", "client.not.found": "istemci bulunamadı", "ok": "Tamam", "install.compiler.mac.title": "Clang derleyicisi şimdi kurulacak", diff --git a/Extension/i18n/trk/src/nativeStrings.i18n.json b/Extension/i18n/trk/src/nativeStrings.i18n.json index 768a2fc1f..d9fa544a1 100644 --- a/Extension/i18n/trk/src/nativeStrings.i18n.json +++ b/Extension/i18n/trk/src/nativeStrings.i18n.json @@ -346,7 +346,9 @@ "auth_denied": "Yetkilendirme kullanıcı tarafından reddedildi.", "auth_unexpected_error": "Yoklama sırasında beklenmeyen hata: {0}", "auth_login_failed": "GitHub oturum açma işlemi başarısız oldu. Oturum açmak için komut satırından --login ile çalıştırmayı deneyin.", + "auth_login_failed_plugin": "GitHub oturum açma işlemi başarısız oldu. npx @microsoft/cpp-language-server --login komutunu çalıştırın", "auth_eula_required": "Devam etmek için EULA'nın kabul edilmesi gerekiyor. --accept-eula ile çalıştırın.", + "auth_eula_required_plugin": "Devam etmek için EULA'nın kabul edilmesi gerekiyor. npx @microsoft/cpp-language-server --accept-eula komutunu çalıştırın", "auth_already_authenticated": "GitHub ile zaten kimlik doğrulaması yaptı. Yeniden kimlik doğrulaması yapmak için --force-login kullanın.", "config_unsupported_version": "Başlatma başarısız oldu: Desteklenmeyen yapılandırma sürümü. Yalnızca 1. sürüm desteklenir.", "config_file_not_found": "Başlatma başarısız oldu: '{0}' yapılandırma dosyası bulunamadı.", From 300d65a9d537e59a379460646ebfcb6756c5d5d0 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 1 Jul 2026 18:22:03 -0700 Subject: [PATCH 08/12] Enable language server tests for GitHub PR's (#14474) --- .github/workflows/ci_mac.yml | 1 + .github/workflows/job-compile-and-test.yml | 81 +++++++------ Extension/.scripts/common.ts | 9 ++ Extension/.scripts/copyExtensionBinaries.ts | 44 +++++++- Extension/.scripts/installAndCopyBinaries.ts | 35 ++++++ Extension/.scripts/test.ts | 5 +- Extension/.scripts/vscode.ts | 8 +- Extension/package.json | 1 + Extension/test/common/selectTests.ts | 106 ++++++++++++------ Extension/test/minBinaryVersion.json | 3 + .../runWithoutDebugging.terminals.test.ts | 4 +- 11 files changed, 212 insertions(+), 85 deletions(-) create mode 100644 Extension/.scripts/installAndCopyBinaries.ts create mode 100644 Extension/test/minBinaryVersion.json diff --git a/.github/workflows/ci_mac.yml b/.github/workflows/ci_mac.yml index 40acb5f1a..04a7ce613 100644 --- a/.github/workflows/ci_mac.yml +++ b/.github/workflows/ci_mac.yml @@ -23,3 +23,4 @@ jobs: platform: mac checkout-ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target-ref || github.ref }} yarn-args: --network-timeout 100000 + diff --git a/.github/workflows/job-compile-and-test.yml b/.github/workflows/job-compile-and-test.yml index bbdea87f1..cf96f22e0 100644 --- a/.github/workflows/job-compile-and-test.yml +++ b/.github/workflows/job-compile-and-test.yml @@ -38,6 +38,12 @@ jobs: run: yarn install ${{ inputs.yarn-args }} working-directory: Extension + - name: Install gdb (linux) + if: ${{ inputs.platform == 'linux' }} + run: | + sudo apt-get update + sudo apt-get install -y gdb + - name: Compile Sources run: yarn run compile working-directory: Extension @@ -50,53 +56,46 @@ jobs: run: yarn test working-directory: Extension - # These tests don't require the binary. - # On Linux, it is failing (before the tests actually run) with: Test run terminated with signal SIGSEGV. - # But it works on Linux during the E2E test. - - name: Run SingleRootProject tests - if: ${{ inputs.platform != 'linux' }} - run: yarn test --scenario=SingleRootProject --skipCheckBinaries + - name: Acquire Native Binaries + run: yarn install-and-copy-binaries-for-test working-directory: Extension - # NOTE : We can't run the test that require the native binary files - # yet -- there will be an update soon that allows the tester to - # acquire them on-the-fly - # - name: Run languageServer integration tests - # if: ${{ inputs.platform == 'windows' }} - # run: yarn test --scenario=SingleRootProject - # working-directory: Extension + - name: Run languageServer integration tests (Windows) + if: ${{ inputs.platform == 'windows' }} + run: yarn test --scenario=SingleRootProject + working-directory: Extension - # - name: Run E2E IntelliSense features tests - # if: ${{ inputs.platform == 'windows' }} - # run: yarn test --scenario=MultirootDeadlockTest - # working-directory: Extension + - name: Run E2E IntelliSense features tests (Windows) + if: ${{ inputs.platform == 'windows' }} + run: yarn test --scenario=MultirootDeadlockTest + working-directory: Extension - # - name: Run E2E IntelliSense features tests - # if: ${{ inputs.platform == 'windows' }} - # run: yarn test --scenario=RunWithoutDebugging - # working-directory: Extension + - name: Run RunWithoutDebugging tests (Windows) + if: ${{ inputs.platform == 'windows' }} + run: yarn test --scenario=RunWithoutDebugging + working-directory: Extension # NOTE: For mac/linux run the tests with xvfb-action for UI support. # Another way to start xvfb https://github.com/microsoft/vscode-test/blob/master/sample/azure-pipelines.yml - # - name: Run languageServer integration tests (xvfb) - # if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} - # uses: coactions/setup-xvfb@v1 - # with: - # run: yarn test --scenario=SingleRootProject - # working-directory: Extension - - # - name: Run E2E IntelliSense features tests (xvfb) - # if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} - # uses: coactions/setup-xvfb@v1 - # with: - # run: yarn test --scenario=MultirootDeadlockTest - # working-directory: Extension - - # - name: Run E2E IntelliSense features tests (xvfb) - # if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} - # uses: coactions/setup-xvfb@v1 - # with: - # run: yarn test --scenario=RunWithoutDebugging - # working-directory: Extension + - name: Run languageServer integration tests (linux/macOS) + if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} + uses: coactions/setup-xvfb@v1 + with: + run: yarn test --scenario=SingleRootProject + working-directory: Extension + + - name: Run E2E IntelliSense features tests (linux/macOS) + if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} + uses: coactions/setup-xvfb@v1 + with: + run: yarn test --scenario=MultirootDeadlockTest + working-directory: Extension + + - name: Run RunWithoutDebugging tests (linux/macOS) + if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} + uses: coactions/setup-xvfb@v1 + with: + run: yarn test --scenario=RunWithoutDebugging --scenario-arg=skipExternalConsole + working-directory: Extension diff --git a/Extension/.scripts/common.ts b/Extension/.scripts/common.ts index c40e94398..1d8bab7e0 100644 --- a/Extension/.scripts/common.ts +++ b/Extension/.scripts/common.ts @@ -20,9 +20,18 @@ import { verbose } from '../src/Utility/Text/streams'; export const $root = resolve(`${__dirname}/..`); export let $cmd = 'main'; export let $scenario = ''; +export const $scenarioArgs: string[] = []; // loop through the args and pick out --scenario=... and remove it from the $args and set $scenario process.argv.slice(2).filter(each => !(each.startsWith('--scenario=') && ($scenario = each.substring('--scenario='.length)))); +// parse out the scenario arguments. +process.argv.slice(2).reduce((acc, arg) => { + if (arg.startsWith('--scenario-arg=')) { + acc.push(arg.substring('--scenario-arg='.length)); + } + return acc; +}, $scenarioArgs); + export const $args = process.argv.slice(2).filter(each => !each.startsWith('--')); export const $switches = process.argv.slice(2).filter(each => each.startsWith('--')); diff --git a/Extension/.scripts/copyExtensionBinaries.ts b/Extension/.scripts/copyExtensionBinaries.ts index 0ebf078be..23c9b13e0 100644 --- a/Extension/.scripts/copyExtensionBinaries.ts +++ b/Extension/.scripts/copyExtensionBinaries.ts @@ -5,7 +5,8 @@ import { cp, readdir, rm, stat } from 'node:fs/promises'; import { homedir } from 'node:os'; -import { join } from 'node:path'; +import { basename, join } from 'node:path'; +import { verbose } from '../src/Utility/Text/streams'; import { $args, $root, green, heading, note } from './common'; const extensionPrefix = 'ms-vscode.cpptools-'; @@ -73,17 +74,47 @@ async function getInstalledExtensions(root: string): Promise { - if (providedPath) { - return providedPath; +async function findExtensionsFolder(root: string): Promise { + try { + const entries = await readdir(root, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory()) { + if (entry.name === 'extensions') { + const extensionEntries = await readdir(join(root, entry.name), { withFileTypes: true }); + for (const extensionEntry of extensionEntries) { + if (extensionEntry.isDirectory() && extensionEntry.name.startsWith(extensionPrefix)) { + return join(root, entry.name); + } + } + } else { + const result = await findExtensionsFolder(join(root, entry.name)); + if (result) { + return result; + } + } + } + } + } catch { + // Ignore errors (permission denied, etc.) } + return undefined; +} +async function findLatestInstalledExtension(providedPath?: string): Promise { const searchRoots: string[] = [ join(homedir(), '.vscode', 'extensions'), join(homedir(), '.vscode-insiders', 'extensions'), join(homedir(), '.vscode-server', 'extensions'), join(homedir(), '.vscode-server-insiders', 'extensions') ]; + if (providedPath) { + // find a folder called 'extensions' recursively under the provided path and add it to the front of the search roots + const extensionsFolderPath = await findExtensionsFolder(providedPath); + if (extensionsFolderPath) { + verbose(`Found extensions folder under provided path: ${extensionsFolderPath}`); + searchRoots.unshift(extensionsFolderPath); + } + } const installed: InstalledExtension[] = (await Promise.all(searchRoots.map(each => getInstalledExtensions(each)))).flat(); if (!installed.length) { @@ -94,7 +125,7 @@ async function findLatestInstalledExtension(providedPath?: string): Promise { console.log(heading('Copy installed extension binaries')); const installedExtensionPath: string = await findLatestInstalledExtension(sourcePath); @@ -110,4 +141,7 @@ export async function main(sourcePath = $args[0]) { } note(`Copied installed binaries into ${$root}`); + + const installedVersion = tryParseVersion(basename(installedExtensionPath)); + return installedVersion?.join('.'); } diff --git a/Extension/.scripts/installAndCopyBinaries.ts b/Extension/.scripts/installAndCopyBinaries.ts new file mode 100644 index 000000000..69f7f3b37 --- /dev/null +++ b/Extension/.scripts/installAndCopyBinaries.ts @@ -0,0 +1,35 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import { runVSCodeCommand } from '@vscode/test-electron'; +import { writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { $root, error, heading, note } from './common'; +import * as copy from './copyExtensionBinaries'; +import { install, isolated, options } from "./vscode"; + +export async function main() { + console.log(heading(`Install VS Code`)); + const vscode = await install(); + if (!vscode) { + error('Failed to install VS Code'); + return; + } + + console.log(heading('Install latest C/C++ Extension')); + const result = await runVSCodeCommand([...vscode.args ?? [], '--install-extension', 'ms-vscode.cpptools', '--pre-release'], options); + if (result.stdout) { + console.log(result.stdout.toString()); + } + if (result.stderr) { + error(result.stderr.toString()); + } + + const binaryVersion = await copy.main(isolated); + if (binaryVersion) { + await writeFile(join($root, 'bin', 'binaryVersion.json'), JSON.stringify({ version: binaryVersion })); + note(`Wrote binary version ${binaryVersion} to bin/binaryVersion.json`); + } +} diff --git a/Extension/.scripts/test.ts b/Extension/.scripts/test.ts index c6b2a9a2c..033d7010c 100644 --- a/Extension/.scripts/test.ts +++ b/Extension/.scripts/test.ts @@ -14,7 +14,7 @@ import { filepath } from '../src/Utility/Filesystem/filepath'; import { is } from '../src/Utility/System/guards'; import { verbose } from '../src/Utility/Text/streams'; import { getTestInfo } from '../test/common/selectTests'; -import { $args, $root, $scenario, assertAnyFile, assertAnyFolder, brightGreen, checkBinaries, cmdSwitch, cyan, error, gray, green, readJson, red, writeJson } from './common'; +import { $args, $root, $scenario, $scenarioArgs, assertAnyFile, assertAnyFolder, brightGreen, checkBinaries, cmdSwitch, cyan, error, gray, green, readJson, red, writeJson } from './common'; import { install, isolated, options } from './vscode'; export { install, reset } from './vscode'; @@ -90,7 +90,8 @@ async function scenarioTests(assets: string, name: string, workspace: string) { extensionTestsPath: resolve($root, 'dist/test/common/selectTests'), launchArgs: workspace ? [...options.launchArgs, workspace] : options.launchArgs, extensionTestsEnv: { - SCENARIO: assets + SCENARIO: assets, + SCENARIO_ARGS: $scenarioArgs.join(',') } }); } diff --git a/Extension/.scripts/vscode.ts b/Extension/.scripts/vscode.ts index fcd5ac7e3..9be75a371 100644 --- a/Extension/.scripts/vscode.ts +++ b/Extension/.scripts/vscode.ts @@ -17,7 +17,7 @@ export const settings = resolve(userDir, "User", 'settings.json'); export const options = { cachePath: `${isolated}/cache`, - launchArgs: ['--no-sandbox', '--disable-updates', '--skip-welcome', '--skip-release-notes', `--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`, '--disable-workspace-trust'] + launchArgs: ['--no-sandbox', '--disable-updates', '--skip-welcome', '--skip-release-notes', '--disable-extensions', `--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`, '--disable-workspace-trust'] }; export async function install() { @@ -34,9 +34,9 @@ export async function install() { args.push(`--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`); // install the appropriate extensions - // spawnSync(cli, [...args, '--install-extension', 'ms-vscode.cpptools'], { encoding: 'utf-8', stdio: 'ignore' }); - // spawnSync(cli, [...args, '--install-extension', 'twxs.cmake'], { encoding: 'utf-8', stdio: 'ignore' }); - // spawnSync(cli, [...args, '--install-extension', 'ms-vscode.cmake-tools'], { encoding: 'utf-8', stdio: 'ignore' }); + // runVSCodeCommand([...args, '--install-extension', 'ms-vscode.cpptools'], options); + // runVSCodeCommand([...args, '--install-extension', 'twxs.cmake'], options); + // runVSCodeCommand([...args, '--install-extension', 'ms-vscode.cmake-tools'], options); const settingsJson = await readJson(settings, {}); if (!settingsJson["workbench.colorTheme"]) { settingsJson["workbench.colorTheme"] = "Tomorrow Night Blue"; diff --git a/Extension/package.json b/Extension/package.json index e697ba4e2..9b22073b8 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -6854,6 +6854,7 @@ "generate-options-schema": "ts-node -T ./.scripts/generateOptionsSchema.ts", "copy-walkthrough-media": "ts-node -T ./.scripts/copyWalkthruMedia.ts", "copy-extension-binaries": "ts-node -T ./.scripts/copyExtensionBinaries.ts", + "install-and-copy-binaries-for-test": "ts-node -T ./.scripts/installAndCopyBinaries.ts", "translations-export": "yarn install && yarn prep && yarn generate-native-strings && gulp translations-export", "translations-generate": "gulp translations-generate", "translations-import": "gulp translations-import", diff --git a/Extension/test/common/selectTests.ts b/Extension/test/common/selectTests.ts index 1ad470056..0d47fce40 100644 --- a/Extension/test/common/selectTests.ts +++ b/Extension/test/common/selectTests.ts @@ -3,8 +3,8 @@ * See 'LICENSE' in the project root for license information. * ------------------------------------------------------------------------------------------ */ -import { readdir } from 'fs/promises'; -import { IOptions, glob as globSync } from 'glob'; +import { readdir, readFile } from 'fs/promises'; +import { glob as globSync, IOptions } from 'glob'; import * as Mocha from 'mocha'; import { basename, dirname, resolve } from 'path'; import { env } from 'process'; @@ -73,10 +73,49 @@ export async function getTestInfo(...scenarioOptions: (string | undefined)[]) { return undefined; } -export function run (testsRoot: string, cb: (error: any, failures?: number) => void): void { /** - * This code runs in the extension host process, and not in the launch (main.ts) process. + * When running tests after using `yarn install-and-copy-binaries-for-test`, this function determines + * if the tests should be skipped based on whether the binary version copied for tests is compatible + * with the minimum required version. The minimum required binary version is defined in the + * `minBinaryVersion.json` file and changes when there are breaking changes in the communication + * protocol or messages. + * + * When running locally, the function is expected to always return false since you're more likely to + * have the correct binaries available. If you ever ran `yarn install-and-copy-binaries-for-test` locally + * and the binaries are too old, this function will return true and skip the tests. The remedy is to + * delete the `bin/binaryVersion.json` file and/or re-run `yarn install-and-copy-binaries-for-test` to + * get the latest binaries. + * @returns A promise that resolves to a boolean indicating whether the tests should be skipped. */ +async function shouldSkipTests(): Promise { + try { + const binaryVersion = JSON.parse(await readFile(`${$root}/bin/binaryVersion.json`, 'utf-8')) as { version: string } | undefined; + const binaryCompat = JSON.parse(await readFile(`${$root}/test/minBinaryVersion.json`, 'utf-8')) as { minBinaryVersion: string } | undefined; + if (binaryCompat?.minBinaryVersion && binaryVersion?.version) { + const minParts = binaryCompat.minBinaryVersion.split('.').map(Number); + const actualParts = binaryVersion.version.split('.').map(Number); + const maxLen = Math.max(minParts.length, actualParts.length); + let tooOld = false; + for (let i = 0; i < maxLen; i++) { + const diff = (actualParts[i] ?? 0) - (minParts[i] ?? 0); + if (diff < 0) { tooOld = true; break; } + if (diff > 0) { break; } + } + if (tooOld) { + console.warn(`\nBinary-dependent tests SKIPPED: installed binary version ${binaryVersion.version} is below the required minimum ${binaryCompat.minBinaryVersion}.`); + console.warn(`Tests will re-enable automatically once binaries >= ${binaryCompat.minBinaryVersion} are installed or 'bin/binaryVersion.json' is removed.\n`); + return true; + } + } + } catch { + } + return false; +} + +export function run(testsRoot: string, cb: (error: any, failures?: number) => void): void { + /** + * This code runs in the extension host process, and not in the launch (main.ts) process. + */ let location = ''; // scan through the $args to find the --scenario=... @@ -87,34 +126,37 @@ export function run (testsRoot: string, cb: (error: any, failures?: number) => v console.error(`The Scenario folder must be specified either by '--scenario=...' or an environment variable 'SCENARIO=...'`); process.exit(1); } - const { name} = testInfo; - - void glob(`${$root}/dist/test/scenarios/${name}/tests/**/**.test.js`).then((files) => { - - try { - if (!files.length) { - throw new Error(`Unable to find unit tests for ${name} at '${$root}/dist/test/scenarios/${name}/tests/**/**.test.js'`); - } - const mocha = new Mocha({ - ui: 'tdd', - timeout: 500000, - require: ['source-map-support/register'], - color: true - }); - - // Add files to the test suite - files.forEach(f => mocha.addFile(resolve(testsRoot, f))); - - console.log('\n\n=============================================\n Test Output\n\n'); - // Run the mocha test - mocha.run((failures: any) => { - cb(null, failures); - console.log('\n\n=============================================\n\n'); - }); - } catch (err) { - console.error(err); - cb(err); + const { name } = testInfo; + + if (await shouldSkipTests()) { + cb(null, 0); + return; + } + + const files = await glob(`${$root}/dist/test/scenarios/${name}/tests/**/**.test.js`).catch(returns.none); + try { + if (!files.length) { + throw new Error(`Unable to find unit tests for ${name} at '${$root}/dist/test/scenarios/${name}/tests/**/**.test.js'`); } - }); + const mocha = new Mocha({ + ui: 'tdd', + timeout: 500000, + require: ['source-map-support/register'], + color: true + }); + + // Add files to the test suite + files.forEach(f => mocha.addFile(resolve(testsRoot, f))); + + console.log('\n\n=============================================\n Test Output\n\n'); + // Run the mocha test + mocha.run((failures: any) => { + cb(null, failures); + console.log('\n\n=============================================\n\n'); + }); + } catch (err) { + console.error(err); + cb(err); + } }); } diff --git a/Extension/test/minBinaryVersion.json b/Extension/test/minBinaryVersion.json new file mode 100644 index 000000000..0f97e8d05 --- /dev/null +++ b/Extension/test/minBinaryVersion.json @@ -0,0 +1,3 @@ +{ + "minBinaryVersion": "1.33.0" +} \ No newline at end of file diff --git a/Extension/test/scenarios/RunWithoutDebugging/tests/runWithoutDebugging.terminals.test.ts b/Extension/test/scenarios/RunWithoutDebugging/tests/runWithoutDebugging.terminals.test.ts index 57b27d975..eb8e11996 100644 --- a/Extension/test/scenarios/RunWithoutDebugging/tests/runWithoutDebugging.terminals.test.ts +++ b/Extension/test/scenarios/RunWithoutDebugging/tests/runWithoutDebugging.terminals.test.ts @@ -108,6 +108,7 @@ suite('Run Without Debugging Terminal and Arguments Test', function (this: Mocha 'two words', path.join(workspacePath, 'input folder', 'three words.txt') ]; + const skipExternalConsole = process.env.SCENARIO_ARGS?.split(',').includes('skipExternalConsole'); suiteSetup(async function (): Promise { const extension: vscode.Extension = vscode.extensions.getExtension('ms-vscode.cpptools') || assert.fail('Extension not found'); @@ -169,7 +170,8 @@ suite('Run Without Debugging Terminal and Arguments Test', function (this: Mocha for (const profile of profiles) { const profileSuffix = profile ? ` with ${profile} as the default terminal` : consoleCase.consoleMode === 'integratedTerminal' ? ' with default terminal' : ''; - test(`No-debug launch via ${consoleCase.label} handles ${programCase.label}${profileSuffix}`, async () => { + const testFunc = skipExternalConsole && consoleCase.consoleMode === 'externalTerminal' ? test.skip : test; + testFunc(`No-debug launch via ${consoleCase.label} handles ${programCase.label}${profileSuffix}`, async () => { await setWindowsDefaultTerminalProfile(profile); disposeTerminals(executablePaths); From 4aa35c9681abce89493a50a4b6c308c7f7054994 Mon Sep 17 00:00:00 2001 From: Bob Brown Date: Wed, 1 Jul 2026 18:22:57 -0700 Subject: [PATCH 09/12] Allow for platform overrides in cppbuild tasks (#14559) --- Extension/.scripts/generateOptionsSchema.ts | 14 +- Extension/package.json | 325 +++++++++++++++++- Extension/package.nls.json | 1 + .../LanguageServer/cppBuildTaskProvider.ts | 163 ++++++--- Extension/tools/TaskDefinitionsSchema.json | 138 ++++++++ 5 files changed, 581 insertions(+), 60 deletions(-) create mode 100644 Extension/tools/TaskDefinitionsSchema.json diff --git a/Extension/.scripts/generateOptionsSchema.ts b/Extension/.scripts/generateOptionsSchema.ts index 346b21007..237945ed3 100644 --- a/Extension/.scripts/generateOptionsSchema.ts +++ b/Extension/.scripts/generateOptionsSchema.ts @@ -85,8 +85,13 @@ function replaceReferences(definitions: any, objects: any): any { objects[key].anyOf = replaceReferences(definitions, objects[key].anyOf); } - // Recursively replace references if this object has properties. - if (objects[key].hasOwnProperty('type') && objects[key].type === 'object' && objects[key].properties !== null) { + // Handle 'oneOf' with references + if (objects[key].hasOwnProperty('oneOf')) { + objects[key].oneOf = replaceReferences(definitions, objects[key].oneOf); + } + + // Recursively replace references if this schema node has properties. + if (objects[key].hasOwnProperty('properties') && objects[key].properties !== null) { objects[key].properties = replaceReferences(definitions, objects[key].properties); objects[key].properties = updateDefaults(objects[key].properties, objects[key].default); } @@ -117,11 +122,13 @@ function mergeReferences(baseDefinitions: any, additionalDefinitions: any): void export async function main() { const packageJSON: any = JSON.parse(await read(resolve($root, 'package.json'))); const schemaJSON: any = JSON.parse(await read(resolve($root, 'tools/OptionsSchema.json'))); + const taskDefinitionsJSON: any = JSON.parse(await read(resolve($root, 'tools/TaskDefinitionsSchema.json'))); const symbolSettingsJSON: any = JSON.parse(await read(resolve($root, 'tools/VSSymbolSettings.json'))); mergeReferences(schemaJSON.definitions, symbolSettingsJSON.definitions); schemaJSON.definitions = replaceReferences(schemaJSON.definitions, schemaJSON.definitions); + taskDefinitionsJSON.definitions = replaceReferences(taskDefinitionsJSON.definitions, taskDefinitionsJSON.definitions); // Hard Code adding in configurationAttributes launch and attach. // cppdbg @@ -132,6 +139,9 @@ export async function main() { packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.CppvsdbgLaunchOptions; packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.CppvsdbgAttachOptions; + // task definitions + packageJSON.contributes.taskDefinitions = [taskDefinitionsJSON.definitions.CppBuildTaskDefinition]; + let content: string = JSON.stringify(packageJSON, null, 4); // We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will diff --git a/Extension/package.json b/Extension/package.json index 9b22073b8..24df79369 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -529,9 +529,332 @@ } } }, + "problemMatcher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "%c_cpp.taskDefinitions.problemMatcher.description%" + }, "detail": { "type": "string", "description": "%c_cpp.taskDefinitions.detail.description%" + }, + "windows": { + "type": "object", + "properties": { + "command": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + }, + "args": { + "type": "array", + "description": "%c_cpp.taskDefinitions.args.description%", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + } + }, + "options": { + "type": "object", + "description": "%c_cpp.taskDefinitions.options.description%", + "properties": { + "cwd": { + "type": "string", + "description": "%c_cpp.taskDefinitions.options.cwd.description%" + } + } + }, + "problemMatcher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "%c_cpp.taskDefinitions.problemMatcher.description%" + } + } + }, + "linux": { + "type": "object", + "properties": { + "command": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + }, + "args": { + "type": "array", + "description": "%c_cpp.taskDefinitions.args.description%", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + } + }, + "options": { + "type": "object", + "description": "%c_cpp.taskDefinitions.options.description%", + "properties": { + "cwd": { + "type": "string", + "description": "%c_cpp.taskDefinitions.options.cwd.description%" + } + } + }, + "problemMatcher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "%c_cpp.taskDefinitions.problemMatcher.description%" + } + } + }, + "osx": { + "type": "object", + "properties": { + "command": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + }, + "args": { + "type": "array", + "description": "%c_cpp.taskDefinitions.args.description%", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + } + ] + } + }, + "options": { + "type": "object", + "description": "%c_cpp.taskDefinitions.options.description%", + "properties": { + "cwd": { + "type": "string", + "description": "%c_cpp.taskDefinitions.options.cwd.description%" + } + } + }, + "problemMatcher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "%c_cpp.taskDefinitions.problemMatcher.description%" + } + } } } } @@ -6943,4 +7266,4 @@ "uuid": "^11.1.1", "undici": "^7.28.0" } -} \ No newline at end of file +} diff --git a/Extension/package.nls.json b/Extension/package.nls.json index 17df9bcdb..68a7266a1 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -1005,6 +1005,7 @@ "c_cpp.taskDefinitions.args.quoting.weak.description": "Quotes the argument using the shell's weak quote character (e.g. \" under bash).", "c_cpp.taskDefinitions.options.description": "Additional command options.", "c_cpp.taskDefinitions.options.cwd.description": "The current working directory of the executed program or script. If omitted Code's current workspace root is used.", + "c_cpp.taskDefinitions.problemMatcher.description": "One or more problem matchers to use to detect compiler errors and warnings in task output.", "c_cpp.taskDefinitions.detail.description": "Additional details of the task.", "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.description": "Current and compile-time paths to the same source trees. Files found under the EditorPath are mapped to the CompileTimePath path for breakpoint matching and mapped from CompileTimePath to EditorPath when displaying stacktrace locations.", "c_cpp.debuggers.sourceFileMap.sourceFileMapEntry.editorPath.description": "The path to the source tree the editor will use.", diff --git a/Extension/src/LanguageServer/cppBuildTaskProvider.ts b/Extension/src/LanguageServer/cppBuildTaskProvider.ts index e42b429c6..486e3df64 100644 --- a/Extension/src/LanguageServer/cppBuildTaskProvider.ts +++ b/Extension/src/LanguageServer/cppBuildTaskProvider.ts @@ -24,8 +24,18 @@ export interface CppBuildTaskDefinition extends TaskDefinition { type: string; label: string; // The label appears in tasks.json file. command: string | util.IQuotedString; - args: (string | util.IQuotedString)[]; - options: cp.ExecOptions | cp.SpawnOptions | undefined; + args?: (string | util.IQuotedString)[]; + options?: cp.ExecOptions | undefined; + windows?: CppBuildTaskPlatformOverride; + linux?: CppBuildTaskPlatformOverride; + osx?: CppBuildTaskPlatformOverride; +} + +interface CppBuildTaskPlatformOverride { + command?: string | util.IQuotedString; + args?: (string | util.IQuotedString)[]; + options?: cp.ExecOptions | undefined; + problemMatcher?: string | string[]; } export class CppBuildTask extends Task { @@ -50,7 +60,7 @@ export class CppBuildTaskProvider implements TaskProvider { const execution: ProcessExecution | ShellExecution | CustomExecution | undefined = _task.execution; if (!execution) { const definition: CppBuildTaskDefinition = _task.definition; - _task = this.getTask(definition.command, false, definition.args ? definition.args : [], definition, _task.detail); + _task = this.getTask(definition, _task.detail); return _task; } return undefined; @@ -59,7 +69,7 @@ export class CppBuildTaskProvider implements TaskProvider { public resolveInsiderTask(_task: CppBuildTask): CppBuildTask | undefined { const definition: CppBuildTaskDefinition = _task.definition; definition.label = definition.label.replace(ext.configPrefix, ""); - _task = this.getTask(definition.command, false, definition.args ? definition.args : [], definition, _task.detail); + _task = this.getTask(definition, _task.detail); return _task; } @@ -152,83 +162,118 @@ export class CppBuildTaskProvider implements TaskProvider { return emptyTasks; } - // Create a build task per compiler path + // Create a build task per compiler path. const result: CppBuildTask[] = []; - // Task for valid user compiler path setting + // Task for valid user compiler path setting. if (isCompilerValid && userCompilerPath) { - result.push(this.getTask(userCompilerPath, appendSourceToName, userCompilerPathAndArgs?.allCompilerArgs)); + result.push(this.generateTask(userCompilerPath, appendSourceToName, userCompilerPathAndArgs?.allCompilerArgs)); } - // Tasks for known compiler paths + // Tasks for known compiler paths. if (knownCompilerPaths) { - result.push(...knownCompilerPaths.map(compilerPath => this.getTask(compilerPath, appendSourceToName, undefined))); + result.push(...knownCompilerPaths.map(compilerPath => this.generateTask(compilerPath, appendSourceToName, undefined))); } return result; } - private getTask: (compilerPath: string | util.IQuotedString, appendSourceToName: boolean, compilerArgs?: (string | util.IQuotedString)[], definition?: CppBuildTaskDefinition, detail?: string) => Task = (compilerPath: string | util.IQuotedString, appendSourceToName: boolean, compilerArgs?: (string | util.IQuotedString)[], definition?: CppBuildTaskDefinition, detail?: string) => { + private generateTask(compilerPath: string | util.IQuotedString, appendSourceToName: boolean, compilerArgs?: (string | util.IQuotedString)[]): CppBuildTask { const compilerPathString: string = util.isString(compilerPath) ? compilerPath : compilerPath.value; - const compilerPathBase: string = path.basename(compilerPathString); - const isCl: boolean = compilerPathBase.toLowerCase() === "cl.exe"; - const isClang: boolean = !isCl && compilerPathBase.toLowerCase().includes("clang"); - // Double-quote the command if needed. - const resolvedCompilerPathString: string = isCl ? compilerPathBase : compilerPathString; - let resolvedCompilerPath: string | util.IQuotedString = compilerPath; - if (isCl) { - resolvedCompilerPath = compilerPathBase; - } - - if (!definition) { - const isWindows: boolean = os.platform() === 'win32'; - const taskLabel: string = ((appendSourceToName && !compilerPathBase.startsWith(ext.configPrefix)) ? - ext.configPrefix : "") + compilerPathBase + " " + localize("build.active.file", "build active file"); - const programName: string = util.defaultExePath(); - let args: (string | util.IQuotedString)[] = isCl ? - ['/Zi', '/EHsc', '/nologo', `/Fe${programName}`, '${file}'] : - isClang ? - ['-fcolor-diagnostics', '-fansi-escape-codes', '-g', '${file}', '-o', programName] : - ['-fdiagnostics-color=always', '-g', '${file}', '-o', programName]; - - if (compilerArgs && compilerArgs.length > 0) { - args = args.concat(compilerArgs); - } - const cwd: string = isWindows && !isCl && !process.env.PATH?.includes(path.dirname(compilerPathString)) ? path.dirname(compilerPathString) : "${fileDirname}"; - const options: cp.ExecOptions | cp.SpawnOptions | undefined = { cwd: cwd }; - definition = { - type: CppBuildTaskProvider.CppBuildScriptType, - label: taskLabel, - command: compilerPath, - args: args, - options: options - }; - if (isCl) { - definition.command = compilerPathBase; - } + const compilerName: string = path.basename(compilerPathString); + const isCl: boolean = compilerName.toLowerCase() === "cl.exe"; + const isClang: boolean = !isCl && compilerName.toLowerCase().includes("clang"); + + const isWindows: boolean = os.platform() === 'win32'; + const taskLabel: string = ((appendSourceToName && !compilerName.startsWith(ext.configPrefix)) ? + ext.configPrefix : "") + compilerName + " " + localize("build.active.file", "build active file"); + const programName: string = util.defaultExePath(); + let args: (string | util.IQuotedString)[] = isCl ? + ['/Zi', '/EHsc', '/nologo', `/Fe${programName}`, '${file}'] : + isClang ? + ['-fcolor-diagnostics', '-fansi-escape-codes', '-g', '${file}', '-o', programName] : + ['-fdiagnostics-color=always', '-g', '${file}', '-o', programName]; + + if (compilerArgs && compilerArgs.length > 0) { + args = args.concat(compilerArgs); } + const cwd: string = isWindows && !isCl && !process.env.PATH?.includes(path.dirname(compilerPathString)) ? path.dirname(compilerPathString) : "${fileDirname}"; + const options: cp.ExecOptions | undefined = { cwd: cwd }; + const definition: CppBuildTaskDefinition = { + type: CppBuildTaskProvider.CppBuildScriptType, + label: taskLabel, + command: isCl ? compilerName : compilerPath, + args: args, + options: options + }; + + return this.getTask(definition); + } + + private getTask(definition: CppBuildTaskDefinition, detail?: string): CppBuildTask { + const platformDefinition: CppBuildTaskDefinition = this.applyPlatformOverrides(definition); + const command: string = util.isString(platformDefinition.command) ? platformDefinition.command : platformDefinition.command.value; + const compilerName: string = path.basename(command); + const isCl: boolean = compilerName.toLowerCase() === "cl.exe"; + const isClang: boolean = !isCl && compilerName.toLowerCase().includes("clang"); const editor: TextEditor | undefined = window.activeTextEditor; const folder: WorkspaceFolder | undefined = editor ? workspace.getWorkspaceFolder(editor.document.uri) : undefined; - const taskUsesActiveFile: boolean = definition.args.some(arg => { + const taskUsesActiveFile: boolean = platformDefinition.args?.some(arg => { if (util.isString(arg)) { return arg.indexOf('${file}') >= 0; } return arg.value.indexOf('${file}') >= 0; - }); // Need to check this before ${file} is resolved + }) || false; // Need to check this before ${file} is resolved const scope: WorkspaceFolder | TaskScope = folder ? folder : TaskScope.Workspace; - const task: CppBuildTask = new Task(definition, scope, definition.label, ext.CppSourceStr, - new CustomExecution(async (resolvedDefinition: TaskDefinition): Promise => - // When the task is executed, this callback will run. Here, we setup for running the task. - new CustomBuildTaskTerminal(resolvedCompilerPath, resolvedDefinition.args, resolvedDefinition.options, { taskUsesActiveFile, insertStd: isClang && os.platform() === 'darwin' }) - ), isCl ? '$msCompile' : '$gcc'); + const customExecution: CustomExecution = new CustomExecution(async (resolvedDefinition: TaskDefinition): Promise => { + // When the task is executed, this callback will run. Here, we setup for running the task. + // Apply platform-specific overrides (windows/linux/osx) at execution time so that VS Code + // can still match the task definition by its original shape during the resolve phase. + const effectiveDefinition: CppBuildTaskDefinition = this.applyPlatformOverrides(resolvedDefinition as CppBuildTaskDefinition); + const effectiveArgs: (string | util.IQuotedString)[] = effectiveDefinition.args ? effectiveDefinition.args : []; + return new CustomBuildTaskTerminal( + effectiveDefinition.command, + effectiveArgs, + effectiveDefinition.options, + { taskUsesActiveFile, insertStd: isClang && os.platform() === 'darwin' } + ); + }); + const task: CppBuildTask = new CppBuildTask(definition, scope, definition.label, ext.CppSourceStr, customExecution, platformDefinition.problemMatcher ?? (isCl ? '$msCompile' : '$gcc')); task.group = TaskGroup.Build; - task.detail = detail ? detail : localize("compiler.details", "compiler:") + " " + resolvedCompilerPathString; + task.detail = detail ? detail : localize("compiler.details", "compiler:") + " " + (isCl ? compilerName : command); return task; - }; + } + + private applyPlatformOverrides(definition: CppBuildTaskDefinition): CppBuildTaskDefinition { + const platform: NodeJS.Platform = os.platform(); + let platformOverride: CppBuildTaskPlatformOverride | undefined; + + if (platform === 'win32') { + platformOverride = definition.windows; + } else if (platform === 'linux') { + platformOverride = definition.linux; + } else if (platform === 'darwin') { + platformOverride = definition.osx; + } + + if (!platformOverride) { + return definition; + } + + const mergedDefinition: CppBuildTaskDefinition = { + ...definition, + command: platformOverride.command ?? definition.command, + args: platformOverride.args ?? definition.args, + options: platformOverride.options ?? definition.options, + problemMatcher: platformOverride.problemMatcher ?? definition.problemMatcher + }; + + return mergedDefinition; + } public async getJsonTasks(): Promise { const rawJson: any = await this.getRawTasksJson(); @@ -242,9 +287,13 @@ export class CppBuildTaskProvider implements TaskProvider { label: task.label, command: task.command, args: task.args, - options: task.options + options: task.options, + windows: task.windows, + linux: task.linux, + osx: task.osx, + problemMatcher: task.problemMatcher }; - const cppBuildTask: CppBuildTask = new Task(definition, TaskScope.Workspace, task.label, ext.CppSourceStr); + const cppBuildTask: CppBuildTask = new CppBuildTask(definition, TaskScope.Workspace, task.label, ext.CppSourceStr); cppBuildTask.detail = task.detail; cppBuildTask.existing = true; if (util.isObject(task.group) && task.group.isDefault) { diff --git a/Extension/tools/TaskDefinitionsSchema.json b/Extension/tools/TaskDefinitionsSchema.json new file mode 100644 index 000000000..95da3f2e3 --- /dev/null +++ b/Extension/tools/TaskDefinitionsSchema.json @@ -0,0 +1,138 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VS Code task definitions", + "description": "A json schema for VS Code task definitions contributed by the C/C++ extension", + "type": "object", + "definitions": { + "TaskStringWithQuoting": { + "type": "object", + "required": [ + "value", + "quoting" + ], + "properties": { + "value": { + "type": "string", + "description": "%c_cpp.taskDefinitions.args.value.description%" + }, + "quoting": { + "type": "string", + "enum": [ + "escape", + "strong", + "weak" + ], + "enumDescriptions": [ + "%c_cpp.taskDefinitions.args.quoting.escape.description%", + "%c_cpp.taskDefinitions.args.quoting.strong.description%", + "%c_cpp.taskDefinitions.args.quoting.weak.description%" + ], + "default": "strong", + "description": "%c_cpp.taskDefinitions.args.quoting.description%" + } + } + }, + "TaskStringOrQuotedString": { + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/TaskStringWithQuoting" + } + ] + }, + "CppBuildTaskOptions": { + "type": "object", + "description": "%c_cpp.taskDefinitions.options.description%", + "properties": { + "cwd": { + "type": "string", + "description": "%c_cpp.taskDefinitions.options.cwd.description%" + } + } + }, + "CppBuildTaskProblemMatcher": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "%c_cpp.taskDefinitions.problemMatcher.description%" + }, + "CppBuildTaskPlatformOverride": { + "type": "object", + "properties": { + "command": { + "$ref": "#/definitions/TaskStringOrQuotedString" + }, + "args": { + "type": "array", + "description": "%c_cpp.taskDefinitions.args.description%", + "items": { + "$ref": "#/definitions/TaskStringOrQuotedString" + } + }, + "options": { + "$ref": "#/definitions/CppBuildTaskOptions" + }, + "problemMatcher": { + "$ref": "#/definitions/CppBuildTaskProblemMatcher" + } + } + }, + "CppBuildTaskDefinition": { + "type": "cppbuild", + "required": [ + "command", + "label" + ], + "properties": { + "label": { + "type": "string", + "description": "%c_cpp.taskDefinitions.name.description%" + }, + "command": { + "$ref": "#/definitions/TaskStringOrQuotedString" + }, + "args": { + "type": "array", + "description": "%c_cpp.taskDefinitions.args.description%", + "items": { + "$ref": "#/definitions/TaskStringOrQuotedString" + } + }, + "options": { + "$ref": "#/definitions/CppBuildTaskOptions" + }, + "problemMatcher": { + "$ref": "#/definitions/CppBuildTaskProblemMatcher" + }, + "detail": { + "type": "string", + "description": "%c_cpp.taskDefinitions.detail.description%" + }, + "windows": { + "$ref": "#/definitions/CppBuildTaskPlatformOverride" + }, + "linux": { + "$ref": "#/definitions/CppBuildTaskPlatformOverride" + }, + "osx": { + "$ref": "#/definitions/CppBuildTaskPlatformOverride" + } + } + }, + "TaskDefinitions": [ + { + "$ref": "#/definitions/CppBuildTaskDefinition" + } + ] + } +} \ No newline at end of file From 894e10136366b6cdaa60af8b9e5516e984b70717 Mon Sep 17 00:00:00 2001 From: tieo <65707274+tieo@users.noreply.github.com> Date: Thu, 2 Jul 2026 03:50:47 +0200 Subject: [PATCH 10/12] Fix C/C++ debug hover on intermediate members of a dereferenced expression (#14540) * Add EvaluatableExpressionProvider to fix C/C++ debug hover on dereferenced members VS Code's default debug data-tip keeps a leading `*`/`&` and clips on the right, so hovering an intermediate member of e.g. `*a.b.c` evaluates `*a.b` (a dereference of the struct `a.b`) and shows no value. Register an EvaluatableExpressionProvider that, only for that case, returns the expression without the leading operator. Every other expression returns undefined so the default behavior is unchanged. * Move the debug hover provider to the debugger Register the EvaluatableExpressionProvider during debugger activation instead of through the language client, so it also works when IntelliSense is disabled, and move it next to the other debugger code. The expression computation lives in a vscode-free module (evaluatableExpression.ts) so it can be unit tested directly. Registering a provider replaces VS Code's built-in data-tip expression detection, so it reproduces that for ordinary tokens and additionally handles access chains the built-in detection gets wrong for C/C++: - A leading */& binds to the whole access chain (the postfix ., ->, [] operators bind tighter), so it is dropped for an interior member of a dot chain, where *a.b would dereference the struct a.b, and kept on the final member and before ->. - Array subscripts and :: are kept in the token, so members after a subscript (a.b[i].c) and scoped names (ns::var) resolve instead of producing a broken fragment. * Document why the leading-operator drop is .-only The leading */& is kept before -> / [] and at the end of a chain because those left operands are provably pointers/arrays, so *ptr->m, *a.b[i] and &a[i] evaluate without error; it is dropped only before . where the left operand may be a struct. Documents these keep-leading outcomes as deliberate per review feedback. * Decline non-token cursor positions inside a subscript Inside [...] the token spans whitespace and operators (e.g. a[i + j]), so returning the nearest identifier evaluated the wrong expression when the cursor was on an operator or space. Return undefined unless the cursor is on the index identifier itself, and add tests. * Rewrite hover token detection with a balanced-bracket scanner Replace the token regex with a manual scanner so nested subscripts (a[b[i]]) stay in one token, fix hovering past the last identifier truncating a trailing subscript, and decline non-token positions inside [...] (operators/whitespace). Keep the leading * only on the final dereferenced segment (including a final subscript element like *a.b[i]); drop it on interior segments and drop a leading & always. Removes the previous regex (and its ReDoS surface). --------- Co-authored-by: Sean McManus --- .../src/Debugger/evaluatableExpression.ts | 235 ++++++++++++++++++ .../Debugger/evaluatableExpressionProvider.ts | 18 ++ Extension/src/Debugger/extension.ts | 6 +- .../test/unit/evaluatableExpression.test.ts | 115 +++++++++ 4 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 Extension/src/Debugger/evaluatableExpression.ts create mode 100755 Extension/src/Debugger/evaluatableExpressionProvider.ts create mode 100644 Extension/test/unit/evaluatableExpression.test.ts diff --git a/Extension/src/Debugger/evaluatableExpression.ts b/Extension/src/Debugger/evaluatableExpression.ts new file mode 100644 index 000000000..798bd6ca8 --- /dev/null +++ b/Extension/src/Debugger/evaluatableExpression.ts @@ -0,0 +1,235 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +// The column range and text of the expression a debug data-tip should evaluate. +export interface EvaluatableExpressionInfo { + readonly startColumn: number; + readonly endColumn: number; + readonly expression: string; +} + +const wordChar: RegExp = /[\p{L}\p{N}_]/u; + +function isWord(ch: string | undefined): boolean { + return ch !== undefined && wordChar.test(ch); +} + +// Index just past the `]` that closes the `[` at `open`, or -1 if it is unbalanced. +function matchingClose(line: string, open: number): number { + let depth: number = 0; + for (let j: number = open; j < line.length; j++) { + if (line[j] === '[') { + depth++; + } else if (line[j] === ']') { + depth--; + if (depth === 0) { + return j + 1; + } + } + } + return -1; +} + +// Index of the `[` that opens the `]` at `close`, or -1 if it is unbalanced. +function matchingOpen(line: string, close: number): number { + let depth: number = 0; + for (let j: number = close; j >= 0; j--) { + if (line[j] === ']') { + depth++; + } else if (line[j] === '[') { + depth--; + if (depth === 0) { + return j; + } + } + } + return -1; +} + +// Start of the access chain that the subscript opening at `open` applies to, without crossing +// `exprStart` or an enclosing (still-open) `[`. +function primaryStart(line: string, open: number, exprStart: number): number { + let s: number = open; + while (s > exprStart) { + const prev: string = line[s - 1]; + if (isWord(prev)) { + while (s > exprStart && isWord(line[s - 1])) { + s--; + } + } else if (prev === '.') { + s--; + } else if (prev === '>' && line[s - 2] === '-') { + s -= 2; + } else if (prev === ':' && line[s - 2] === ':') { + s -= 2; + } else if (prev === ']') { + const open2: number = matchingOpen(line, s - 1); + if (open2 < exprStart) { + break; + } + s = open2; + } else { + break; + } + } + return s; +} + +// Computes the expression a debug data-tip should evaluate for the token at `character` in `line`, +// or undefined when the cursor is not on an expression token. +// +// Registering an EvaluatableExpressionProvider replaces VS Code's built-in data-tip expression +// detection, so this reproduces that detection for ordinary tokens and additionally resolves access +// chains involving a leading `*`/`&` or array subscripts, which the built-in detection mishandles: +// - A leading `*` is kept only when hovering the final segment of the chain (the value actually +// dereferenced, e.g. `*a.b.c`); on any interior segment it is dropped, so hovering `b` in +// `*a.b.c` gives `a.b` and hovering `b` in `*a.b[i]` gives `a.b` (not `*a.b`, the dereferenced +// struct/array base). A leading `&` is always dropped so the hovered variable shows its value +// rather than its address. +// - Array subscripts are part of the chain, including nested ones like `a[b[i]]`; hovering `c` in +// `a.b[i].c` evaluates `a.b[i].c` rather than a fragment after the `]`, hovering a subscript +// bracket evaluates the indexed element, and hovering the index evaluates it on its own. +// +// This has no vscode dependency so it can be unit tested directly. +export function computeEvaluatableExpression(line: string, character: number): EvaluatableExpressionInfo | undefined { + // Find the access-chain token containing the cursor: an optional leading run of `*`/`&`, then a + // chain of identifiers, `.`, `->`, `::` and balanced `[...]` subscripts. Brackets are matched by + // depth so nested subscripts stay in one token. The cursor is matched with an inclusive end so a + // token is selected when the cursor is at its trailing edge (VS Code's built-in does the same). + let tokenStart: number = -1; + let tokenEnd: number = -1; + const n: number = line.length; + let i: number = 0; + while (i < n) { + const start: number = i; + while (i < n && (line[i] === '*' || line[i] === '&')) { + i++; + } + let chained: boolean = false; + let advanced: boolean = true; + while (i < n && advanced) { + const c: string = line[i]; + if (isWord(c)) { + while (i < n && isWord(line[i])) { + i++; + } + chained = true; + } else if (c === '.') { + i++; + chained = true; + } else if (c === '-' && line[i + 1] === '>') { + i += 2; + chained = true; + } else if (c === ':' && line[i + 1] === ':') { + i += 2; + chained = true; + } else if (c === '[') { + const close: number = matchingClose(line, i); + if (close === -1) { + advanced = false; + } else { + i = close; + chained = true; + } + } else { + advanced = false; + } + } + if (chained && start <= character && character <= i) { + tokenStart = start; + tokenEnd = i; + break; + } + i = chained && i > start ? i : start + 1; + } + if (tokenStart === -1) { + return undefined; + } + + const leadingMatch: RegExpMatchArray | null = line.substring(tokenStart, tokenEnd).match(/^[*&]+/u); + const leading: string | null = leadingMatch !== null ? leadingMatch[0] : null; + const exprStart: number = tokenStart + (leading !== null ? leading.length : 0); + + // A chain can begin with `.` or `->` when its head was skipped (e.g. a call: `foo().bar` leaves + // `.bar`). Such a fragment is not a valid expression, so decline it. + if (line[exprStart] === '.' || (line[exprStart] === '-' && line[exprStart + 1] === '>')) { + return undefined; + } + + // On a subscript bracket, evaluate the indexed element: the subscripted primary through that + // subscript, without the leading `*`/`&`. + const cursorChar: string = line.charAt(character); + if (cursorChar === '[' || cursorChar === ']') { + const open: number = cursorChar === '[' ? character : matchingOpen(line, character); + const close: number = cursorChar === '[' ? matchingClose(line, character) : character + 1; + if (open !== -1 && close !== -1) { + let startColumn: number = Math.max(primaryStart(line, open, exprStart), exprStart); + // Keep a leading `*` when the subscript is the final segment (the dereferenced + // element, e.g. `*a.b[i]`); a leading `&`, or an interior subscript, drops it. + if (close === tokenEnd && startColumn === exprStart && leading !== null && /^\*+$/u.test(leading)) { + startColumn = tokenStart; + } + return { startColumn, endColumn: close, expression: line.substring(startColumn, close) }; + } + } + + // Locate the identifier under the cursor and the offset just past it. + let clipEnd: number = tokenEnd; + let wordStart: number = tokenStart; + let word: string = ''; + const wordRegExp: RegExp = /[\p{L}\p{N}_]+/gu; + const tokenText: string = line.substring(tokenStart, tokenEnd); + for (let w: RegExpExecArray | null = wordRegExp.exec(tokenText); w !== null; w = wordRegExp.exec(tokenText)) { + clipEnd = tokenStart + w.index + w[0].length; + wordStart = tokenStart + w.index; + word = w[0]; + if (clipEnd >= character) { + break; + } + } + + // An identifier inside a `[...]` is the index; it is evaluated on its own. Inside `[...]` the + // chain also spans operators and whitespace (e.g. `a[i + j]`), so only return the identifier + // when the cursor is actually on it; other positions are not tokens. + let depth: number = 0; + for (let k: number = tokenStart; k < character; k++) { + if (line[k] === '[') { + depth++; + } else if (line[k] === ']') { + depth--; + } + } + if (depth > 0) { + if (character < wordStart || character >= clipEnd) { + return undefined; + } + return { startColumn: wordStart, endColumn: clipEnd, expression: word }; + } + + // Past the last identifier but still on the token's trailing `]` (or its inclusive trailing + // edge), with no identifier left between the cursor and the end: evaluate the indexed + // element, like hovering that closing bracket, so the clip never cuts a subscript in half. + if (line.charAt(tokenEnd - 1) === ']' && !/[\p{L}\p{N}_]/u.test(line.substring(character, tokenEnd))) { + const open: number = matchingOpen(line, tokenEnd - 1); + if (open !== -1) { + let startColumn: number = Math.max(primaryStart(line, open, exprStart), exprStart); + if (startColumn === exprStart && leading !== null && /^\*+$/u.test(leading)) { + startColumn = tokenStart; + } + return { startColumn, endColumn: tokenEnd, expression: line.substring(startColumn, tokenEnd) }; + } + } + + // The leading `*`/`&` belongs to the final segment of the chain. A `*` is kept only when the + // cursor is on that final segment (the value actually dereferenced, e.g. `*a.b.c`). On any + // interior segment it is dropped, since `*a.b` would dereference the struct `a.b` and `*a.b[i]` + // the array base rather than the indexed element. A leading `&` is always dropped so hovering + // the variable shows its value, not its address. + const keepLeading: boolean = leading !== null && clipEnd >= tokenEnd && /^\*+$/u.test(leading); + if (!keepLeading) { + return { startColumn: exprStart, endColumn: clipEnd, expression: line.substring(exprStart, clipEnd) }; + } + return { startColumn: tokenStart, endColumn: clipEnd, expression: line.substring(tokenStart, clipEnd) }; +} diff --git a/Extension/src/Debugger/evaluatableExpressionProvider.ts b/Extension/src/Debugger/evaluatableExpressionProvider.ts new file mode 100755 index 000000000..fd04d1da7 --- /dev/null +++ b/Extension/src/Debugger/evaluatableExpressionProvider.ts @@ -0,0 +1,18 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. + * See 'LICENSE' in the project root for license information. + * ------------------------------------------------------------------------------------------ */ +import * as vscode from 'vscode'; +import { computeEvaluatableExpression, EvaluatableExpressionInfo } from './evaluatableExpression'; + +// Provides the expression a C/C++ debug data-tip evaluates when hovering a variable. The actual +// computation lives in `evaluatableExpression.ts` (no vscode dependency) so it can be unit tested. +export class EvaluatableExpressionProvider implements vscode.EvaluatableExpressionProvider { + public provideEvaluatableExpression(document: vscode.TextDocument, position: vscode.Position): vscode.ProviderResult { + const info: EvaluatableExpressionInfo | undefined = computeEvaluatableExpression(document.lineAt(position.line).text, position.character); + if (info === undefined) { + return undefined; + } + return new vscode.EvaluatableExpression(new vscode.Range(position.line, info.startColumn, position.line, info.endColumn), info.expression); + } +} diff --git a/Extension/src/Debugger/extension.ts b/Extension/src/Debugger/extension.ts index f784c1382..780fa121b 100644 --- a/Extension/src/Debugger/extension.ts +++ b/Extension/src/Debugger/extension.ts @@ -14,13 +14,14 @@ import { SshTargetsProvider, getActiveSshTarget, initializeSshTargets, selectSsh import { TargetLeafNode, setActiveSshTarget } from '../SSH/TargetsView/targetNodes'; import { sshCommandToConfig } from '../SSH/sshCommandToConfig'; import { getSshConfiguration, getSshConfigurationFiles, parseFailures, writeSshConfiguration } from '../SSH/sshHosts'; -import { pathAccessible } from '../common'; +import { documentSelector, pathAccessible } from '../common'; import { instrument } from '../instrumentation'; import { getSshChannel } from '../logger'; import { AttachItemsProvider, AttachPicker, RemoteAttachPicker } from './attachToProcess'; import { ConfigurationAssetProviderFactory, ConfigurationSnippetProvider, DebugConfigurationProvider, IConfigurationAssetProvider } from './configurationProvider'; import { DebuggerType } from './configurations'; import { CppdbgDebugAdapterDescriptorFactory, CppvsdbgDebugAdapterDescriptorFactory } from './debugAdapterDescriptorFactory'; +import { EvaluatableExpressionProvider } from './evaluatableExpressionProvider'; import { NativeAttachItemsProviderFactory } from './nativeAttach'; // The extension deactivate method is asynchronous, so we handle the disposables ourselves instead of using extensionContext.subscriptions. @@ -82,6 +83,9 @@ export async function initialize(context: vscode.ExtensionContext): Promise { + it('returns undefined when the cursor is not on a token', () => { + strictEqual(evaluate('a + | b'), undefined); + }); + + it('evaluates a plain identifier', () => { + strictEqual(evaluate('|x'), 'x'); + }); + + it('drops a leading * for an interior member of a dot chain', () => { + strictEqual(evaluate('*|a.b.c'), 'a'); + strictEqual(evaluate('*a.|b.c'), 'a.b'); + }); + + it('keeps a leading * on the final member', () => { + strictEqual(evaluate('*a.b.|c'), '*a.b.c'); + }); + + it('drops a leading * on an interior member before -> and keeps it on the final member', () => { + strictEqual(evaluate('*|ptr->member'), 'ptr'); + strictEqual(evaluate('*ptr->|member'), '*ptr->member'); + }); + + it('drops a leading * before a subscript (the array base is not the dereferenced value)', () => { + strictEqual(evaluate('*a.|b[i]'), 'a.b'); + strictEqual(evaluate('*dbbolz.|nullzwang_ok[DBBOLZ_A_AUS]'), 'dbbolz.nullzwang_ok'); + }); + + it('drops a leading & so the variable shows its value, not its address', () => { + strictEqual(evaluate('&|nullzwang_ok'), 'nullzwang_ok'); + strictEqual(evaluate('&a.b.|c'), 'a.b.c'); + }); + + it('leaves -> chains without a leading operator unchanged', () => { + strictEqual(evaluate('p->|q->r'), 'p->q'); + strictEqual(evaluate('p->q->|r'), 'p->q->r'); + }); + + it('keeps array subscripts in the chain', () => { + strictEqual(evaluate('a.|b[i].c'), 'a.b'); + strictEqual(evaluate('a.b[i].|c'), 'a.b[i].c'); + strictEqual(evaluate('dbbolz.dbbolz_anst[out_idx].|anw_dig'), 'dbbolz.dbbolz_anst[out_idx].anw_dig'); + strictEqual(evaluate('dbbolz.dbbolz_anst[out_idx].anw_dig.|stsdig'), 'dbbolz.dbbolz_anst[out_idx].anw_dig.stsdig'); + }); + + it('evaluates the element when on a subscript bracket, without the leading operator', () => { + strictEqual(evaluate('a.b|[i].c'), 'a.b[i]'); + strictEqual(evaluate('a.b[i|].c'), 'a.b[i]'); + strictEqual(evaluate('&dbbolz.dbbolz_anst[out_idx].fg|[kanal_idx]'), 'dbbolz.dbbolz_anst[out_idx].fg[kanal_idx]'); + }); + + it('evaluates the index on its own when inside a subscript', () => { + strictEqual(evaluate('a.b[|i].c'), 'i'); + strictEqual(evaluate('&dbbolz.dbbolz_anst[out_idx].fg[|kanal_idx]'), 'kanal_idx'); + }); + + it('keeps :: scoped names together', () => { + strictEqual(evaluate('ns::|var'), 'ns::var'); + strictEqual(evaluate('ns::var::|z'), 'ns::var::z'); + }); + + it('returns undefined for a fragment that begins with a connector', () => { + // The head of the expression (a call) is skipped by the tokenizer, leaving a `.`/`->` start. + strictEqual(evaluate('foo().|bar'), undefined); + strictEqual(evaluate('obj->fn()->|field'), undefined); + strictEqual(evaluate('(*this).|member'), undefined); + }); + + it('returns undefined when the cursor is on an operator or space inside a subscript', () => { + strictEqual(evaluate('a[i |+ j].c'), undefined); + strictEqual(evaluate('a[i +| j].c'), undefined); + strictEqual(evaluate('a[i +|j].c'), 'j'); + strictEqual(evaluate('a[i|+1].c'), undefined); + }); + + it('treats nested subscripts as balanced brackets', () => { + strictEqual(evaluate('a|[b[i]]'), 'a[b[i]]'); + strictEqual(evaluate('a[b|[i]]'), 'b[i]'); + strictEqual(evaluate('a[b[|i]]'), 'i'); + strictEqual(evaluate('a[b[i]|]'), 'a[b[i]]'); + }); + + it('keeps a trailing subscript whole when hovering past the last identifier', () => { + strictEqual(evaluate('a[i]|'), 'a[i]'); + strictEqual(evaluate('*a.b[i]|'), '*a.b[i]'); + }); + + it('keeps a leading * on a final subscript element but drops it on an interior one', () => { + strictEqual(evaluate('*a.b|[i]'), '*a.b[i]'); + strictEqual(evaluate('*a.b[i|]'), '*a.b[i]'); + strictEqual(evaluate('*a.b|[i].c'), 'a.b[i]'); + strictEqual(evaluate('&a|[i]'), 'a[i]'); + }); + + it('does not grab the whole element when hovering an interior connector', () => { + strictEqual(evaluate('*x|.y[i]'), 'x'); + strictEqual(evaluate('*dbbolz|.nullzwang_ok[DBBOLZ_A_AUS]'), 'dbbolz'); + }); +}); From 44a962969d6ad4a9add715d4043b76bebe832edb Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Thu, 2 Jul 2026 18:20:51 -0700 Subject: [PATCH 11/12] Update changelog and version for 1.33.3. (#14562) --- Extension/CHANGELOG.md | 14 +++++++++++++- Extension/package.json | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 13757a930..f028025b6 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,9 +1,21 @@ # C/C++ for Visual Studio Code Changelog +## Version 1.33.3: July 6, 2026 +### Enhancement +* Allow platform overrides in `cppbuild` tasks. [#11601](https://github.com/microsoft/vscode-cpptools/issues/11601) + +### Bug Fixes +* Fix `[[no_unique_address]]` empty-base layout `sizeof` being computed too large. [#14524](https://github.com/microsoft/vscode-cpptools/issues/14524) +* Fix C/C++ debug data-tips on members of a dereferenced expression. [PR #14540](https://github.com/microsoft/vscode-cpptools/pull/14540) + * Thanks for the contribution. [@tieo](https://github.com/tieo) +* Fix `clang-format`/`clang-tidy` version check failing on Windows. [PR #14552](https://github.com/microsoft/vscode-cpptools/pull/14552) +* Fix Windows backslash paths being mangled when adding an SSH target. [PR #14554](https://github.com/microsoft/vscode-cpptools/pull/14554) +* Fix "directory_cache" crashes. +* Fix spurious IntelliSense error on `std::variant` brace-initialization. + ## Version 1.33.2: June 26, 2026 ### Bug Fixes * Fix a regression with 'Find All References' with functions that exist in both C and C++ files. [#14546](https://github.com/microsoft/vscode-cpptools/issues/14546) -* Fix some regression crashes. ## Version 1.33.1: June 23, 2026 ### Bug Fixes diff --git a/Extension/package.json b/Extension/package.json index 24df79369..41abfff67 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -2,7 +2,7 @@ "name": "cpptools", "displayName": "C/C++", "description": "C/C++ IntelliSense, debugging, and code browsing.", - "version": "1.33.2-main", + "version": "1.33.3-main", "publisher": "ms-vscode", "icon": "LanguageCCPP_color_128x.png", "readme": "README.md", @@ -7266,4 +7266,4 @@ "uuid": "^11.1.1", "undici": "^7.28.0" } -} +} \ No newline at end of file From d686c15de1a3b0b5e2bdb13863d63900ffc2ac0f Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Thu, 2 Jul 2026 18:54:38 -0700 Subject: [PATCH 12/12] Add .vscode/settings.json to .gitignore. (#14563) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d2a8df0e9..89defab0e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ OneLocBuild # ignore imported localization xlf directory vscode-translations-import + +.vscode/settings.json