diff --git a/.github/actions/package-lock.json b/.github/actions/package-lock.json index d72b57351..17ef37017 100644 --- a/.github/actions/package-lock.json +++ b/.github/actions/package-lock.json @@ -4302,9 +4302,9 @@ "license": "ISC" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg=", + "version": "4.3.2", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { diff --git a/.github/workflows/job-compile-and-test.yml b/.github/workflows/job-compile-and-test.yml index 0ccd4b3b4..3b693283b 100644 --- a/.github/workflows/job-compile-and-test.yml +++ b/.github/workflows/job-compile-and-test.yml @@ -25,56 +25,56 @@ jobs: runs-on: ${{ inputs.runner-env }} steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.checkout-ref }} - name: Use Node.js 24 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 - - name: Validate Yarn lockfile - run: yarn test-yarn-lock && yarn verify-yarn-lock - working-directory: Extension - - - name: Validate LLDB-MI component manifest - run: yarn test-lldb-mi-component-manifest && yarn verify-lldb-mi-component-manifest - working-directory: Extension - + - name: Validate Yarn lockfile + run: yarn test-yarn-lock && yarn verify-yarn-lock + working-directory: Extension + + - name: Validate LLDB-MI component manifest + run: yarn test-lldb-mi-component-manifest && yarn verify-lldb-mi-component-manifest + working-directory: Extension + - name: Install Dependencies - shell: bash - env: - YARN_ARGS: ${{ inputs.yarn-args }} - run: | - read -r -a yarn_args <<< "$YARN_ARGS" - for attempt in 1 2 3; do - if yarn install "${yarn_args[@]}"; then - exit 0 - fi - if (( attempt == 3 )); then - exit 1 - fi - delay=$((attempt * 15)) - printf 'yarn install failed; retrying in %d seconds.\n' "$delay" >&2 - sleep "$delay" - done + shell: bash + env: + YARN_ARGS: ${{ inputs.yarn-args }} + run: | + read -r -a yarn_args <<< "$YARN_ARGS" + for attempt in 1 2 3; do + if yarn install "${yarn_args[@]}"; then + exit 0 + fi + if (( attempt == 3 )); then + exit 1 + fi + delay=$((attempt * 15)) + printf 'yarn install failed; retrying in %d seconds.\n' "$delay" >&2 + sleep "$delay" + done working-directory: Extension - name: Install gdb (linux) if: ${{ inputs.platform == 'linux' }} - timeout-minutes: 10 + timeout-minutes: 10 run: | - sudo apt-get \ - -o Acquire::Retries=3 \ - -o Acquire::http::Timeout=30 \ - -o Acquire::https::Timeout=30 \ - update - sudo apt-get \ - -o Acquire::Retries=3 \ - -o Acquire::http::Timeout=30 \ - -o Acquire::https::Timeout=30 \ - install -y gdb + sudo apt-get \ + -o Acquire::Retries=3 \ + -o Acquire::http::Timeout=30 \ + -o Acquire::https::Timeout=30 \ + update + sudo apt-get \ + -o Acquire::Retries=3 \ + -o Acquire::http::Timeout=30 \ + -o Acquire::https::Timeout=30 \ + install -y gdb - name: Compile Sources run: yarn run compile @@ -88,6 +88,10 @@ jobs: run: yarn test working-directory: Extension + - name: Test VS Code acquisition + run: yarn test-vscode-acquisition + working-directory: Extension + - name: Acquire Native Binaries run: yarn install-and-copy-binaries-for-test working-directory: Extension @@ -97,11 +101,11 @@ jobs: run: yarn test --scenario=SingleRootProject working-directory: Extension - - name: Run SimpleCppProject tests (Windows) - if: ${{ inputs.platform == 'windows' }} - run: yarn test --scenario=SimpleCppProject - working-directory: Extension - + - name: Run SimpleCppProject tests (Windows) + if: ${{ inputs.platform == 'windows' }} + run: yarn test --scenario=SimpleCppProject + working-directory: Extension + - name: Run E2E IntelliSense features tests (Windows) if: ${{ inputs.platform == 'windows' }} run: yarn test --scenario=MultirootDeadlockTest @@ -122,13 +126,13 @@ jobs: run: yarn test --scenario=SingleRootProject working-directory: Extension - - name: Run SimpleCppProject tests (linux/macOS) - if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} - uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1.0.1 - with: - run: yarn test --scenario=SimpleCppProject - working-directory: Extension - + - name: Run SimpleCppProject tests (linux/macOS) + if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} + uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1.0.1 + with: + run: yarn test --scenario=SimpleCppProject + working-directory: Extension + - name: Run E2E IntelliSense features tests (linux/macOS) if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }} uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1.0.1 diff --git a/Extension/.scripts/installAndCopyBinaries.ts b/Extension/.scripts/installAndCopyBinaries.ts index 4eb6a4054..5e51fc3fb 100644 --- a/Extension/.scripts/installAndCopyBinaries.ts +++ b/Extension/.scripts/installAndCopyBinaries.ts @@ -6,17 +6,13 @@ import { runVSCodeCommand } from '@vscode/test-electron'; import { writeFile } from 'node:fs/promises'; import { join } from 'node:path'; -import { $root, error, heading, note, warn } from './common'; +import { $root, heading, note, warn } 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); diff --git a/Extension/.scripts/vscode.test.mjs b/Extension/.scripts/vscode.test.mjs new file mode 100644 index 000000000..1feb17934 --- /dev/null +++ b/Extension/.scripts/vscode.test.mjs @@ -0,0 +1,205 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { mkdtempSync, rmSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import process from 'node:process'; +import test from 'node:test'; +import { fileURLToPath, URL } from 'node:url'; + +const require = createRequire(import.meta.url); +const extensionRoot = fileURLToPath(new URL('../', import.meta.url)); + +require('ts-node').register({ + project: fileURLToPath(new URL('tsconfig.json', import.meta.url)), + transpileOnly: true +}); +const proxyquire = require('proxyquire').noCallThru(); +const sinon = require('sinon'); +const { TimeoutError } = require('@vscode/test-electron/out/request'); + +function networkError(code) { + return Object.assign(new Error('Controlled acquisition failure'), { code }); +} + +function createInstaller() { + const download = sinon.stub().resolves('test-executable'); + const resolveCli = sinon.stub().returns(['test-cli', '--existing-argument', '--extensions-dir=default', '--user-data-dir=default']); + const wait = sinon.stub().resolves(); + const mkdir = sinon.stub().resolves(); + const write = sinon.stub().resolves(); + const warn = sinon.stub(); + const installer = proxyquire(fileURLToPath(new URL('vscode.ts', import.meta.url)), { + '@vscode/test-electron': { downloadAndUnzipVSCode: download, resolveCliArgsFromVSCodeExecutablePath: resolveCli }, + 'timers/promises': { setTimeout: wait }, + '../src/Utility/Text/streams': { verbose: sinon.stub() }, + './common': { mkdir, write, warn, readJson: sinon.stub().resolves({}) }, + './vscodeTestPath': { getVSCodeTestIsolate: () => join(tmpdir(), 'cpptools-acquisition-unit') } + }); + return { ...installer, download, resolveCli, wait, mkdir, write, warn }; +} + +test('successful acquisition preserves the version, cache and CLI arguments without retries', async () => { + const installer = createInstaller(); + const result = await installer.install(); + + assert.equal(installer.download.callCount, 1); + assert.equal(installer.download.firstCall.args[0], installer.options); + assert.equal(installer.options.version, installer.testVSCodeVersion); + assert.equal(installer.options.cachePath, `${installer.isolated}/cache`); + assert.deepEqual(result, { + cli: 'test-cli', + args: ['--existing-argument', `--extensions-dir=${installer.extensionsDir}`, `--user-data-dir=${installer.userDir}`] + }); + assert.equal(installer.wait.callCount, 0); + assert.equal(installer.warn.callCount, 0); + assert.equal(installer.write.callCount, 1); +}); + +for (const code of ['EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTUNREACH', 'ENETUNREACH', 'EPIPE', 'ETIMEDOUT']) { + test(`retries ${code} once before a successful acquisition`, async () => { + const installer = createInstaller(); + installer.download.onFirstCall().rejects(networkError(code)); + + await installer.install(); + + assert.equal(installer.download.callCount, 2); + assert.ok(installer.download.getCalls().every(call => call.args[0] === installer.options)); + assert.deepEqual(installer.wait.args, [[1000]]); + assert.equal(installer.warn.callCount, 1); + assert.equal(installer.mkdir.callCount, 1); + assert.equal(installer.write.callCount, 1); + }); +} + +test('retries the test-electron request timeout', async () => { + const installer = createInstaller(); + installer.download.onFirstCall().rejects(new TimeoutError(15000)); + + await installer.install(); + + assert.equal(installer.download.callCount, 2); + assert.deepEqual(installer.wait.args, [[1000]]); +}); + +test('exhausts transient aggregate errors after three attempts with bounded backoff', async () => { + const installer = createInstaller(); + installer.download.rejects(new AggregateError([networkError('ETIMEDOUT'), networkError('ENETUNREACH')])); + + await assert.rejects(installer.install(), /after 3 attempts: ETIMEDOUT:.*ENETUNREACH:/); + + assert.equal(installer.download.callCount, 3); + assert.deepEqual(installer.wait.args, [[1000], [2000]]); + assert.equal(installer.warn.callCount, 2); + assert.equal(installer.resolveCli.callCount, 0); + assert.equal(installer.write.callCount, 0); +}); + +for (const [name, failure] of [ + ['an invalid version', new Error('Invalid version')], + ['a permissions error', networkError('EACCES')], + ['a full disk', networkError('ENOSPC')], + ['a certificate error', networkError('CERT_HAS_EXPIRED')], + ['the library exhausting its archive retries', new Error('Failed to download and unzip VS Code 1.131.0')], + ['an unclassified HTTP failure', 'Failed to get JSON'], + ['an empty aggregate error', new AggregateError([])], + ['an aggregate containing a permanent error', new AggregateError([networkError('ETIMEDOUT'), networkError('EACCES')])] +]) { + test(`does not retry ${name}`, async () => { + const installer = createInstaller(); + installer.download.callsFake(async () => { throw failure; }); + + await assert.rejects(installer.install(), /Failed to install VS Code:.*after 1 attempt/); + + assert.equal(installer.download.callCount, 1); + assert.equal(installer.wait.callCount, 0); + assert.equal(installer.warn.callCount, 0); + assert.equal(installer.resolveCli.callCount, 0); + assert.equal(installer.write.callCount, 0); + }); +} + +test('does not retry installation work after acquisition succeeds', async () => { + const installer = createInstaller(); + installer.write.rejects(networkError('EPIPE')); + + await assert.rejects(installer.install(), /Failed to install VS Code/); + + assert.equal(installer.download.callCount, 1); + assert.equal(installer.write.callCount, 1); + assert.equal(installer.wait.callCount, 0); +}); + +for (const [name, code, attempts, delays] of [ + ['a non-retryable failure', 'EACCES', 1, []], + ['exhausted transient failures', 'ETIMEDOUT', 3, [1000, 2000]] +]) { + test(`acquisition CLI exits 1 without downstream work after ${name}`, () => { + const testRoot = mkdtempSync(join(tmpdir(), 'cpptools-acquisition-')); + const preload = ` + import { EventEmitter } from 'node:events'; + import { createRequire } from 'node:module'; + import process from 'node:process'; + const require = createRequire(${JSON.stringify(import.meta.url)}); + require('https').get = () => { + process.stdout.write('ACQUISITION_ATTEMPT\\n'); + const request = new EventEmitter(); + request.destroy = () => request; + process.nextTick(() => { + const failure = Object.assign(new Error('Controlled VS Code acquisition failure'), { code: '${code}' }); + request.emit('error', '${code}' === 'ETIMEDOUT' + ? new AggregateError([failure, Object.assign(new Error('Controlled IPv6 failure'), { code: 'ENETUNREACH' })]) + : failure); + }); + return request; + }; + require('timers/promises').setTimeout = async (milliseconds) => { + process.stdout.write('ACQUISITION_DELAY:' + milliseconds + '\\n'); + }; + const electronPath = require.resolve('@vscode/test-electron'); + const electron = require(electronPath); + require.cache[electronPath].exports = { + ...electron, + async runVSCodeCommand() { + throw new Error('Unexpected extension installation'); + } + }; + const copyPath = require.resolve('./copyExtensionBinaries.ts'); + require.cache[copyPath] = { + id: copyPath, + filename: copyPath, + loaded: true, + exports: { + async main() { + throw new Error('Unexpected binary copying'); + } + } + }; + `; + + try { + const result = spawnSync(process.execPath, [ + '--import', `data:text/javascript,${encodeURIComponent(preload)}`, + require.resolve('ts-node/dist/bin.js'), '-T', '.scripts/installAndCopyBinaries.ts' + ], { + cwd: extensionRoot, + env: { ...process.env, CPPTOOLS_VSCODE_TEST_ROOT: testRoot }, + encoding: 'utf8', + timeout: 15000 + }); + + assert.ifError(result.error); + assert.equal(result.signal, null); + const output = result.stdout + result.stderr; + assert.match(output, /Controlled VS Code acquisition failure/); + assert.match(output, new RegExp(`acquisition failed after ${attempts} attempt`)); + assert.equal(output.match(/^ACQUISITION_ATTEMPT$/gm)?.length, attempts); + assert.deepEqual([...output.matchAll(/^ACQUISITION_DELAY:(\d+)$/gm)].map(match => Number(match[1])), delays); + assert.doesNotMatch(output, /Install latest C\/C\+\+ Extension|Unexpected extension installation|Unexpected binary copying/); + assert.equal(result.status, 1, output); + } finally { + rmSync(testRoot, { recursive: true, force: true }); + } + }); +} diff --git a/Extension/.scripts/vscode.ts b/Extension/.scripts/vscode.ts index 18bd8bbc3..5ee642bd6 100644 --- a/Extension/.scripts/vscode.ts +++ b/Extension/.scripts/vscode.ts @@ -5,8 +5,9 @@ import { downloadAndUnzipVSCode, resolveCliArgsFromVSCodeExecutablePath } from '@vscode/test-electron'; import { resolve } from 'path'; +import { setTimeout as delay } from 'timers/promises'; import { verbose } from '../src/Utility/Text/streams'; -import { mkdir, readJson, rimraf, write } from './common'; +import { mkdir, readJson, rimraf, warn, write } from './common'; import { getVSCodeTestIsolate } from './vscodeTestPath'; export const isolated = getVSCodeTestIsolate(__dirname); @@ -24,6 +25,43 @@ export const options = { launchArgs: ['--no-sandbox', '--disable-updates', '--skip-welcome', '--skip-release-notes', '--disable-extensions', `--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`, '--disable-workspace-trust'] }; +const transientNetworkErrors = new Set(['EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTUNREACH', 'ENETUNREACH', 'EPIPE', 'ETIMEDOUT']); + +function isRetryableAcquisitionError(err: unknown): boolean { + if (err instanceof AggregateError) { + return err.errors.length > 0 && err.errors.every(isRetryableAcquisitionError); + } + return err instanceof Error && (err.constructor.name === 'TimeoutError' + || ('code' in err && typeof err.code === 'string' && transientNetworkErrors.has(err.code))); +} + +function describeAcquisitionError(err: unknown): string { + if (err instanceof AggregateError) { + return err.errors.map(describeAcquisitionError).join('; ') || err.message; + } + if (err instanceof Error) { + return 'code' in err ? `${err.code}: ${err.message}` : err.message; + } + return String(err); +} + +async function downloadVSCode(): Promise { + const maxAttempts = 3; + for (let attempt = 1; ; attempt++) { + try { + return await downloadAndUnzipVSCode(options); + } catch (err: unknown) { + const details = describeAcquisitionError(err); + if (attempt === maxAttempts || !isRetryableAcquisitionError(err)) { + throw new Error(`VS Code ${options.version} acquisition failed after ${attempt} ${attempt === 1 ? 'attempt' : 'attempts'}: ${details}`, { cause: err }); + } + const delayMs = 1000 * 2 ** (attempt - 1); + warn(`VS Code acquisition attempt ${attempt}/${maxAttempts} failed: ${details}. Retrying in ${delayMs} ms.`); + await delay(delayMs); + } + } +} + export async function install() { try { // Create a new isolated directory for VS Code instance in the test folder, and make it specific to the extension folder so we can avoid collisions. @@ -32,7 +70,7 @@ export async function install() { verbose(`Isolated VSCode test folder: ${isolated}`); await mkdir(isolated); - const vscodeExecutablePath = await downloadAndUnzipVSCode(options); + const vscodeExecutablePath = await downloadVSCode(); const [cli, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath).filter(each => !each.startsWith('--extensions-dir=') && !each.startsWith('--user-data-dir=')); args.push(`--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`); @@ -54,7 +92,7 @@ export async function install() { }; } catch (err: unknown) { - console.log(err); + throw new Error(`Failed to install VS Code: ${err instanceof Error ? err.message : String(err)}`, { cause: err }); } } diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 1d3ad7e28..6f425af52 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,5 +1,26 @@ # C/C++ for Visual Studio Code Changelog +## Version 1.35.1: September 14, 2026 +### New Feature +* Add the 'Select a Translation Unit...' command to choose which source file provides IntelliSense context for the active header file. [PR #14688](https://github.com/microsoft/vscode-cpptools/pull/14688) + +### Enhancements +* Improve IntelliSense configuration lookup performance for symbolic links to `compile_commands.json`. +* Update the bundled `clang-tidy` and `clang-format` from 23.1.0 to 23.1.1. +* Improve performance when pruning large IntelliSense caches. + +### Bug Fixes +* Fix `/U` and `-U` compiler arguments not undefining macros for IntelliSense and code analysis. [#13786](https://github.com/microsoft/vscode-cpptools/issues/13786) +* Fix excessive CPU usage by idle parser workers while workspace parsing is still running. [#14757](https://github.com/microsoft/vscode-cpptools/issues/14757) +* Remove the obsolete `C_Cpp.default.recursiveIncludes.reduce` setting and its configuration UI control. [PR #14761](https://github.com/microsoft/vscode-cpptools/pull/14761) +* Fix missing or stale IntelliSense configurations when `compile_commands.json` is created after startup, changed, deleted, or accessed through symbolic links, including in multi-root workspaces. +* Fix missing `cp1125` support on all platforms, unsupported file encodings on Linux, and incorrect GB18030 decoding on Linux and macOS. +* Fix recursive include lookup sometimes selecting the wrong header when directories are reached through multiple symbolic links. +* Fix a potential language server deadlock during workspace initialization and concurrent document edits. +* Fix an IntelliSense crash when parsing templates in Clang mode. +* Fix a `cpptools` crash during shutdown on macOS. +* Update dependencies. + ## Version 1.35.0: September 10, 2026 ### Enhancement * Improve workspace indexing performance. diff --git a/Extension/package.json b/Extension/package.json index 38df2d105..63ce49586 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.35.0-main", + "version": "1.35.1-main", "publisher": "ms-vscode", "icon": "LanguageCCPP_color_128x.png", "readme": "README.md", @@ -1359,17 +1359,6 @@ "markdownDescription": "%c_cpp.configuration.default.dotConfig.markdownDescription%", "scope": "resource" }, - "C_Cpp.default.recursiveIncludes.reduce": { - "type": "string", - "enum": [ - "", - "always", - "never", - "default" - ], - "markdownDescription": "%c_cpp.configuration.default.recursiveIncludes.reduce.markdownDescription%", - "scope": "resource" - }, "C_Cpp.default.recursiveIncludes.priority": { "type": "string", "enum": [ @@ -3990,6 +3979,11 @@ "title": "%c_cpp.command.switchHeaderSource.title%", "category": "C/C++" }, + { + "command": "C_Cpp.SelectTranslationUnit", + "title": "%c_cpp.command.selectTranslationUnit.title%", + "category": "C/C++" + }, { "command": "C_Cpp.EnableErrorSquiggles", "title": "%c_cpp.command.enableErrorSquiggles.title%", @@ -6542,6 +6536,10 @@ "command": "C_Cpp.SwitchHeaderSource", "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && !(config.C_Cpp.intelliSenseEngine =~ /^[dD]isabled$/)" }, + { + "command": "C_Cpp.SelectTranslationUnit", + "when": "editorLangId =~ /^(c|(cuda-)?cpp)$/ && config.C_Cpp.intelliSenseEngine =~ /^[dD]efault$/" + }, { "command": "C_Cpp.EnableErrorSquiggles", "when": "config.C_Cpp.intelliSenseEngine =~ /^[dD]efault$/" @@ -7170,6 +7168,7 @@ "show": "ts-node -T .scripts/clean.ts show", "clean": "ts-node -T .scripts/clean.ts", "test-lldb-mi-component-manifest": "node --test .scripts/verifyLldbMiComponentManifest.test.mjs", + "test-vscode-acquisition": "node --test .scripts/vscode.test.mjs", "test-yarn-lock": "node --test .scripts/verifyYarnLock.test.mjs", "verify-lldb-mi-component-manifest": "node .scripts/verifyLldbMiComponentManifest.mjs", "verify-yarn-lock": "node .scripts/verifyYarnLock.mjs", diff --git a/Extension/package.nls.json b/Extension/package.nls.json index c42e03e45..d10af1bcd 100644 --- a/Extension/package.nls.json +++ b/Extension/package.nls.json @@ -15,6 +15,7 @@ "c_cpp.command.installCompiler.title": "Install a C++ Compiler", "c_cpp.command.rescanCompilers.title": "Rescan for Compilers", "c_cpp.command.switchHeaderSource.title": "Switch Header/Source", + "c_cpp.command.selectTranslationUnit.title": "Select a Translation Unit...", "c_cpp.command.enableErrorSquiggles.title": "Enable Error Squiggles", "c_cpp.command.disableErrorSquiggles.title": "Disable Error Squiggles", "c_cpp.command.toggleDimInactiveRegions.title": "Toggle Inactive Region Colorization", @@ -732,12 +733,6 @@ "Markdown text between `` should not be translated or localized (they represent literal text) and the capitalization, spacing, and punctuation (including the ``) should not be altered." ] }, - "c_cpp.configuration.default.recursiveIncludes.reduce.markdownDescription": { - "message": "The value to use in a configuration if `recursiveIncludes.reduce` is either not specified or set to `${default}`.", - "comment": [ - "Markdown text between `` should not be translated or localized (they represent literal text) and the capitalization, spacing, and punctuation (including the ``) should not be altered." - ] - }, "c_cpp.configuration.default.recursiveIncludes.priority.markdownDescription": { "message": "The value to use in a configuration if `recursiveIncludes.priority` is either not specified or set to `${default}`.", "comment": [ diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 5e98f2859..ef459c05f 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -216,6 +216,16 @@ interface SwitchHeaderSourceParams extends WorkspaceFolderParams { switchHeaderSourceFileName: string; } +interface GetTranslationUnitSourceCandidatesResult { + candidates: string[]; + currentTranslationUnit: string; +} + +interface SelectTranslationUnitParams { + uri: string; + translationUnit: string; +} + interface FileChangedParams extends WorkspaceFolderParams { uri: string; } @@ -625,6 +635,7 @@ const PreInitializationRequest: RequestType = new RequestTyp const InitializationRequest: RequestType = new RequestType('cpptools/initialize'); const QueryCompilerDefaultsRequest: RequestType = new RequestType('cpptools/queryCompilerDefaults'); const SwitchHeaderSourceRequest: RequestType = new RequestType('cpptools/didSwitchHeaderSource'); +const GetTranslationUnitSourceCandidatesRequest: RequestType = new RequestType('cpptools/getTranslationUnitSourceCandidates'); const GetDiagnosticsRequest: RequestType = new RequestType('cpptools/getDiagnostics'); export const GetDocumentSymbolRequest: RequestType = new RequestType('cpptools/getDocumentSymbols'); export const GetSymbolInfoRequest: RequestType = new RequestType('cpptools/getWorkspaceSymbols'); @@ -653,6 +664,7 @@ const PauseParsingNotification: NotificationType = new NotificationType = new NotificationType('cpptools/resumeParsing'); const DidChangeActiveEditorNotification: NotificationType = new NotificationType('cpptools/didChangeActiveEditor'); const RestartIntelliSenseForFileNotification: NotificationType = new NotificationType('cpptools/restartIntelliSenseForFile'); +const SelectTranslationUnitNotification: NotificationType = new NotificationType('cpptools/selectTranslationUnit'); const DidChangeTextEditorSelectionNotification: NotificationType = new NotificationType('cpptools/didChangeTextEditorSelection'); const ChangeCompileCommandsNotification: NotificationType = new NotificationType('cpptools/didChangeCompileCommands'); const ChangeSelectedSettingNotification: NotificationType = new NotificationType('cpptools/didChangeSelectedSetting'); @@ -832,6 +844,8 @@ export interface Client { takeOwnership(document: vscode.TextDocument): void; sendDidOpen(document: vscode.TextDocument): Promise; requestSwitchHeaderSource(rootUri: vscode.Uri, fileName: string, token: vscode.CancellationToken): Thenable; + getTranslationUnitSourceCandidates(uri: vscode.Uri, token: vscode.CancellationToken): Promise; + selectTranslationUnit(uri: vscode.Uri, translationUnit: string): Promise; updateActiveDocumentTextOptions(): void; didChangeActiveEditor(editor?: vscode.TextEditor, selection?: Range): Promise; restartIntelliSenseForFile(document: vscode.TextDocument): Promise; @@ -3098,6 +3112,19 @@ export class DefaultClient implements Client { } } + public async getTranslationUnitSourceCandidates(uri: vscode.Uri, token: vscode.CancellationToken): Promise { + const params: TextDocumentIdentifier = { uri: uri.toString() }; + await withCancellation(this.ready, token); + return DefaultClient.withLspCancellationHandling( + () => this.languageClient.sendRequest(GetTranslationUnitSourceCandidatesRequest, params, token), token); + } + + public async selectTranslationUnit(uri: vscode.Uri, translationUnit: string): Promise { + const params: SelectTranslationUnitParams = { uri: uri.toString(), translationUnit }; + await this.ready; + return this.languageClient.sendNotification(SelectTranslationUnitNotification, params).catch(logAndReturn.undefined); + } + public async requestCompiler(newCompilerPath?: string): Promise { const params: QueryDefaultCompilerParams = { newTrustedCompilerPath: newCompilerPath ?? "" @@ -4470,6 +4497,10 @@ class NullClient implements Client { takeOwnership(document: vscode.TextDocument): void { } sendDidOpen(document: vscode.TextDocument): Promise { return Promise.resolve(); } requestSwitchHeaderSource(rootUri: vscode.Uri, fileName: string, token: vscode.CancellationToken): Thenable { return Promise.resolve(""); } + getTranslationUnitSourceCandidates(uri: vscode.Uri, token: vscode.CancellationToken): Promise { + return Promise.resolve({ candidates: [], currentTranslationUnit: "" }); + } + selectTranslationUnit(uri: vscode.Uri, translationUnit: string): Promise { return Promise.resolve(); } updateActiveDocumentTextOptions(): void { } didChangeActiveEditor(editor?: vscode.TextEditor): Promise { return Promise.resolve(); } restartIntelliSenseForFile(document: vscode.TextDocument): Promise { return Promise.resolve(); } diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index dbbe302e0..6d01647ec 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -113,7 +113,6 @@ export interface Browse { } export interface RecursiveIncludes { - reduce?: string; priority?: string; order?: string; } diff --git a/Extension/src/LanguageServer/extension.ts b/Extension/src/LanguageServer/extension.ts index 67a7d1720..6fee4dbd3 100644 --- a/Extension/src/LanguageServer/extension.ts +++ b/Extension/src/LanguageServer/extension.ts @@ -383,6 +383,7 @@ export async function registerCommands(enabled: boolean): Promise { commandDisposables.forEach(d => d.dispose()); commandDisposables.length = 0; commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SwitchHeaderSource', enabled ? onSwitchHeaderSource : onDisabledCommand)); + commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SelectTranslationUnit', enabled ? onSelectTranslationUnit : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ResetDatabase', enabled ? onResetDatabase : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SelectIntelliSenseConfiguration', enabled ? selectIntelliSenseConfiguration : onDisabledCommand)); commandDisposables.push(vscode.commands.registerCommand('C_Cpp.InstallCompiler', enabled ? installCompiler : onDisabledCommand)); @@ -468,6 +469,107 @@ async function onRestartIntelliSenseForFile() { return clients.ActiveClient.restartIntelliSenseForFile(activeEditor.document); } +function getEditorPath(fileName: string): string { + let bestRealRoot: string | undefined; + let bestRootPath: string | undefined; + clients.forEach(client => { + if (!client.RootRealPath) { + return; + } + const relativePath: string = path.relative(client.RootRealPath, fileName); + const isUnderRoot: boolean = relativePath === "" || + (relativePath !== ".." && !relativePath.startsWith(`..${path.sep}`) && !path.isAbsolute(relativePath)); + if (isUnderRoot && (!bestRealRoot || client.RootRealPath.length > bestRealRoot.length)) { + bestRealRoot = client.RootRealPath; + bestRootPath = client.RootPath; + } + }); + return bestRealRoot && bestRootPath ? path.join(bestRootPath, path.relative(bestRealRoot, fileName)) : fileName; +} + +interface TranslationUnitQuickPickItem extends vscode.QuickPickItem { + translationUnit: string; +} + +async function onSelectTranslationUnit(): Promise { + const activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; + if (!activeEditor || !util.isCpp(activeEditor.document)) { + return; + } + + const client: Client = clients.ActiveClient; + const result = await (async () => { + const tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); + try { + const candidatesPromise = client.getTranslationUnitSourceCandidates(activeEditor.document.uri, tokenSource.token); + const showProgress: boolean = await new Promise((resolve, reject) => { + const timer: NodeJS.Timeout = global.setTimeout(() => resolve(true), 2000); + void candidatesPromise.then(() => { + clearTimeout(timer); + resolve(false); + }, (e) => { + clearTimeout(timer); + reject(e); + }); + }); + + if (!showProgress) { + return await candidatesPromise; + } + + return await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize('find.translation.units', 'Finding Translation Units...'), + cancellable: true + }, async (_progress, token) => { + const cancellationListener: vscode.Disposable = token.onCancellationRequested(() => tokenSource.cancel()); + try { + return await candidatesPromise; + } finally { + cancellationListener.dispose(); + } + }); + } catch (e) { + if (e instanceof vscode.CancellationError) { + return undefined; + } + throw e; + } finally { + tokenSource.dispose(); + } + })(); + if (result === undefined) { + return; + } + if (result.candidates.length === 0) { + void vscode.window.showInformationMessage(localize('no.translation.units.found', 'No translation units were found for the active file.')); + return; + } + const currentTranslationUnit: string = getEditorPath(result.currentTranslationUnit); + const items: TranslationUnitQuickPickItem[] = result.candidates.map(candidate => { + const editorPath: string = getEditorPath(candidate); + const relativePath: string = vscode.workspace.asRelativePath(vscode.Uri.file(editorPath)); + const directory: string = path.dirname(relativePath); + const isCurrent: boolean = editorPath === currentTranslationUnit; + return { + label: `${isCurrent ? "$(check) " : ""}${path.basename(relativePath)}`, + description: isCurrent ? localize('current.translation.unit', 'Current translation unit') : + directory === "." ? undefined : directory, + detail: editorPath, + translationUnit: editorPath + }; + }); + const selection: TranslationUnitQuickPickItem | undefined = await vscode.window.showQuickPick(items, { + title: localize('select.translation.unit', 'Select a Translation Unit'), + placeHolder: localize('select.translation.unit.placeholder', 'Select a source file to use as the translation unit'), + matchOnDescription: true, + matchOnDetail: true + }); + if (selection !== undefined) { + await client.selectTranslationUnit(activeEditor.document.uri, selection.translationUnit); + } +} + async function onSwitchHeaderSource(): Promise { const activeEditor: vscode.TextEditor | undefined = vscode.window.activeTextEditor; if (!activeEditor || !util.isCpp(activeEditor.document)) { @@ -487,16 +589,7 @@ async function onSwitchHeaderSource(): Promise { if (!targetFileName) { return; } - // If the targetFileName has a path that is a symlink target of a workspace folder, - // then replace the RootRealPath with the RootPath (the symlink path). - let targetFileNameReplaced: boolean = false; - clients.forEach(client => { - if (!targetFileNameReplaced && client.RootRealPath && client.RootPath !== client.RootRealPath - && targetFileName.startsWith(client.RootRealPath)) { - targetFileName = client.RootPath + targetFileName.substring(client.RootRealPath.length); - targetFileNameReplaced = true; - } - }); + targetFileName = getEditorPath(targetFileName); const document: vscode.TextDocument = await vscode.workspace.openTextDocument(targetFileName); await vscode.window.showTextDocument(document).then(undefined, logAndReturn.undefined); } catch (e) { diff --git a/Extension/src/nativeStrings.json b/Extension/src/nativeStrings.json index 149887245..ffe091980 100644 --- a/Extension/src/nativeStrings.json +++ b/Extension/src/nativeStrings.json @@ -777,5 +777,13 @@ "browse_database_disabled_incompatible_storage": { "text": "The browse database was disabled because its storage location does not support SQLite WAL shared memory. Set browse.databaseFilename to a local path.", "hint": "browse.databaseFilename is a setting name. {Locked=\"SQLite WAL\"} {Locked=\"browse.databaseFilename\"}" + }, + "selected_translation_unit_not_include_file_previous": { + "text": "The selected translation unit '{0}' does not include '{1}'. IntelliSense will restore the previous translation unit if it is still available; otherwise, it will use '{1}' as a header-only translation unit.", + "hint": "{0} is the selected translation unit path. {1} is the active file path. {Locked=\"IntelliSense\"} {Locked=\"{0}\"} {Locked=\"{1}\"}" + }, + "selected_translation_unit_not_include_file_header_only": { + "text": "The selected translation unit '{0}' does not include '{1}'. No previous translation unit is available, so IntelliSense will use '{1}' as a header-only translation unit.", + "hint": "{0} is the selected translation unit path. {1} is the active file path. {Locked=\"IntelliSense\"} {Locked=\"{0}\"} {Locked=\"{1}\"}" } } diff --git a/Extension/ui/settings.html b/Extension/ui/settings.html index 5f1a25091..f1f6fb136 100644 --- a/Extension/ui/settings.html +++ b/Extension/ui/settings.html @@ -737,21 +737,6 @@ -
-
Recursive includes: reduce
-
- Set to always to reduce the number of recursive include paths provided to IntelliSense to only those paths currently referenced by #include statements. This requires first parsing files to determine which files are included. Set to never to provide all recursive include paths to IntelliSense. Reducing the number of recursive include paths may improve IntelliSense performance when a very large number of recursive include paths are involved. Not reducing the number of recursive include paths can improve IntelliSense performance by avoiding the need to parse files to determine which include paths to provide. -
-
- -
-
-
Recursive includes: priority
diff --git a/Extension/yarn.lock b/Extension/yarn.lock index 63151aa47..01892337f 100644 --- a/Extension/yarn.lock +++ b/Extension/yarn.lock @@ -3829,9 +3829,9 @@ js-tokens@^4.0.0: integrity "sha1-GSA/tZmR35jjoocFDUZHzerzJJk= sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" js-yaml@^4.1.0, js-yaml@^4.1.1: - version "4.3.1" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" - integrity "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg= sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==" + version "4.3.2" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz#8e44fb14a2643c59726bb15787b5f1512cb3d3fb" + integrity "sha1-jkT7FKJkPFlya7FXh7XxUSyz0/s= sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==" dependencies: argparse "^2.0.1" @@ -4894,11 +4894,12 @@ punycode@^2.1.0: integrity "sha1-AnQi4vrsCyXhVJw+G9gwm5EztuU= sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" qs@^6.9.1: - version "6.15.2" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.15.2.tgz#fd55426d710403ddccc45e0f9eab16db7727ece9" - integrity "sha1-/VVCbXEEA93MxF4PnqsW23cn7Ok= sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==" + version "6.16.0" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.16.0.tgz#c22c723a28a920f3aacdce8289fabd43eccb79fd" + integrity "sha1-wixyOiipIPOqzc6Cifq9Q+zLef0= sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==" dependencies: - side-channel "^1.1.0" + es-define-property "^1.0.1" + side-channel "^1.1.1" queue-microtask@^1.2.2: version "1.2.3" @@ -5283,13 +5284,13 @@ 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= sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" -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" - integrity "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0= sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==" +side-channel-list@^1.0.1: + version "1.0.1" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" + integrity "sha1-wuC1oUpUCuvuO7xsP4ZmzJtQkSc= sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==" dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" + object-inspect "^1.13.4" side-channel-map@^1.0.1: version "1.0.1" @@ -5312,14 +5313,14 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.1.0: - version "1.1.0" - resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" - integrity "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k= sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==" +side-channel@^1.1.0, side-channel@^1.1.1: + version "1.1.1" + resolved "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.1.tgz#ea02c62e05dc4bea67d4442f0fb71ee192f8e0ab" + integrity "sha1-6gLGLgXcS+pn1EQvD7ce4ZL44Ks= sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==" dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" + object-inspect "^1.13.4" + side-channel-list "^1.0.1" side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" diff --git a/ExtensionPack/package-lock.json b/ExtensionPack/package-lock.json index d7c5b73d7..67ed2bbf2 100644 --- a/ExtensionPack/package-lock.json +++ b/ExtensionPack/package-lock.json @@ -2097,9 +2097,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg=", + "version": "4.3.2", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { @@ -2869,13 +2869,14 @@ } }, "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.15.2.tgz", - "integrity": "sha1-/VVCbXEEA93MxF4PnqsW23cn7Ok=", + "version": "6.16.0", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -3129,15 +3130,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -3149,14 +3150,14 @@ } }, "node_modules/side-channel-list": { - "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", - "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" diff --git a/Themes/package-lock.json b/Themes/package-lock.json index 7c4e2fc01..e9a16705c 100644 --- a/Themes/package-lock.json +++ b/Themes/package-lock.json @@ -2097,9 +2097,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg=", + "version": "4.3.2", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { @@ -2869,13 +2869,14 @@ } }, "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.15.2.tgz", - "integrity": "sha1-/VVCbXEEA93MxF4PnqsW23cn7Ok=", + "version": "6.16.0", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -3129,15 +3130,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=", + "version": "1.1.1", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -3149,14 +3150,14 @@ } }, "node_modules/side-channel-list": { - "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", - "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=", + "version": "1.0.1", + "resolved": "https://pkgs.dev.azure.com/azure-public/VisualCpp/_packaging/cpp_PublicPackages/npm/registry/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4"