Repository: voideditor/void Branch: main Commit: 17e7a5b15243 Files: 8041 Total size: 103.7 MB Directory structure: gitextract_zxyiywqm/ ├── .config/ │ ├── 1espt/ │ │ └── PipelineAutobaseliningConfig.yml │ └── guardian/ │ ├── .gdnbaselines │ └── .gdnsuppress ├── .configurations/ │ └── configuration.dsc.yaml ├── .devcontainer/ │ ├── Dockerfile │ ├── README.md │ ├── devcontainer-lock.json │ ├── devcontainer.json │ ├── install-vscode.sh │ └── post-create.sh ├── .editorconfig ├── .eslint-ignore ├── .eslint-plugin-local/ │ ├── code-amd-node-module.ts │ ├── code-declare-service-brand.ts │ ├── code-ensure-no-disposables-leak-in-test.ts │ ├── code-import-patterns.ts │ ├── code-layering.ts │ ├── code-limited-top-functions.ts │ ├── code-must-use-result.ts │ ├── code-must-use-super-dispose.ts │ ├── code-no-dangerous-type-assertions.ts │ ├── code-no-global-document-listener.ts │ ├── code-no-native-private.ts │ ├── code-no-nls-in-standalone-editor.ts │ ├── code-no-potentially-unsafe-disposables.ts │ ├── code-no-runtime-import.ts │ ├── code-no-standalone-editor.ts │ ├── code-no-static-self-ref.ts │ ├── code-no-test-async-suite.ts │ ├── code-no-test-only.ts │ ├── code-no-unexternalized-strings.ts │ ├── code-no-unused-expressions.ts │ ├── code-parameter-properties-must-have-explicit-accessibility.ts │ ├── code-translation-remind.ts │ ├── index.js │ ├── package.json │ ├── tsconfig.json │ ├── utils.ts │ ├── vscode-dts-cancellation.ts │ ├── vscode-dts-create-func.ts │ ├── vscode-dts-event-naming.ts │ ├── vscode-dts-interface-naming.ts │ ├── vscode-dts-literal-or-types.ts │ ├── vscode-dts-provider-naming.ts │ ├── vscode-dts-string-type-literals.ts │ ├── vscode-dts-use-export.ts │ ├── vscode-dts-use-thenable.ts │ └── vscode-dts-vscode-in-comments.ts ├── .git-blame-ignore-revs ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── config.yml │ │ └── issue_template.md │ ├── scripts/ │ │ └── issue_triage.py │ └── workflows/ │ └── triage.yml ├── .gitignore ├── .idx/ │ └── dev.nix ├── .lsifrc.json ├── .mailmap ├── .mention-bot ├── .npmrc ├── .nvmrc ├── .voidrules ├── .vscode/ │ ├── cglicenses.schema.json │ ├── extensions/ │ │ ├── vscode-selfhost-import-aid/ │ │ │ ├── .vscode/ │ │ │ │ ├── launch.json │ │ │ │ └── settings.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── extension.ts │ │ │ └── tsconfig.json │ │ └── vscode-selfhost-test-provider/ │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── settings.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── coverageProvider.ts │ │ │ ├── debounce.ts │ │ │ ├── extension.ts │ │ │ ├── failingDeepStrictEqualAssertFixer.ts │ │ │ ├── failureTracker.ts │ │ │ ├── importGraph.ts │ │ │ ├── memoize.ts │ │ │ ├── metadata.ts │ │ │ ├── snapshot.ts │ │ │ ├── sourceUtils.ts │ │ │ ├── stackTraceParser.ts │ │ │ ├── streamSplitter.ts │ │ │ ├── testOutputScanner.ts │ │ │ ├── testTree.ts │ │ │ ├── v8CoverageWrangling.test.ts │ │ │ ├── v8CoverageWrangling.ts │ │ │ └── vscodeTestRunner.ts │ │ └── tsconfig.json │ ├── extensions.json │ ├── launch.json │ ├── notebooks/ │ │ ├── api.github-issues │ │ ├── endgame.github-issues │ │ ├── grooming-delta.github-issues │ │ ├── grooming.github-issues │ │ ├── inbox.github-issues │ │ ├── my-endgame.github-issues │ │ ├── my-work.github-issues │ │ ├── papercuts.github-issues │ │ ├── verification.github-issues │ │ └── vscode-dev.github-issues │ ├── searches/ │ │ └── ts36031.code-search │ ├── settings.json │ ├── shared.code-snippets │ └── tasks.json ├── .vscode-test.js ├── CodeQL.yml ├── HOW_TO_CONTRIBUTE.md ├── LICENSE-VS-Code.txt ├── LICENSE.txt ├── README.md ├── ThirdPartyNotices.txt ├── VOID_CODEBASE_GUIDE.md ├── build/ │ ├── .cachesalt │ ├── .gitattributes │ ├── .gitignore │ ├── .moduleignore │ ├── .moduleignore.darwin │ ├── .moduleignore.linux │ ├── .moduleignore.win32 │ ├── .npmrc │ ├── .webignore │ ├── azure-pipelines/ │ │ ├── alpine/ │ │ │ ├── cli-build-alpine.yml │ │ │ └── product-build-alpine.yml │ │ ├── cli/ │ │ │ ├── cli-apply-patches.yml │ │ │ ├── cli-compile.yml │ │ │ ├── cli-darwin-sign.yml │ │ │ ├── cli-win32-sign.yml │ │ │ ├── install-rust-posix.yml │ │ │ ├── install-rust-win32.yml │ │ │ └── test.yml │ │ ├── common/ │ │ │ ├── computeBuiltInDepsCacheKey.js │ │ │ ├── computeBuiltInDepsCacheKey.ts │ │ │ ├── computeNodeModulesCacheKey.js │ │ │ ├── computeNodeModulesCacheKey.ts │ │ │ ├── createBuild.js │ │ │ ├── createBuild.ts │ │ │ ├── extract-telemetry.sh │ │ │ ├── getPublishAuthTokens.js │ │ │ ├── getPublishAuthTokens.ts │ │ │ ├── install-builtin-extensions.yml │ │ │ ├── installPlaywright.js │ │ │ ├── listNodeModules.js │ │ │ ├── listNodeModules.ts │ │ │ ├── publish.js │ │ │ ├── publish.ts │ │ │ ├── releaseBuild.js │ │ │ ├── releaseBuild.ts │ │ │ ├── retry.js │ │ │ ├── retry.ts │ │ │ ├── sign-win32.js │ │ │ ├── sign-win32.ts │ │ │ ├── sign.js │ │ │ ├── sign.ts │ │ │ └── telemetry-config.json │ │ ├── config/ │ │ │ ├── CredScanSuppressions.json │ │ │ └── tsaoptions.json │ │ ├── darwin/ │ │ │ ├── app-entitlements.plist │ │ │ ├── cli-build-darwin.yml │ │ │ ├── helper-gpu-entitlements.plist │ │ │ ├── helper-plugin-entitlements.plist │ │ │ ├── helper-renderer-entitlements.plist │ │ │ ├── product-build-darwin-cli-sign.yml │ │ │ ├── product-build-darwin-sign.yml │ │ │ ├── product-build-darwin-test.yml │ │ │ ├── product-build-darwin-universal.yml │ │ │ └── product-build-darwin.yml │ │ ├── distro/ │ │ │ ├── download-distro.yml │ │ │ ├── mixin-npm.js │ │ │ ├── mixin-npm.ts │ │ │ ├── mixin-quality.js │ │ │ └── mixin-quality.ts │ │ ├── distro-build.yml │ │ ├── linux/ │ │ │ ├── .gitignore │ │ │ ├── apt-retry.sh │ │ │ ├── cli-build-linux.yml │ │ │ ├── product-build-linux-test.yml │ │ │ ├── product-build-linux.yml │ │ │ ├── setup-env.sh │ │ │ ├── snap-build-linux.yml │ │ │ ├── verify-glibc-requirements.sh │ │ │ └── xvfb.init │ │ ├── oss/ │ │ │ ├── product-build-pr-cache-linux.yml │ │ │ └── product-build-pr-cache-win32.yml │ │ ├── product-build-pr.yml │ │ ├── product-build.yml │ │ ├── product-compile.yml │ │ ├── product-npm-package-validate.yml │ │ ├── product-publish.yml │ │ ├── product-release.yml │ │ ├── publish-types/ │ │ │ ├── check-version.js │ │ │ ├── check-version.ts │ │ │ ├── publish-types.yml │ │ │ ├── update-types.js │ │ │ └── update-types.ts │ │ ├── upload-cdn.js │ │ ├── upload-cdn.ts │ │ ├── upload-nlsmetadata.js │ │ ├── upload-nlsmetadata.ts │ │ ├── upload-sourcemaps.js │ │ ├── upload-sourcemaps.ts │ │ ├── web/ │ │ │ └── product-build-web.yml │ │ └── win32/ │ │ ├── cli-build-win32.yml │ │ ├── exec.ps1 │ │ ├── import-esrp-auth-cert.ps1 │ │ ├── listprocesses.bat │ │ ├── product-build-win32-cli-sign.yml │ │ ├── product-build-win32-test.yml │ │ ├── product-build-win32.yml │ │ ├── retry.ps1 │ │ └── sdl-scan-win32.yml │ ├── buildfile.js │ ├── builtin/ │ │ ├── .eslintrc │ │ ├── browser-main.js │ │ ├── index.html │ │ ├── main.js │ │ └── package.json │ ├── checksums/ │ │ ├── electron.txt │ │ ├── nodejs.txt │ │ └── vscode-sysroot.txt │ ├── darwin/ │ │ ├── create-universal-app.js │ │ ├── create-universal-app.ts │ │ ├── sign.js │ │ ├── sign.ts │ │ ├── verify-macho.js │ │ └── verify-macho.ts │ ├── eslint.js │ ├── filters.js │ ├── gulp-eslint.js │ ├── gulpfile.cli.js │ ├── gulpfile.compile.js │ ├── gulpfile.editor.js │ ├── gulpfile.extensions.js │ ├── gulpfile.hygiene.js │ ├── gulpfile.js │ ├── gulpfile.reh.js │ ├── gulpfile.scan.js │ ├── gulpfile.vscode.js │ ├── gulpfile.vscode.linux.js │ ├── gulpfile.vscode.web.js │ ├── gulpfile.vscode.win32.js │ ├── hygiene.js │ ├── lib/ │ │ ├── asar.js │ │ ├── asar.ts │ │ ├── builtInExtensions.js │ │ ├── builtInExtensions.ts │ │ ├── builtInExtensionsCG.js │ │ ├── builtInExtensionsCG.ts │ │ ├── bundle.js │ │ ├── bundle.ts │ │ ├── compilation.js │ │ ├── compilation.ts │ │ ├── date.js │ │ ├── date.ts │ │ ├── dependencies.js │ │ ├── dependencies.ts │ │ ├── electron.js │ │ ├── electron.ts │ │ ├── extensions.js │ │ ├── extensions.ts │ │ ├── fetch.js │ │ ├── fetch.ts │ │ ├── formatter.js │ │ ├── formatter.ts │ │ ├── getVersion.js │ │ ├── getVersion.ts │ │ ├── git.js │ │ ├── git.ts │ │ ├── i18n.js │ │ ├── i18n.resources.json │ │ ├── i18n.ts │ │ ├── inlineMeta.js │ │ ├── inlineMeta.ts │ │ ├── layersChecker.js │ │ ├── layersChecker.ts │ │ ├── mangle/ │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── renameWorker.js │ │ │ ├── renameWorker.ts │ │ │ ├── staticLanguageServiceHost.js │ │ │ └── staticLanguageServiceHost.ts │ │ ├── monaco-api.js │ │ ├── monaco-api.ts │ │ ├── nls.js │ │ ├── nls.ts │ │ ├── node.js │ │ ├── node.ts │ │ ├── optimize.js │ │ ├── optimize.ts │ │ ├── policies.js │ │ ├── policies.ts │ │ ├── postcss.js │ │ ├── postcss.ts │ │ ├── preLaunch.js │ │ ├── preLaunch.ts │ │ ├── propertyInitOrderChecker.js │ │ ├── propertyInitOrderChecker.ts │ │ ├── reporter.js │ │ ├── reporter.ts │ │ ├── snapshotLoader.js │ │ ├── snapshotLoader.ts │ │ ├── standalone.js │ │ ├── standalone.ts │ │ ├── stats.js │ │ ├── stats.ts │ │ ├── stylelint/ │ │ │ ├── validateVariableNames.js │ │ │ ├── validateVariableNames.ts │ │ │ └── vscode-known-variables.json │ │ ├── task.js │ │ ├── task.ts │ │ ├── test/ │ │ │ ├── i18n.test.js │ │ │ └── i18n.test.ts │ │ ├── treeshaking.js │ │ ├── treeshaking.ts │ │ ├── tsb/ │ │ │ ├── builder.js │ │ │ ├── builder.ts │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── transpiler.js │ │ │ ├── transpiler.ts │ │ │ ├── utils.js │ │ │ └── utils.ts │ │ ├── typings/ │ │ │ ├── cgmanifest.json │ │ │ ├── event-stream.d.ts │ │ │ ├── github-releases.d.ts │ │ │ ├── gulp-bom.d.ts │ │ │ ├── gulp-buffer.d.ts │ │ │ ├── gulp-flatmap.d.ts │ │ │ ├── lazy.js.d.ts │ │ │ ├── stream.d.ts │ │ │ ├── ternary-stream.d.ts │ │ │ └── vinyl.d.ts │ │ ├── util.js │ │ ├── util.ts │ │ └── watch/ │ │ ├── index.js │ │ ├── index.ts │ │ ├── watch-win32.js │ │ └── watch-win32.ts │ ├── linux/ │ │ ├── debian/ │ │ │ ├── calculate-deps.js │ │ │ ├── calculate-deps.ts │ │ │ ├── dep-lists.js │ │ │ ├── dep-lists.ts │ │ │ ├── install-sysroot.js │ │ │ ├── install-sysroot.ts │ │ │ ├── types.js │ │ │ └── types.ts │ │ ├── dependencies-generator.js │ │ ├── dependencies-generator.ts │ │ ├── libcxx-fetcher.js │ │ ├── libcxx-fetcher.ts │ │ └── rpm/ │ │ ├── calculate-deps.js │ │ ├── calculate-deps.ts │ │ ├── dep-lists.js │ │ ├── dep-lists.ts │ │ ├── types.js │ │ └── types.ts │ ├── loader.min │ ├── monaco/ │ │ ├── LICENSE │ │ ├── README-npm.md │ │ ├── README.md │ │ ├── ThirdPartyNotices.txt │ │ ├── monaco.d.ts.recipe │ │ ├── monaco.usage.recipe │ │ ├── package.json │ │ └── version.txt │ ├── npm/ │ │ ├── dirs.js │ │ ├── gyp/ │ │ │ └── package.json │ │ ├── jsconfig.json │ │ ├── postinstall.js │ │ ├── preinstall.js │ │ ├── update-all-grammars.mjs │ │ ├── update-distro.mjs │ │ └── update-localization-extension.js │ ├── package.json │ ├── setup-npm-registry.js │ ├── stylelint.js │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── win32/ │ ├── .gitignore │ ├── Cargo.toml │ ├── code.iss │ ├── explorer-appx-fetcher.js │ ├── explorer-appx-fetcher.ts │ └── i18n/ │ ├── Default.hu.isl │ ├── Default.ko.isl │ ├── Default.zh-cn.isl │ ├── Default.zh-tw.isl │ ├── messages.de.isl │ ├── messages.en.isl │ ├── messages.es.isl │ ├── messages.fr.isl │ ├── messages.hu.isl │ ├── messages.it.isl │ ├── messages.ja.isl │ ├── messages.ko.isl │ ├── messages.pt-br.isl │ ├── messages.ru.isl │ ├── messages.tr.isl │ ├── messages.zh-cn.isl │ └── messages.zh-tw.isl ├── cglicenses.json ├── cgmanifest.json ├── cli/ │ ├── .cargo/ │ │ └── config.toml │ ├── CONTRIBUTING.md │ ├── Cargo.toml │ ├── ThirdPartyNotices.txt │ ├── build.rs │ ├── rustfmt.toml │ └── src/ │ ├── async_pipe.rs │ ├── auth.rs │ ├── bin/ │ │ └── code/ │ │ ├── legacy_args.rs │ │ └── main.rs │ ├── commands/ │ │ ├── args.rs │ │ ├── context.rs │ │ ├── output.rs │ │ ├── serve_web.rs │ │ ├── tunnels.rs │ │ ├── update.rs │ │ └── version.rs │ ├── commands.rs │ ├── constants.rs │ ├── desktop/ │ │ └── version_manager.rs │ ├── desktop.rs │ ├── download_cache.rs │ ├── json_rpc.rs │ ├── lib.rs │ ├── log.rs │ ├── msgpack_rpc.rs │ ├── options.rs │ ├── rpc.rs │ ├── self_update.rs │ ├── singleton.rs │ ├── state.rs │ ├── tunnels/ │ │ ├── challenge.rs │ │ ├── code_server.rs │ │ ├── control_server.rs │ │ ├── dev_tunnels.rs │ │ ├── legal.rs │ │ ├── local_forwarding.rs │ │ ├── nosleep.rs │ │ ├── nosleep_linux.rs │ │ ├── nosleep_macos.rs │ │ ├── nosleep_windows.rs │ │ ├── paths.rs │ │ ├── port_forwarder.rs │ │ ├── protocol.rs │ │ ├── server_bridge.rs │ │ ├── server_multiplexer.rs │ │ ├── service.rs │ │ ├── service_linux.rs │ │ ├── service_macos.rs │ │ ├── service_windows.rs │ │ ├── shutdown_signal.rs │ │ ├── singleton_client.rs │ │ ├── singleton_server.rs │ │ ├── socket_signal.rs │ │ └── wsl_detect.rs │ ├── tunnels.rs │ ├── update_service.rs │ ├── util/ │ │ ├── app_lock.rs │ │ ├── command.rs │ │ ├── errors.rs │ │ ├── file_lock.rs │ │ ├── http.rs │ │ ├── input.rs │ │ ├── io.rs │ │ ├── is_integrated.rs │ │ ├── machine.rs │ │ ├── os.rs │ │ ├── prereqs.rs │ │ ├── ring_buffer.rs │ │ ├── sync.rs │ │ ├── tar.rs │ │ └── zipper.rs │ └── util.rs ├── eslint.config.js ├── extensions/ │ ├── .npmrc │ ├── bat/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── batchfile.code-snippets │ │ └── syntaxes/ │ │ └── batchfile.tmLanguage.json │ ├── cgmanifest.json │ ├── clojure/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── clojure.tmLanguage.json │ ├── coffeescript/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── coffeescript.code-snippets │ │ └── syntaxes/ │ │ └── coffeescript.tmLanguage.json │ ├── configuration-editing/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── schemas/ │ │ │ ├── attachContainer.schema.json │ │ │ ├── devContainer.codespaces.schema.json │ │ │ └── devContainer.vscode.schema.json │ │ ├── src/ │ │ │ ├── browser/ │ │ │ │ └── net.ts │ │ │ ├── configurationEditingMain.ts │ │ │ ├── extensionsProposals.ts │ │ │ ├── importExportProfiles.ts │ │ │ ├── node/ │ │ │ │ └── net.ts │ │ │ ├── settingsDocumentHelper.ts │ │ │ ├── test/ │ │ │ │ ├── completion.test.ts │ │ │ │ └── index.ts │ │ │ └── typings/ │ │ │ └── ref.d.ts │ │ └── tsconfig.json │ ├── cpp/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammars.js │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ ├── c.code-snippets │ │ │ └── cpp.code-snippets │ │ └── syntaxes/ │ │ ├── c.tmLanguage.json │ │ ├── cpp.embedded.macro.tmLanguage.json │ │ ├── cpp.tmLanguage.json │ │ ├── cuda-cpp.tmLanguage.json │ │ └── platform.tmLanguage.json │ ├── csharp/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── csharp.code-snippets │ │ └── syntaxes/ │ │ └── csharp.tmLanguage.json │ ├── css/ │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── css.tmLanguage.json │ ├── css-language-features/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ ├── settings.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── client/ │ │ │ ├── src/ │ │ │ │ ├── browser/ │ │ │ │ │ └── cssClientMain.ts │ │ │ │ ├── cssClient.ts │ │ │ │ ├── customData.ts │ │ │ │ ├── dropOrPaste/ │ │ │ │ │ ├── dropOrPasteResource.ts │ │ │ │ │ ├── shared.ts │ │ │ │ │ └── uriList.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── cssClientMain.ts │ │ │ │ │ └── nodeFs.ts │ │ │ │ └── requests.ts │ │ │ └── tsconfig.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── schemas/ │ │ │ └── package.schema.json │ │ ├── server/ │ │ │ ├── .npmrc │ │ │ ├── .vscode/ │ │ │ │ ├── launch.json │ │ │ │ └── tasks.json │ │ │ ├── extension-browser.webpack.config.js │ │ │ ├── extension.webpack.config.js │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── cssServerMain.ts │ │ │ │ │ └── cssServerWorkerMain.ts │ │ │ │ ├── cssServer.ts │ │ │ │ ├── customData.ts │ │ │ │ ├── languageModelCache.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── cssServerMain.ts │ │ │ │ │ ├── cssServerNodeMain.ts │ │ │ │ │ └── nodeFs.ts │ │ │ │ ├── requests.ts │ │ │ │ ├── test/ │ │ │ │ │ ├── completion.test.ts │ │ │ │ │ └── links.test.ts │ │ │ │ └── utils/ │ │ │ │ ├── documentContext.ts │ │ │ │ ├── runner.ts │ │ │ │ ├── strings.ts │ │ │ │ └── validation.ts │ │ │ ├── test/ │ │ │ │ ├── index.js │ │ │ │ ├── linksTestFixtures/ │ │ │ │ │ └── .gitignore │ │ │ │ └── pathCompletionFixtures/ │ │ │ │ ├── .foo.js │ │ │ │ ├── about/ │ │ │ │ │ ├── about.css │ │ │ │ │ └── about.html │ │ │ │ ├── index.html │ │ │ │ ├── scss/ │ │ │ │ │ ├── _foo.scss │ │ │ │ │ └── main.scss │ │ │ │ └── src/ │ │ │ │ ├── data/ │ │ │ │ │ └── foo.asar │ │ │ │ ├── feature.js │ │ │ │ └── test.js │ │ │ └── tsconfig.json │ │ └── test/ │ │ └── mocha.opts │ ├── dart/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── dart.tmLanguage.json │ ├── debug-auto-launch/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── extension.ts │ │ └── tsconfig.json │ ├── debug-server-ready/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── extension.ts │ │ └── tsconfig.json │ ├── diff/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── diff.tmLanguage.json │ ├── docker/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── docker.tmLanguage.json │ ├── emmet/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── settings.json │ │ ├── .vscodeignore │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── cgmanifest.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── abbreviationActions.ts │ │ │ ├── balance.ts │ │ │ ├── browser/ │ │ │ │ └── emmetBrowserMain.ts │ │ │ ├── bufferStream.ts │ │ │ ├── defaultCompletionProvider.ts │ │ │ ├── editPoint.ts │ │ │ ├── emmetCommon.ts │ │ │ ├── evaluateMathExpression.ts │ │ │ ├── imageSizeHelper.ts │ │ │ ├── incrementDecrement.ts │ │ │ ├── locateFile.ts │ │ │ ├── matchTag.ts │ │ │ ├── mergeLines.ts │ │ │ ├── node/ │ │ │ │ └── emmetNodeMain.ts │ │ │ ├── parseDocument.ts │ │ │ ├── reflectCssValue.ts │ │ │ ├── removeTag.ts │ │ │ ├── selectItem.ts │ │ │ ├── selectItemHTML.ts │ │ │ ├── selectItemStylesheet.ts │ │ │ ├── splitJoinTag.ts │ │ │ ├── test/ │ │ │ │ ├── abbreviationAction.test.ts │ │ │ │ ├── completion.test.ts │ │ │ │ ├── cssAbbreviationAction.test.ts │ │ │ │ ├── editPointSelectItemBalance.test.ts │ │ │ │ ├── evaluateMathExpression.test.ts │ │ │ │ ├── incrementDecrement.test.ts │ │ │ │ ├── index.ts │ │ │ │ ├── partialParsingStylesheet.test.ts │ │ │ │ ├── reflectCssValue.test.ts │ │ │ │ ├── tagActions.test.ts │ │ │ │ ├── testUtils.ts │ │ │ │ ├── toggleComment.test.ts │ │ │ │ ├── updateImageSize.test.ts │ │ │ │ └── wrapWithAbbreviation.test.ts │ │ │ ├── toggleComment.ts │ │ │ ├── typings/ │ │ │ │ ├── EmmetFlatNode.d.ts │ │ │ │ ├── EmmetNode.d.ts │ │ │ │ ├── emmetio__css-parser.d.ts │ │ │ │ ├── emmetio__html-matcher.d.ts │ │ │ │ └── refs.d.ts │ │ │ ├── updateImageSize.ts │ │ │ ├── updateTag.ts │ │ │ └── util.ts │ │ ├── test-workspace/ │ │ │ └── .vscode/ │ │ │ └── settings.json │ │ └── tsconfig.json │ ├── esbuild-webview-common.js │ ├── extension-editing/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── constants.ts │ │ │ ├── extensionEditingBrowserMain.ts │ │ │ ├── extensionEditingMain.ts │ │ │ ├── extensionEngineValidation.ts │ │ │ ├── extensionLinter.ts │ │ │ ├── jsonReconstruct.ts │ │ │ └── packageDocumentHelper.ts │ │ └── tsconfig.json │ ├── fsharp/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── fsharp.code-snippets │ │ └── syntaxes/ │ │ └── fsharp.tmLanguage.json │ ├── git/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── build/ │ │ │ └── update-emoji.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── resources/ │ │ │ └── emojis.json │ │ ├── src/ │ │ │ ├── actionButton.ts │ │ │ ├── api/ │ │ │ │ ├── api1.ts │ │ │ │ ├── extension.ts │ │ │ │ └── git.d.ts │ │ │ ├── askpass-empty.sh │ │ │ ├── askpass-main.ts │ │ │ ├── askpass.sh │ │ │ ├── askpass.ts │ │ │ ├── autofetch.ts │ │ │ ├── blame.ts │ │ │ ├── branchProtection.ts │ │ │ ├── cache.ts │ │ │ ├── commands.ts │ │ │ ├── decorationProvider.ts │ │ │ ├── decorators.ts │ │ │ ├── diagnostics.ts │ │ │ ├── editSessionIdentityProvider.ts │ │ │ ├── emoji.ts │ │ │ ├── fileSystemProvider.ts │ │ │ ├── git-base.ts │ │ │ ├── git-editor-empty.sh │ │ │ ├── git-editor-main.ts │ │ │ ├── git-editor.sh │ │ │ ├── git.ts │ │ │ ├── gitEditor.ts │ │ │ ├── historyItemDetailsProvider.ts │ │ │ ├── historyProvider.ts │ │ │ ├── ipc/ │ │ │ │ ├── ipcClient.ts │ │ │ │ └── ipcServer.ts │ │ │ ├── main.ts │ │ │ ├── model.ts │ │ │ ├── operation.ts │ │ │ ├── postCommitCommands.ts │ │ │ ├── protocolHandler.ts │ │ │ ├── pushError.ts │ │ │ ├── remotePublisher.ts │ │ │ ├── remoteSource.ts │ │ │ ├── repository.ts │ │ │ ├── ssh-askpass-empty.sh │ │ │ ├── ssh-askpass.sh │ │ │ ├── staging.ts │ │ │ ├── statusbar.ts │ │ │ ├── terminal.ts │ │ │ ├── test/ │ │ │ │ ├── git.test.ts │ │ │ │ ├── index.ts │ │ │ │ └── smoke.test.ts │ │ │ ├── timelineProvider.ts │ │ │ ├── typings/ │ │ │ │ └── git-base.d.ts │ │ │ ├── uri.ts │ │ │ ├── util.ts │ │ │ └── watch.ts │ │ └── tsconfig.json │ ├── git-base/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── build/ │ │ │ └── update-grammars.js │ │ ├── cgmanifest.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── languages/ │ │ │ ├── git-commit.language-configuration.json │ │ │ ├── git-rebase.language-configuration.json │ │ │ └── ignore.language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── api/ │ │ │ │ ├── api1.ts │ │ │ │ ├── extension.ts │ │ │ │ └── git-base.d.ts │ │ │ ├── decorators.ts │ │ │ ├── extension.ts │ │ │ ├── model.ts │ │ │ ├── remoteProvider.ts │ │ │ ├── remoteSource.ts │ │ │ └── util.ts │ │ ├── syntaxes/ │ │ │ ├── git-commit.tmLanguage.json │ │ │ ├── git-rebase.tmLanguage.json │ │ │ └── ignore.tmLanguage.json │ │ └── tsconfig.json │ ├── github/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension.webpack.config.js │ │ ├── markdown.css │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── auth.ts │ │ │ ├── branchProtection.ts │ │ │ ├── canonicalUriProvider.ts │ │ │ ├── commands.ts │ │ │ ├── credentialProvider.ts │ │ │ ├── extension.ts │ │ │ ├── historyItemDetailsProvider.ts │ │ │ ├── links.ts │ │ │ ├── publish.ts │ │ │ ├── pushErrorHandler.ts │ │ │ ├── remoteSourceProvider.ts │ │ │ ├── remoteSourcePublisher.ts │ │ │ ├── shareProviders.ts │ │ │ ├── test/ │ │ │ │ ├── github.test.ts │ │ │ │ └── index.ts │ │ │ ├── typings/ │ │ │ │ ├── git-base.d.ts │ │ │ │ ├── git.d.ts │ │ │ │ └── ref.d.ts │ │ │ └── util.ts │ │ ├── testWorkspace/ │ │ │ ├── .github/ │ │ │ │ ├── PULL_REQUEST_TEMPLATE/ │ │ │ │ │ ├── a.md │ │ │ │ │ ├── b.md │ │ │ │ │ └── x.txt │ │ │ │ └── PULL_REQUEST_TEMPLATE.md │ │ │ ├── PULL_REQUEST_TEMPLATE/ │ │ │ │ ├── a.md │ │ │ │ ├── b.md │ │ │ │ └── x.txt │ │ │ ├── PULL_REQUEST_TEMPLATE.md │ │ │ ├── docs/ │ │ │ │ ├── PULL_REQUEST_TEMPLATE/ │ │ │ │ │ ├── a.md │ │ │ │ │ ├── b.md │ │ │ │ │ └── x.txt │ │ │ │ └── PULL_REQUEST_TEMPLATE.md │ │ │ ├── some-markdown.md │ │ │ └── x.txt │ │ └── tsconfig.json │ ├── github-authentication/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── media/ │ │ │ ├── auth.css │ │ │ └── index.html │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── browser/ │ │ │ │ ├── authServer.ts │ │ │ │ ├── buffer.ts │ │ │ │ ├── crypto.ts │ │ │ │ └── fetch.ts │ │ │ ├── common/ │ │ │ │ ├── env.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── experimentationService.ts │ │ │ │ ├── keychain.ts │ │ │ │ ├── logger.ts │ │ │ │ └── utils.ts │ │ │ ├── config.ts │ │ │ ├── extension.ts │ │ │ ├── flows.ts │ │ │ ├── github.ts │ │ │ ├── githubServer.ts │ │ │ ├── node/ │ │ │ │ ├── authServer.ts │ │ │ │ ├── buffer.ts │ │ │ │ ├── crypto.ts │ │ │ │ └── fetch.ts │ │ │ └── test/ │ │ │ ├── flows.test.ts │ │ │ └── node/ │ │ │ └── authServer.test.ts │ │ └── tsconfig.json │ ├── go/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── go.tmLanguage.json │ ├── groovy/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── groovy.code-snippets │ │ └── syntaxes/ │ │ └── groovy.tmLanguage.json │ ├── grunt/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── main.ts │ │ └── tsconfig.json │ ├── gulp/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── main.ts │ │ └── tsconfig.json │ ├── handlebars/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── Handlebars.tmLanguage.json │ ├── hlsl/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── hlsl.tmLanguage.json │ ├── html/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── html.code-snippets │ │ └── syntaxes/ │ │ ├── html-derivative.tmLanguage.json │ │ └── html.tmLanguage.json │ ├── html-language-features/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ ├── settings.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── build/ │ │ │ └── bundleTypeScriptLibraries.js │ │ ├── cgmanifest.json │ │ ├── client/ │ │ │ ├── src/ │ │ │ │ ├── autoInsertion.ts │ │ │ │ ├── browser/ │ │ │ │ │ └── htmlClientMain.ts │ │ │ │ ├── customData.ts │ │ │ │ ├── htmlClient.ts │ │ │ │ ├── languageParticipants.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── htmlClientMain.ts │ │ │ │ │ └── nodeFs.ts │ │ │ │ └── requests.ts │ │ │ └── tsconfig.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── schemas/ │ │ │ └── package.schema.json │ │ └── server/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── build/ │ │ │ └── javaScriptLibraryLoader.js │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── lib/ │ │ │ ├── cgmanifest.json │ │ │ └── jquery.d.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── browser/ │ │ │ │ ├── htmlServerMain.ts │ │ │ │ └── htmlServerWorkerMain.ts │ │ │ ├── customData.ts │ │ │ ├── htmlServer.ts │ │ │ ├── languageModelCache.ts │ │ │ ├── modes/ │ │ │ │ ├── cssMode.ts │ │ │ │ ├── embeddedSupport.ts │ │ │ │ ├── formatting.ts │ │ │ │ ├── htmlFolding.ts │ │ │ │ ├── htmlMode.ts │ │ │ │ ├── javascriptLibs.ts │ │ │ │ ├── javascriptMode.ts │ │ │ │ ├── javascriptSemanticTokens.ts │ │ │ │ ├── languageModes.ts │ │ │ │ ├── selectionRanges.ts │ │ │ │ └── semanticTokens.ts │ │ │ ├── node/ │ │ │ │ ├── htmlServerMain.ts │ │ │ │ ├── htmlServerNodeMain.ts │ │ │ │ └── nodeFs.ts │ │ │ ├── requests.ts │ │ │ ├── test/ │ │ │ │ ├── completions.test.ts │ │ │ │ ├── documentContext.test.ts │ │ │ │ ├── embedded.test.ts │ │ │ │ ├── fixtures/ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ ├── 19813-4spaces.html │ │ │ │ │ │ ├── 19813-tab.html │ │ │ │ │ │ ├── 19813.html │ │ │ │ │ │ └── 21634.html │ │ │ │ │ └── inputs/ │ │ │ │ │ ├── 19813.html │ │ │ │ │ └── 21634.html │ │ │ │ ├── folding.test.ts │ │ │ │ ├── formatting.test.ts │ │ │ │ ├── pathCompletionFixtures/ │ │ │ │ │ ├── .foo.js │ │ │ │ │ ├── about/ │ │ │ │ │ │ ├── about.css │ │ │ │ │ │ ├── about.html │ │ │ │ │ │ └── media/ │ │ │ │ │ │ └── icon.pic │ │ │ │ │ ├── index.html │ │ │ │ │ └── src/ │ │ │ │ │ ├── feature.js │ │ │ │ │ └── test.js │ │ │ │ ├── rename.test.ts │ │ │ │ ├── selectionRanges.test.ts │ │ │ │ ├── semanticTokens.test.ts │ │ │ │ └── words.test.ts │ │ │ └── utils/ │ │ │ ├── arrays.ts │ │ │ ├── documentContext.ts │ │ │ ├── positions.ts │ │ │ ├── runner.ts │ │ │ ├── strings.ts │ │ │ └── validation.ts │ │ ├── test/ │ │ │ └── index.js │ │ └── tsconfig.json │ ├── ini/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── ini.language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── properties.language-configuration.json │ │ └── syntaxes/ │ │ └── ini.tmLanguage.json │ ├── ipynb/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── esbuild.js │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── notebook-src/ │ │ │ └── cellAttachmentRenderer.ts │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── common.ts │ │ │ ├── constants.ts │ │ │ ├── deserializers.ts │ │ │ ├── helper.ts │ │ │ ├── ipynbMain.browser.ts │ │ │ ├── ipynbMain.node.ts │ │ │ ├── ipynbMain.ts │ │ │ ├── notebookAttachmentCleaner.ts │ │ │ ├── notebookImagePaste.ts │ │ │ ├── notebookModelStoreSync.ts │ │ │ ├── notebookSerializer.node.ts │ │ │ ├── notebookSerializer.ts │ │ │ ├── notebookSerializer.web.ts │ │ │ ├── notebookSerializerWorker.ts │ │ │ ├── notebookSerializerWorker.web.ts │ │ │ ├── serializers.ts │ │ │ ├── test/ │ │ │ │ ├── clearOutputs.test.ts │ │ │ │ ├── index.ts │ │ │ │ ├── notebookModelStoreSync.test.ts │ │ │ │ └── serializers.test.ts │ │ │ └── types.d.ts │ │ └── tsconfig.json │ ├── jake/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── main.ts │ │ └── tsconfig.json │ ├── java/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── java.code-snippets │ │ └── syntaxes/ │ │ └── java.tmLanguage.json │ ├── javascript/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── javascript-language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── javascript.code-snippets │ │ ├── syntaxes/ │ │ │ ├── JavaScript.tmLanguage.json │ │ │ ├── JavaScriptReact.tmLanguage.json │ │ │ ├── Readme.md │ │ │ └── Regular Expressions (JavaScript).tmLanguage │ │ └── tags-language-configuration.json │ ├── json/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammars.js │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ ├── JSON.tmLanguage.json │ │ ├── JSONC.tmLanguage.json │ │ ├── JSONL.tmLanguage.json │ │ └── snippets.tmLanguage.json │ ├── json-language-features/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── client/ │ │ │ ├── src/ │ │ │ │ ├── browser/ │ │ │ │ │ └── jsonClientMain.ts │ │ │ │ ├── jsonClient.ts │ │ │ │ ├── languageParticipants.ts │ │ │ │ ├── languageStatus.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── jsonClientMain.ts │ │ │ │ │ └── schemaCache.ts │ │ │ │ └── utils/ │ │ │ │ └── hash.ts │ │ │ └── tsconfig.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ └── server/ │ │ ├── .npmignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── README.md │ │ ├── bin/ │ │ │ └── vscode-json-languageserver │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── browser/ │ │ │ │ ├── jsonServerMain.ts │ │ │ │ └── jsonServerWorkerMain.ts │ │ │ ├── jsonServer.ts │ │ │ ├── languageModelCache.ts │ │ │ ├── node/ │ │ │ │ ├── jsonServerMain.ts │ │ │ │ └── jsonServerNodeMain.ts │ │ │ └── utils/ │ │ │ ├── runner.ts │ │ │ ├── strings.ts │ │ │ └── validation.ts │ │ ├── test/ │ │ │ └── mocha.opts │ │ └── tsconfig.json │ ├── julia/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── julia.tmLanguage.json │ ├── latex/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammars.js │ │ ├── cgmanifest.json │ │ ├── cpp-bailout-license.txt │ │ ├── latex-cpp-embedded-language-configuration.json │ │ ├── latex-language-configuration.json │ │ ├── markdown-latex-combined-language-configuration.json │ │ ├── markdown-latex-combined-license.txt │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ ├── Bibtex.tmLanguage.json │ │ ├── LaTeX.tmLanguage.json │ │ ├── TeX.tmLanguage.json │ │ ├── cpp-grammar-bailout.tmLanguage.json │ │ └── markdown-latex-combined.tmLanguage.json │ ├── less/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.js │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── less.tmLanguage.json │ ├── log/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── log.tmLanguage.json │ ├── lua/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── lua.tmLanguage.json │ ├── make/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── make.tmLanguage.json │ ├── mangle-loader.js │ ├── markdown-basics/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── markdown.code-snippets │ │ └── syntaxes/ │ │ └── markdown.tmLanguage.json │ ├── markdown-language-features/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── esbuild-notebook.js │ │ ├── esbuild-preview.js │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── media/ │ │ │ ├── highlight.css │ │ │ └── markdown.css │ │ ├── notebook/ │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── preview-src/ │ │ │ ├── activeLineMarker.ts │ │ │ ├── csp.ts │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ ├── loading.ts │ │ │ ├── messaging.ts │ │ │ ├── pre.ts │ │ │ ├── scroll-sync.ts │ │ │ ├── settings.ts │ │ │ ├── strings.ts │ │ │ └── tsconfig.json │ │ ├── schemas/ │ │ │ └── package.schema.json │ │ ├── src/ │ │ │ ├── client/ │ │ │ │ ├── client.ts │ │ │ │ ├── fileWatchingManager.ts │ │ │ │ ├── inMemoryDocument.ts │ │ │ │ ├── protocol.ts │ │ │ │ └── workspace.ts │ │ │ ├── commandManager.ts │ │ │ ├── commands/ │ │ │ │ ├── copyImage.ts │ │ │ │ ├── index.ts │ │ │ │ ├── insertResource.ts │ │ │ │ ├── openImage.ts │ │ │ │ ├── refreshPreview.ts │ │ │ │ ├── reloadPlugins.ts │ │ │ │ ├── renderDocument.ts │ │ │ │ ├── showPreview.ts │ │ │ │ ├── showPreviewSecuritySelector.ts │ │ │ │ ├── showSource.ts │ │ │ │ └── toggleLock.ts │ │ │ ├── extension.browser.ts │ │ │ ├── extension.shared.ts │ │ │ ├── extension.ts │ │ │ ├── languageFeatures/ │ │ │ │ ├── copyFiles/ │ │ │ │ │ ├── copyFiles.ts │ │ │ │ │ ├── dropOrPasteResource.ts │ │ │ │ │ ├── newFilePathGenerator.ts │ │ │ │ │ ├── pasteUrlProvider.ts │ │ │ │ │ ├── shared.ts │ │ │ │ │ ├── smartDropOrPaste.ts │ │ │ │ │ └── snippets.ts │ │ │ │ ├── diagnostics.ts │ │ │ │ ├── fileReferences.ts │ │ │ │ ├── linkUpdater.ts │ │ │ │ └── updateLinksOnPaste.ts │ │ │ ├── logging.ts │ │ │ ├── markdownEngine.ts │ │ │ ├── markdownExtensions.ts │ │ │ ├── preview/ │ │ │ │ ├── documentRenderer.ts │ │ │ │ ├── preview.ts │ │ │ │ ├── previewConfig.ts │ │ │ │ ├── previewManager.ts │ │ │ │ ├── scrolling.ts │ │ │ │ ├── security.ts │ │ │ │ └── topmostLineMonitor.ts │ │ │ ├── slugify.ts │ │ │ ├── telemetryReporter.ts │ │ │ ├── test/ │ │ │ │ ├── copyFile.test.ts │ │ │ │ ├── documentLink.test.ts │ │ │ │ ├── engine.test.ts │ │ │ │ ├── engine.ts │ │ │ │ ├── index.ts │ │ │ │ ├── nulLogging.ts │ │ │ │ ├── pasteUrl.test.ts │ │ │ │ ├── urlToUri.test.ts │ │ │ │ └── util.ts │ │ │ ├── types/ │ │ │ │ └── textDocument.ts │ │ │ ├── typings/ │ │ │ │ └── ref.d.ts │ │ │ └── util/ │ │ │ ├── arrays.ts │ │ │ ├── async.ts │ │ │ ├── cancellation.ts │ │ │ ├── dispose.ts │ │ │ ├── document.ts │ │ │ ├── dom.ts │ │ │ ├── file.ts │ │ │ ├── mimes.ts │ │ │ ├── openDocumentLink.ts │ │ │ ├── resourceMap.ts │ │ │ ├── resources.ts │ │ │ ├── schemes.ts │ │ │ ├── uriList.ts │ │ │ └── url.ts │ │ ├── test-workspace/ │ │ │ ├── a.md │ │ │ ├── b.md │ │ │ ├── sub/ │ │ │ │ ├── c.md │ │ │ │ ├── d.md │ │ │ │ ├── file with space.md │ │ │ │ └── foo.txt │ │ │ └── sub with space/ │ │ │ └── file.md │ │ ├── tsconfig.browser.json │ │ ├── tsconfig.json │ │ └── types/ │ │ └── previewMessaging.d.ts │ ├── markdown-math/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── cgmanifest.json │ │ ├── esbuild.js │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── notebook/ │ │ │ ├── katex.ts │ │ │ └── tsconfig.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── preview-styles/ │ │ │ └── index.css │ │ ├── src/ │ │ │ └── extension.ts │ │ ├── syntaxes/ │ │ │ ├── md-math-block.tmLanguage.json │ │ │ ├── md-math-fence.tmLanguage.json │ │ │ ├── md-math-inline.tmLanguage.json │ │ │ └── md-math.tmLanguage.json │ │ └── tsconfig.json │ ├── media-preview/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── media/ │ │ │ ├── audioPreview.css │ │ │ ├── audioPreview.js │ │ │ ├── imagePreview.css │ │ │ ├── imagePreview.js │ │ │ ├── videoPreview.css │ │ │ └── videoPreview.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── audioPreview.ts │ │ │ ├── binarySizeStatusBarEntry.ts │ │ │ ├── extension.ts │ │ │ ├── imagePreview/ │ │ │ │ ├── index.ts │ │ │ │ ├── sizeStatusBarEntry.ts │ │ │ │ └── zoomStatusBarEntry.ts │ │ │ ├── mediaPreview.ts │ │ │ ├── ownedStatusBarEntry.ts │ │ │ ├── util/ │ │ │ │ ├── dispose.ts │ │ │ │ └── dom.ts │ │ │ └── videoPreview.ts │ │ └── tsconfig.json │ ├── merge-conflict/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── codelensProvider.ts │ │ │ ├── commandHandler.ts │ │ │ ├── contentProvider.ts │ │ │ ├── delayer.ts │ │ │ ├── documentMergeConflict.ts │ │ │ ├── documentTracker.ts │ │ │ ├── interfaces.ts │ │ │ ├── mergeConflictMain.ts │ │ │ ├── mergeConflictParser.ts │ │ │ ├── mergeDecorator.ts │ │ │ └── services.ts │ │ └── tsconfig.json │ ├── microsoft-authentication/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── media/ │ │ │ ├── auth.css │ │ │ └── index.html │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── packageMocks/ │ │ │ ├── dpapi/ │ │ │ │ └── dpapi.js │ │ │ └── keytar/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── src/ │ │ │ ├── AADHelper.ts │ │ │ ├── UriEventHandler.ts │ │ │ ├── betterSecretStorage.ts │ │ │ ├── browser/ │ │ │ │ ├── authProvider.ts │ │ │ │ ├── authServer.ts │ │ │ │ ├── buffer.ts │ │ │ │ └── fetch.ts │ │ │ ├── common/ │ │ │ │ ├── accountAccess.ts │ │ │ │ ├── async.ts │ │ │ │ ├── cachePlugin.ts │ │ │ │ ├── env.ts │ │ │ │ ├── event.ts │ │ │ │ ├── experimentation.ts │ │ │ │ ├── loggerOptions.ts │ │ │ │ ├── loopbackClientAndOpener.ts │ │ │ │ ├── publicClientCache.ts │ │ │ │ ├── scopeData.ts │ │ │ │ ├── telemetryReporter.ts │ │ │ │ ├── test/ │ │ │ │ │ ├── loopbackClientAndOpener.test.ts │ │ │ │ │ └── scopeData.test.ts │ │ │ │ └── uri.ts │ │ │ ├── cryptoUtils.ts │ │ │ ├── extension.ts │ │ │ ├── extensionV1.ts │ │ │ ├── extensionV2.ts │ │ │ ├── logger.ts │ │ │ └── node/ │ │ │ ├── authProvider.ts │ │ │ ├── authServer.ts │ │ │ ├── buffer.ts │ │ │ ├── cachedPublicClientApplication.ts │ │ │ ├── fetch.ts │ │ │ ├── flows.ts │ │ │ ├── loopbackTemplate.ts │ │ │ └── publicClientCache.ts │ │ └── tsconfig.json │ ├── notebook-renderers/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── esbuild.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── ansi.ts │ │ │ ├── color.ts │ │ │ ├── colorMap.ts │ │ │ ├── htmlHelper.ts │ │ │ ├── index.ts │ │ │ ├── linkify.ts │ │ │ ├── rendererTypes.ts │ │ │ ├── stackTraceHelper.ts │ │ │ ├── test/ │ │ │ │ ├── index.ts │ │ │ │ ├── linkify.test.ts │ │ │ │ ├── notebookRenderer.test.ts │ │ │ │ └── stackTraceHelper.test.ts │ │ │ └── textHelper.ts │ │ └── tsconfig.json │ ├── npm/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── commands.ts │ │ │ ├── features/ │ │ │ │ ├── bowerJSONContribution.ts │ │ │ │ ├── date.ts │ │ │ │ ├── jsonContributions.ts │ │ │ │ └── packageJSONContribution.ts │ │ │ ├── npmBrowserMain.ts │ │ │ ├── npmMain.ts │ │ │ ├── npmScriptLens.ts │ │ │ ├── npmView.ts │ │ │ ├── preferred-pm.ts │ │ │ ├── readScripts.ts │ │ │ ├── scriptHover.ts │ │ │ └── tasks.ts │ │ └── tsconfig.json │ ├── objective-c/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammars.js │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ ├── objective-c++.tmLanguage.json │ │ └── objective-c.tmLanguage.json │ ├── open-remote-ssh/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── authResolver.ts │ │ │ ├── commands.ts │ │ │ ├── common/ │ │ │ │ ├── disposable.ts │ │ │ │ ├── files.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── platform.ts │ │ │ │ └── ports.ts │ │ │ ├── extension.ts │ │ │ ├── hostTreeView.ts │ │ │ ├── remoteLocationHistory.ts │ │ │ ├── serverConfig.ts │ │ │ ├── serverSetup.ts │ │ │ └── ssh/ │ │ │ ├── hostfile.ts │ │ │ ├── identityFiles.ts │ │ │ ├── sshConfig.ts │ │ │ ├── sshConnection.ts │ │ │ └── sshDestination.ts │ │ └── tsconfig.json │ ├── open-remote-wsl/ │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── authResolver.ts │ │ │ ├── commands.ts │ │ │ ├── common/ │ │ │ │ ├── async.ts │ │ │ │ ├── disposable.ts │ │ │ │ ├── event.ts │ │ │ │ ├── files.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── platform.ts │ │ │ │ └── ports.ts │ │ │ ├── distroTreeView.ts │ │ │ ├── extension.ts │ │ │ ├── remoteLocationHistory.ts │ │ │ ├── serverConfig.ts │ │ │ ├── serverSetup.ts │ │ │ └── wsl/ │ │ │ ├── wslManager.ts │ │ │ └── wslTerminal.ts │ │ └── tsconfig.json │ ├── package.json │ ├── perl/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── perl.language-configuration.json │ │ ├── perl6.language-configuration.json │ │ └── syntaxes/ │ │ ├── perl.tmLanguage.json │ │ └── perl6.tmLanguage.json │ ├── php/ │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── php.code-snippets │ │ └── syntaxes/ │ │ ├── html.tmLanguage.json │ │ └── php.tmLanguage.json │ ├── php-language-features/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── features/ │ │ │ │ ├── completionItemProvider.ts │ │ │ │ ├── hoverProvider.ts │ │ │ │ ├── phpGlobalFunctions.ts │ │ │ │ ├── phpGlobals.ts │ │ │ │ ├── signatureHelpProvider.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── async.ts │ │ │ │ │ └── markedTextUtil.ts │ │ │ │ └── validationProvider.ts │ │ │ ├── phpMain.ts │ │ │ └── typings/ │ │ │ └── node.additions.d.ts │ │ └── tsconfig.json │ ├── postinstall.mjs │ ├── powershell/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── powershell.tmLanguage.json │ ├── pug/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── pug.tmLanguage.json │ ├── python/ │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ ├── MagicPython.tmLanguage.json │ │ └── MagicRegExp.tmLanguage.json │ ├── r/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── r.tmLanguage.json │ ├── razor/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── cshtml.tmLanguage.json │ ├── references-view/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── calls/ │ │ │ │ ├── index.ts │ │ │ │ └── model.ts │ │ │ ├── extension.ts │ │ │ ├── highlights.ts │ │ │ ├── navigation.ts │ │ │ ├── references/ │ │ │ │ ├── index.ts │ │ │ │ └── model.ts │ │ │ ├── references-view.d.ts │ │ │ ├── tree.ts │ │ │ ├── types/ │ │ │ │ ├── index.ts │ │ │ │ └── model.ts │ │ │ └── utils.ts │ │ └── tsconfig.json │ ├── restructuredtext/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── rst.tmLanguage.json │ ├── ruby/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── ruby.tmLanguage.json │ ├── rust/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── rust.tmLanguage.json │ ├── scss/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ ├── sassdoc.tmLanguage.json │ │ └── scss.tmLanguage.json │ ├── search-result/ │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ └── extension.ts │ │ ├── syntaxes/ │ │ │ ├── generateTMLanguage.js │ │ │ └── searchResult.tmLanguage.json │ │ └── tsconfig.json │ ├── shaderlab/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── shaderlab.tmLanguage.json │ ├── shared.webpack.config.js │ ├── shellscript/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── shell-unix-bash.tmLanguage.json │ ├── simple-browser/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── esbuild-preview.js │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── media/ │ │ │ └── main.css │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── preview-src/ │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ ├── src/ │ │ │ ├── dispose.ts │ │ │ ├── extension.ts │ │ │ ├── simpleBrowserManager.ts │ │ │ └── simpleBrowserView.ts │ │ └── tsconfig.json │ ├── sql/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammar.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── syntaxes/ │ │ └── sql.tmLanguage.json │ ├── swift/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── swift.code-snippets │ │ └── syntaxes/ │ │ └── swift.tmLanguage.json │ ├── terminal-suggest/ │ │ ├── .gitignore │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── ThirdPartyNotices.txt │ │ ├── cgmanifest.json │ │ ├── extension.webpack.config.js │ │ ├── fixtures/ │ │ │ └── shell-parser/ │ │ │ ├── basic/ │ │ │ │ ├── input.sh │ │ │ │ └── output.txt │ │ │ ├── multipleStatements/ │ │ │ │ ├── input.sh │ │ │ │ └── output.txt │ │ │ ├── primaryExpressions/ │ │ │ │ ├── input.sh │ │ │ │ └── output.txt │ │ │ └── variables/ │ │ │ ├── input.sh │ │ │ └── output.txt │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── scripts/ │ │ │ ├── clone-fig.ps1 │ │ │ ├── clone-fig.sh │ │ │ ├── pullFishBuiltins.ts │ │ │ ├── pullZshBuiltins.ts │ │ │ ├── terminalScriptHelpers.ts │ │ │ ├── update-specs.js │ │ │ ├── update-specs.ps1 │ │ │ └── update-specs.sh │ │ ├── src/ │ │ │ ├── completions/ │ │ │ │ ├── cd.ts │ │ │ │ ├── code-insiders.ts │ │ │ │ ├── code-tunnel-insiders.ts │ │ │ │ ├── code-tunnel.ts │ │ │ │ ├── code.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── npx.ts │ │ │ │ ├── set-location.ts │ │ │ │ └── upstream/ │ │ │ │ ├── apt.ts │ │ │ │ ├── brew.ts │ │ │ │ ├── cat.ts │ │ │ │ ├── chmod.ts │ │ │ │ ├── chown.ts │ │ │ │ ├── cp.ts │ │ │ │ ├── curl.ts │ │ │ │ ├── df.ts │ │ │ │ ├── du.ts │ │ │ │ ├── echo.ts │ │ │ │ ├── find.ts │ │ │ │ ├── git.ts │ │ │ │ ├── grep.ts │ │ │ │ ├── head.ts │ │ │ │ ├── kill.ts │ │ │ │ ├── killall.ts │ │ │ │ ├── less.ts │ │ │ │ ├── ls.ts │ │ │ │ ├── mkdir.ts │ │ │ │ ├── more.ts │ │ │ │ ├── mv.ts │ │ │ │ ├── nano.ts │ │ │ │ ├── node.ts │ │ │ │ ├── npm.ts │ │ │ │ ├── nvm.ts │ │ │ │ ├── pnpm.ts │ │ │ │ ├── ps.ts │ │ │ │ ├── pwd.ts │ │ │ │ ├── python.ts │ │ │ │ ├── python3.ts │ │ │ │ ├── rm.ts │ │ │ │ ├── rmdir.ts │ │ │ │ ├── scp.ts │ │ │ │ ├── ssh.ts │ │ │ │ ├── tail.ts │ │ │ │ ├── top.ts │ │ │ │ ├── touch.ts │ │ │ │ ├── uname.ts │ │ │ │ ├── vim.ts │ │ │ │ ├── wget.ts │ │ │ │ └── yarn.ts │ │ │ ├── constants.ts │ │ │ ├── env/ │ │ │ │ └── pathExecutableCache.ts │ │ │ ├── fig/ │ │ │ │ ├── README.md │ │ │ │ ├── api-bindings/ │ │ │ │ │ └── types.ts │ │ │ │ ├── autocomplete/ │ │ │ │ │ ├── fig/ │ │ │ │ │ │ └── hooks.ts │ │ │ │ │ ├── generators/ │ │ │ │ │ │ ├── cache.ts │ │ │ │ │ │ ├── customSuggestionsGenerator.ts │ │ │ │ │ │ ├── helpers.ts │ │ │ │ │ │ └── scriptSuggestionsGenerator.ts │ │ │ │ │ └── state/ │ │ │ │ │ ├── generators.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── autocomplete-parser/ │ │ │ │ │ ├── caches.ts │ │ │ │ │ ├── errors.ts │ │ │ │ │ └── parseArguments.ts │ │ │ │ ├── execute.ts │ │ │ │ ├── fig-autocomplete-shared/ │ │ │ │ │ ├── convert.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── mixins.ts │ │ │ │ │ ├── revert.ts │ │ │ │ │ ├── specMetadata.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── figInterface.ts │ │ │ │ ├── shared/ │ │ │ │ │ ├── errors.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── internal.ts │ │ │ │ │ ├── test/ │ │ │ │ │ │ └── utils.test.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── shell-parser/ │ │ │ │ ├── command.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── index.ts │ │ │ │ ├── parser.ts │ │ │ │ └── test/ │ │ │ │ ├── command.test.ts │ │ │ │ └── parser.test.ts │ │ │ ├── helpers/ │ │ │ │ ├── completionItem.ts │ │ │ │ ├── executable.ts │ │ │ │ ├── file.ts │ │ │ │ ├── filepaths.ts │ │ │ │ ├── os.ts │ │ │ │ ├── promise.ts │ │ │ │ └── uri.ts │ │ │ ├── shell/ │ │ │ │ ├── bash.ts │ │ │ │ ├── common.ts │ │ │ │ ├── fish.ts │ │ │ │ ├── fishBuiltinsCache.ts │ │ │ │ ├── pwsh.ts │ │ │ │ ├── zsh.ts │ │ │ │ └── zshBuiltinsCache.ts │ │ │ ├── terminalSuggestMain.ts │ │ │ ├── test/ │ │ │ │ ├── completions/ │ │ │ │ │ ├── cd.test.ts │ │ │ │ │ ├── code-insiders.test.ts │ │ │ │ │ ├── code.test.ts │ │ │ │ │ └── upstream/ │ │ │ │ │ ├── echo.test.ts │ │ │ │ │ ├── git.test.ts │ │ │ │ │ ├── ls.test.ts │ │ │ │ │ ├── mkdir.test.ts │ │ │ │ │ ├── rm.test.ts │ │ │ │ │ ├── rmdir.test.ts │ │ │ │ │ └── touch.test.ts │ │ │ │ ├── env/ │ │ │ │ │ └── pathExecutableCache.test.ts │ │ │ │ ├── fig.test.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── terminalSuggestMain.test.ts │ │ │ │ └── tokens.test.ts │ │ │ ├── tokens.ts │ │ │ └── types.ts │ │ ├── testWorkspace/ │ │ │ └── parent/ │ │ │ └── home/ │ │ │ └── child/ │ │ │ └── .keep │ │ └── tsconfig.json │ ├── theme-abyss/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── abyss-color-theme.json │ ├── theme-defaults/ │ │ ├── fileicons/ │ │ │ └── vs_minimal-icon-theme.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ ├── dark_modern.json │ │ ├── dark_plus.json │ │ ├── dark_vs.json │ │ ├── hc_black.json │ │ ├── hc_light.json │ │ ├── light_modern.json │ │ ├── light_plus.json │ │ └── light_vs.json │ ├── theme-kimbie-dark/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── kimbie-dark-color-theme.json │ ├── theme-monokai/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── monokai-color-theme.json │ ├── theme-monokai-dimmed/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── dimmed-monokai-color-theme.json │ ├── theme-quietlight/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── quietlight-color-theme.json │ ├── theme-red/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── Red-color-theme.json │ ├── theme-seti/ │ │ ├── .vscodeignore │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── ThirdPartyNotices.txt │ │ ├── build/ │ │ │ └── update-icon-theme.js │ │ ├── cgmanifest.json │ │ ├── icons/ │ │ │ ├── preview.html │ │ │ └── vs-seti-icon-theme.json │ │ ├── package.json │ │ └── package.nls.json │ ├── theme-solarized-dark/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── solarized-dark-color-theme.json │ ├── theme-solarized-light/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── solarized-light-color-theme.json │ ├── theme-tomorrow-night-blue/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ └── themes/ │ │ └── tomorrow-night-blue-color-theme.json │ ├── tsconfig.base.json │ ├── tunnel-forwarding/ │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── src/ │ │ │ ├── deferredPromise.ts │ │ │ ├── extension.ts │ │ │ └── split.ts │ │ └── tsconfig.json │ ├── types/ │ │ ├── lib.textEncoder.d.ts │ │ └── lib.url.d.ts │ ├── typescript-basics/ │ │ ├── .vscodeignore │ │ ├── build/ │ │ │ └── update-grammars.mjs │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── typescript.code-snippets │ │ └── syntaxes/ │ │ ├── Readme.md │ │ ├── TypeScript.tmLanguage.json │ │ ├── TypeScriptReact.tmLanguage.json │ │ ├── jsdoc.js.injection.tmLanguage.json │ │ └── jsdoc.ts.injection.tmLanguage.json │ ├── typescript-language-features/ │ │ ├── .npmrc │ │ ├── .vscodeignore │ │ ├── README.md │ │ ├── cgmanifest.json │ │ ├── extension-browser.webpack.config.js │ │ ├── extension.webpack.config.js │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── schemas/ │ │ │ ├── jsconfig.schema.json │ │ │ ├── package.schema.json │ │ │ └── tsconfig.schema.json │ │ ├── src/ │ │ │ ├── api.ts │ │ │ ├── commands/ │ │ │ │ ├── commandManager.ts │ │ │ │ ├── configurePlugin.ts │ │ │ │ ├── goToProjectConfiguration.ts │ │ │ │ ├── index.ts │ │ │ │ ├── learnMoreAboutRefactorings.ts │ │ │ │ ├── openJsDocLink.ts │ │ │ │ ├── openTsServerLog.ts │ │ │ │ ├── reloadProject.ts │ │ │ │ ├── restartTsServer.ts │ │ │ │ ├── selectTypeScriptVersion.ts │ │ │ │ └── tsserverRequests.ts │ │ │ ├── configuration/ │ │ │ │ ├── configuration.browser.ts │ │ │ │ ├── configuration.electron.ts │ │ │ │ ├── configuration.ts │ │ │ │ ├── documentSelector.ts │ │ │ │ ├── fileSchemes.ts │ │ │ │ ├── languageDescription.ts │ │ │ │ ├── languageIds.ts │ │ │ │ └── schemes.ts │ │ │ ├── experimentTelemetryReporter.ts │ │ │ ├── experimentationService.ts │ │ │ ├── extension.browser.ts │ │ │ ├── extension.ts │ │ │ ├── filesystems/ │ │ │ │ ├── ata.ts │ │ │ │ ├── autoInstallerFs.ts │ │ │ │ └── memFs.ts │ │ │ ├── languageFeatures/ │ │ │ │ ├── callHierarchy.ts │ │ │ │ ├── codeLens/ │ │ │ │ │ ├── baseCodeLensProvider.ts │ │ │ │ │ ├── implementationsCodeLens.ts │ │ │ │ │ └── referencesCodeLens.ts │ │ │ │ ├── completions.ts │ │ │ │ ├── copyPaste.ts │ │ │ │ ├── definitionProviderBase.ts │ │ │ │ ├── definitions.ts │ │ │ │ ├── diagnostics.ts │ │ │ │ ├── directiveCommentCompletions.ts │ │ │ │ ├── documentHighlight.ts │ │ │ │ ├── documentSymbol.ts │ │ │ │ ├── fileConfigurationManager.ts │ │ │ │ ├── fileReferences.ts │ │ │ │ ├── fixAll.ts │ │ │ │ ├── folding.ts │ │ │ │ ├── formatting.ts │ │ │ │ ├── hover.ts │ │ │ │ ├── implementations.ts │ │ │ │ ├── inlayHints.ts │ │ │ │ ├── jsDocCompletions.ts │ │ │ │ ├── linkedEditing.ts │ │ │ │ ├── organizeImports.ts │ │ │ │ ├── quickFix.ts │ │ │ │ ├── refactor.ts │ │ │ │ ├── references.ts │ │ │ │ ├── rename.ts │ │ │ │ ├── semanticTokens.ts │ │ │ │ ├── signatureHelp.ts │ │ │ │ ├── smartSelect.ts │ │ │ │ ├── sourceDefinition.ts │ │ │ │ ├── tagClosing.ts │ │ │ │ ├── tsconfig.ts │ │ │ │ ├── typeDefinitions.ts │ │ │ │ ├── updatePathsOnRename.ts │ │ │ │ ├── util/ │ │ │ │ │ ├── codeAction.ts │ │ │ │ │ ├── copilot.ts │ │ │ │ │ ├── dependentRegistration.ts │ │ │ │ │ ├── snippetForFunctionCall.ts │ │ │ │ │ └── textRendering.ts │ │ │ │ └── workspaceSymbols.ts │ │ │ ├── languageProvider.ts │ │ │ ├── lazyClientHost.ts │ │ │ ├── logging/ │ │ │ │ ├── logLevelMonitor.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── telemetry.ts │ │ │ │ └── tracer.ts │ │ │ ├── remoteRepositories.browser.ts │ │ │ ├── task/ │ │ │ │ ├── taskProvider.ts │ │ │ │ └── tsconfigProvider.ts │ │ │ ├── test/ │ │ │ │ ├── index.ts │ │ │ │ ├── smoke/ │ │ │ │ │ ├── completions.test.ts │ │ │ │ │ ├── fixAll.test.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── jsDocCompletions.test.ts │ │ │ │ │ ├── quickFix.test.ts │ │ │ │ │ └── referencesCodeLens.test.ts │ │ │ │ ├── suggestTestHelpers.ts │ │ │ │ ├── testUtils.ts │ │ │ │ └── unit/ │ │ │ │ ├── cachedResponse.test.ts │ │ │ │ ├── functionCallSnippet.test.ts │ │ │ │ ├── index.ts │ │ │ │ ├── jsdocSnippet.test.ts │ │ │ │ ├── onEnter.test.ts │ │ │ │ ├── requestQueue.test.ts │ │ │ │ ├── server.test.ts │ │ │ │ └── textRendering.test.ts │ │ │ ├── test-all.ts │ │ │ ├── tsServer/ │ │ │ │ ├── api.ts │ │ │ │ ├── bufferSyncSupport.ts │ │ │ │ ├── cachedResponse.ts │ │ │ │ ├── callbackMap.ts │ │ │ │ ├── cancellation.electron.ts │ │ │ │ ├── cancellation.ts │ │ │ │ ├── fileWatchingManager.ts │ │ │ │ ├── logDirectoryProvider.electron.ts │ │ │ │ ├── logDirectoryProvider.ts │ │ │ │ ├── nodeManager.ts │ │ │ │ ├── pluginPathsProvider.ts │ │ │ │ ├── plugins.ts │ │ │ │ ├── protocol/ │ │ │ │ │ ├── errorCodes.ts │ │ │ │ │ ├── fixNames.ts │ │ │ │ │ ├── modifiers.ts │ │ │ │ │ ├── protocol.const.ts │ │ │ │ │ └── protocol.d.ts │ │ │ │ ├── requestQueue.ts │ │ │ │ ├── server.ts │ │ │ │ ├── serverError.ts │ │ │ │ ├── serverProcess.browser.ts │ │ │ │ ├── serverProcess.electron.ts │ │ │ │ ├── spawner.ts │ │ │ │ ├── versionManager.ts │ │ │ │ ├── versionProvider.electron.ts │ │ │ │ └── versionProvider.ts │ │ │ ├── tsconfig.ts │ │ │ ├── typeConverters.ts │ │ │ ├── typeScriptServiceClientHost.ts │ │ │ ├── typescriptService.ts │ │ │ ├── typescriptServiceClient.ts │ │ │ ├── ui/ │ │ │ │ ├── activeJsTsEditorTracker.ts │ │ │ │ ├── intellisenseStatus.ts │ │ │ │ ├── largeProjectStatus.ts │ │ │ │ ├── managedFileContext.ts │ │ │ │ ├── typingsStatus.ts │ │ │ │ └── versionStatus.ts │ │ │ └── utils/ │ │ │ ├── arrays.ts │ │ │ ├── async.ts │ │ │ ├── cancellation.ts │ │ │ ├── dispose.ts │ │ │ ├── fs.electron.ts │ │ │ ├── fs.ts │ │ │ ├── hash.ts │ │ │ ├── lazy.ts │ │ │ ├── memoize.ts │ │ │ ├── objects.ts │ │ │ ├── packageInfo.ts │ │ │ ├── platform.ts │ │ │ ├── regexp.ts │ │ │ ├── relativePathResolver.ts │ │ │ ├── resourceMap.ts │ │ │ └── temp.electron.ts │ │ ├── test-workspace/ │ │ │ ├── bar.ts │ │ │ ├── foo.ts │ │ │ ├── foojs.js │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ ├── tsconfig.json │ │ └── web/ │ │ ├── README.md │ │ ├── src/ │ │ │ ├── fileWatcherManager.ts │ │ │ ├── logging.ts │ │ │ ├── pathMapper.ts │ │ │ ├── serverHost.ts │ │ │ ├── typingsInstaller/ │ │ │ │ ├── jsTyping.ts │ │ │ │ └── typingsInstaller.ts │ │ │ ├── util/ │ │ │ │ ├── args.ts │ │ │ │ └── hrtime.ts │ │ │ ├── wasmCancellationToken.ts │ │ │ ├── webServer.ts │ │ │ └── workerSession.ts │ │ └── tsconfig.json │ ├── vb/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── language-configuration.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── snippets/ │ │ │ └── vb.code-snippets │ │ └── syntaxes/ │ │ └── asp-vb-net.tmLanguage.json │ ├── vscode-api-tests/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── .vscodeignore │ │ ├── package.json │ │ ├── src/ │ │ │ ├── extension.ts │ │ │ ├── memfs.ts │ │ │ ├── singlefolder-tests/ │ │ │ │ ├── chat.test.ts │ │ │ │ ├── commands.test.ts │ │ │ │ ├── configuration.test.ts │ │ │ │ ├── debug.test.ts │ │ │ │ ├── documentPaste.test.ts │ │ │ │ ├── editor.test.ts │ │ │ │ ├── env.test.ts │ │ │ │ ├── extensions.test.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interactiveWindow.test.ts │ │ │ │ ├── ipynb.test.ts │ │ │ │ ├── languagedetection.test.ts │ │ │ │ ├── languages.test.ts │ │ │ │ ├── lm.test.ts │ │ │ │ ├── notebook.api.test.ts │ │ │ │ ├── notebook.document.test.ts │ │ │ │ ├── notebook.editor.test.ts │ │ │ │ ├── notebook.kernel.test.ts │ │ │ │ ├── proxy.test.ts │ │ │ │ ├── quickInput.test.ts │ │ │ │ ├── readonlyFileSystem.test.ts │ │ │ │ ├── rpc.test.ts │ │ │ │ ├── state.test.ts │ │ │ │ ├── terminal.shellIntegration.test.ts │ │ │ │ ├── terminal.test.ts │ │ │ │ ├── types.test.ts │ │ │ │ ├── window.test.ts │ │ │ │ ├── workspace.event.test.ts │ │ │ │ ├── workspace.fs.test.ts │ │ │ │ ├── workspace.tasks.test.ts │ │ │ │ ├── workspace.test.ts │ │ │ │ └── workspace.watcher.test.ts │ │ │ ├── utils.ts │ │ │ └── workspace-tests/ │ │ │ ├── index.ts │ │ │ └── workspace.test.ts │ │ ├── testWorkspace/ │ │ │ ├── .vscode/ │ │ │ │ ├── launch.json │ │ │ │ └── settings.json │ │ │ ├── 10linefile.ts │ │ │ ├── 30linefile.ts │ │ │ ├── bower.json │ │ │ ├── debug.js │ │ │ ├── far.js │ │ │ ├── files-exclude/ │ │ │ │ └── file.txt │ │ │ ├── lorem.txt │ │ │ ├── myFile.ts │ │ │ ├── search-exclude/ │ │ │ │ └── file.txt │ │ │ ├── simple.txt │ │ │ └── test.ipynb │ │ ├── testWorkspace2/ │ │ │ ├── .vscode/ │ │ │ │ └── settings.json │ │ │ └── simple.txt │ │ ├── testworkspace.code-workspace │ │ └── tsconfig.json │ ├── vscode-colorize-perf-tests/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── colorizer.test.ts │ │ │ ├── colorizerTestMain.ts │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── colorize-fixtures/ │ │ │ ├── test-checker.ts │ │ │ ├── test-treeView.ts │ │ │ └── test.ts │ │ └── tsconfig.json │ ├── vscode-colorize-tests/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── package.json │ │ ├── producticons/ │ │ │ ├── index.html │ │ │ ├── mit_license.txt │ │ │ └── test-product-icon-theme.json │ │ ├── src/ │ │ │ ├── colorizer.test.ts │ │ │ ├── colorizerTestMain.ts │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── colorize-fixtures/ │ │ │ │ ├── 12750.html │ │ │ │ ├── 13448.html │ │ │ │ ├── 14119.less │ │ │ │ ├── 25920.html │ │ │ │ ├── COMMIT_EDITMSG │ │ │ │ ├── Dockerfile │ │ │ │ ├── basic.java │ │ │ │ ├── git-rebase-todo │ │ │ │ ├── issue-1550.yaml │ │ │ │ ├── issue-224862.yaml │ │ │ │ ├── issue-28354.php │ │ │ │ ├── issue-4008.yaml │ │ │ │ ├── issue-6303.yaml │ │ │ │ ├── issue-76997.php │ │ │ │ ├── makefile │ │ │ │ ├── md-math.md │ │ │ │ ├── test-13777.go │ │ │ │ ├── test-166781.rs │ │ │ │ ├── test-173216.sh │ │ │ │ ├── test-173224.sh │ │ │ │ ├── test-173336.sh │ │ │ │ ├── test-23630.cpp │ │ │ │ ├── test-23850.cpp │ │ │ │ ├── test-241001.ts │ │ │ │ ├── test-33886.md │ │ │ │ ├── test-4287.pug │ │ │ │ ├── test-6611.rs │ │ │ │ ├── test-7115.xml │ │ │ │ ├── test-78769.cpp │ │ │ │ ├── test-80644.cpp │ │ │ │ ├── test-brackets.tsx │ │ │ │ ├── test-cssvariables.less │ │ │ │ ├── test-cssvariables.scss │ │ │ │ ├── test-embedding.html │ │ │ │ ├── test-freeze-56377.py │ │ │ │ ├── test-freeze-56476.ps1 │ │ │ │ ├── test-function-inv.ts │ │ │ │ ├── test-issue11.ts │ │ │ │ ├── test-issue241715.ts │ │ │ │ ├── test-issue5431.ts │ │ │ │ ├── test-issue5465.ts │ │ │ │ ├── test-issue5566.ts │ │ │ │ ├── test-jsdoc-multiline-type.ts │ │ │ │ ├── test-keywords.ts │ │ │ │ ├── test-members.ts │ │ │ │ ├── test-object-literals.ts │ │ │ │ ├── test-regex.coffee │ │ │ │ ├── test-strings.ts │ │ │ │ ├── test-this.ts │ │ │ │ ├── test-variables.css │ │ │ │ ├── test.bat │ │ │ │ ├── test.bib │ │ │ │ ├── test.c │ │ │ │ ├── test.cc │ │ │ │ ├── test.clj │ │ │ │ ├── test.code-snippets │ │ │ │ ├── test.coffee │ │ │ │ ├── test.cpp │ │ │ │ ├── test.cs │ │ │ │ ├── test.cshtml │ │ │ │ ├── test.css │ │ │ │ ├── test.cu │ │ │ │ ├── test.dart │ │ │ │ ├── test.diff │ │ │ │ ├── test.fs │ │ │ │ ├── test.go │ │ │ │ ├── test.groovy │ │ │ │ ├── test.handlebars │ │ │ │ ├── test.hbs │ │ │ │ ├── test.hlsl │ │ │ │ ├── test.html │ │ │ │ ├── test.ini │ │ │ │ ├── test.jl │ │ │ │ ├── test.js │ │ │ │ ├── test.json │ │ │ │ ├── test.jsx │ │ │ │ ├── test.less │ │ │ │ ├── test.log │ │ │ │ ├── test.lua │ │ │ │ ├── test.m │ │ │ │ ├── test.md │ │ │ │ ├── test.mm │ │ │ │ ├── test.p6 │ │ │ │ ├── test.php │ │ │ │ ├── test.pl │ │ │ │ ├── test.ps1 │ │ │ │ ├── test.pug │ │ │ │ ├── test.py │ │ │ │ ├── test.r │ │ │ │ ├── test.rb │ │ │ │ ├── test.regexp.ts │ │ │ │ ├── test.rs │ │ │ │ ├── test.rst │ │ │ │ ├── test.scss │ │ │ │ ├── test.sh │ │ │ │ ├── test.shader │ │ │ │ ├── test.sql │ │ │ │ ├── test.sty │ │ │ │ ├── test.swift │ │ │ │ ├── test.tex │ │ │ │ ├── test.ts │ │ │ │ ├── test.vb │ │ │ │ ├── test.xml │ │ │ │ ├── test.yaml │ │ │ │ ├── test2.pl │ │ │ │ ├── test6916.js │ │ │ │ └── tsconfig_off.json │ │ │ ├── colorize-results/ │ │ │ │ ├── 12750_html.json │ │ │ │ ├── 13448_html.json │ │ │ │ ├── 14119_less.json │ │ │ │ ├── 25920_html.json │ │ │ │ ├── COMMIT_EDITMSG.json │ │ │ │ ├── Dockerfile.json │ │ │ │ ├── basic_java.json │ │ │ │ ├── git-rebase-todo.json │ │ │ │ ├── issue-1550_yaml.json │ │ │ │ ├── issue-224862_yaml.json │ │ │ │ ├── issue-28354_php.json │ │ │ │ ├── issue-4008_yaml.json │ │ │ │ ├── issue-6303_yaml.json │ │ │ │ ├── issue-76997_php.json │ │ │ │ ├── makefile.json │ │ │ │ ├── md-math_md.json │ │ │ │ ├── test-13777_go.json │ │ │ │ ├── test-166781_rs.json │ │ │ │ ├── test-173216_sh.json │ │ │ │ ├── test-173224_sh.json │ │ │ │ ├── test-173336_sh.json │ │ │ │ ├── test-23630_cpp.json │ │ │ │ ├── test-23850_cpp.json │ │ │ │ ├── test-241001_ts.json │ │ │ │ ├── test-33886_md.json │ │ │ │ ├── test-4287_pug.json │ │ │ │ ├── test-6611_rs.json │ │ │ │ ├── test-7115_xml.json │ │ │ │ ├── test-78769_cpp.json │ │ │ │ ├── test-80644_cpp.json │ │ │ │ ├── test-brackets_tsx.json │ │ │ │ ├── test-cssvariables_less.json │ │ │ │ ├── test-cssvariables_scss.json │ │ │ │ ├── test-embedding_html.json │ │ │ │ ├── test-freeze-56377_py.json │ │ │ │ ├── test-freeze-56476_ps1.json │ │ │ │ ├── test-function-inv_ts.json │ │ │ │ ├── test-issue11_ts.json │ │ │ │ ├── test-issue241715_ts.json │ │ │ │ ├── test-issue5431_ts.json │ │ │ │ ├── test-issue5465_ts.json │ │ │ │ ├── test-issue5566_ts.json │ │ │ │ ├── test-jsdoc-multiline-type_ts.json │ │ │ │ ├── test-keywords_ts.json │ │ │ │ ├── test-members_ts.json │ │ │ │ ├── test-object-literals_ts.json │ │ │ │ ├── test-regex_coffee.json │ │ │ │ ├── test-strings_ts.json │ │ │ │ ├── test-this_ts.json │ │ │ │ ├── test-variables_css.json │ │ │ │ ├── test2_pl.json │ │ │ │ ├── test6916_js.json │ │ │ │ ├── test_bat.json │ │ │ │ ├── test_bib.json │ │ │ │ ├── test_c.json │ │ │ │ ├── test_cc.json │ │ │ │ ├── test_clj.json │ │ │ │ ├── test_code-snippets.json │ │ │ │ ├── test_coffee.json │ │ │ │ ├── test_cpp.json │ │ │ │ ├── test_cs.json │ │ │ │ ├── test_cshtml.json │ │ │ │ ├── test_css.json │ │ │ │ ├── test_cu.json │ │ │ │ ├── test_dart.json │ │ │ │ ├── test_diff.json │ │ │ │ ├── test_fs.json │ │ │ │ ├── test_go.json │ │ │ │ ├── test_groovy.json │ │ │ │ ├── test_handlebars.json │ │ │ │ ├── test_hbs.json │ │ │ │ ├── test_hlsl.json │ │ │ │ ├── test_html.json │ │ │ │ ├── test_ini.json │ │ │ │ ├── test_jl.json │ │ │ │ ├── test_js.json │ │ │ │ ├── test_json.json │ │ │ │ ├── test_jsx.json │ │ │ │ ├── test_less.json │ │ │ │ ├── test_log.json │ │ │ │ ├── test_lua.json │ │ │ │ ├── test_m.json │ │ │ │ ├── test_md.json │ │ │ │ ├── test_mm.json │ │ │ │ ├── test_p6.json │ │ │ │ ├── test_php.json │ │ │ │ ├── test_pl.json │ │ │ │ ├── test_ps1.json │ │ │ │ ├── test_pug.json │ │ │ │ ├── test_py.json │ │ │ │ ├── test_r.json │ │ │ │ ├── test_rb.json │ │ │ │ ├── test_regexp.ts.json │ │ │ │ ├── test_rs.json │ │ │ │ ├── test_rst.json │ │ │ │ ├── test_scss.json │ │ │ │ ├── test_sh.json │ │ │ │ ├── test_shader.json │ │ │ │ ├── test_sql.json │ │ │ │ ├── test_sty.json │ │ │ │ ├── test_swift.json │ │ │ │ ├── test_tex.json │ │ │ │ ├── test_ts.json │ │ │ │ ├── test_vb.json │ │ │ │ ├── test_xml.json │ │ │ │ ├── test_yaml.json │ │ │ │ └── tsconfig_off_json.json │ │ │ ├── colorize-tree-sitter-results/ │ │ │ │ ├── 12750_html.json │ │ │ │ ├── 13448_html.json │ │ │ │ ├── 14119_less.json │ │ │ │ ├── 25920_html.json │ │ │ │ ├── COMMIT_EDITMSG.json │ │ │ │ ├── Dockerfile.json │ │ │ │ ├── basic_java.json │ │ │ │ ├── git-rebase-todo.json │ │ │ │ ├── issue-1550_yaml.json │ │ │ │ ├── issue-224862_yaml.json │ │ │ │ ├── issue-28354_php.json │ │ │ │ ├── issue-4008_yaml.json │ │ │ │ ├── issue-6303_yaml.json │ │ │ │ ├── issue-76997_php.json │ │ │ │ ├── makefile.json │ │ │ │ ├── md-math_md.json │ │ │ │ ├── test-13777_go.json │ │ │ │ ├── test-166781_rs.json │ │ │ │ ├── test-173216_sh.json │ │ │ │ ├── test-173224_sh.json │ │ │ │ ├── test-173336_sh.json │ │ │ │ ├── test-23630_cpp.json │ │ │ │ ├── test-23850_cpp.json │ │ │ │ ├── test-241001_ts.json │ │ │ │ ├── test-33886_md.json │ │ │ │ ├── test-4287_pug.json │ │ │ │ ├── test-6611_rs.json │ │ │ │ ├── test-7115_xml.json │ │ │ │ ├── test-78769_cpp.json │ │ │ │ ├── test-80644_cpp.json │ │ │ │ ├── test-brackets_tsx.json │ │ │ │ ├── test-cssvariables_less.json │ │ │ │ ├── test-cssvariables_scss.json │ │ │ │ ├── test-embedding_html.json │ │ │ │ ├── test-freeze-56377_py.json │ │ │ │ ├── test-freeze-56476_ps1.json │ │ │ │ ├── test-function-inv_ts.json │ │ │ │ ├── test-issue11_ts.json │ │ │ │ ├── test-issue241715_ts.json │ │ │ │ ├── test-issue5431_ts.json │ │ │ │ ├── test-issue5465_ts.json │ │ │ │ ├── test-issue5566_ts.json │ │ │ │ ├── test-jsdoc-multiline-type_ts.json │ │ │ │ ├── test-keywords_ts.json │ │ │ │ ├── test-members_ts.json │ │ │ │ ├── test-object-literals_ts.json │ │ │ │ ├── test-regex_coffee.json │ │ │ │ ├── test-strings_ts.json │ │ │ │ ├── test-this_ts.json │ │ │ │ ├── test-variables_css.json │ │ │ │ ├── test2_pl.json │ │ │ │ ├── test6916_js.json │ │ │ │ ├── test_bat.json │ │ │ │ ├── test_bib.json │ │ │ │ ├── test_c.json │ │ │ │ ├── test_cc.json │ │ │ │ ├── test_clj.json │ │ │ │ ├── test_code-snippets.json │ │ │ │ ├── test_coffee.json │ │ │ │ ├── test_cpp.json │ │ │ │ ├── test_cs.json │ │ │ │ ├── test_cshtml.json │ │ │ │ ├── test_css.json │ │ │ │ ├── test_cu.json │ │ │ │ ├── test_dart.json │ │ │ │ ├── test_diff.json │ │ │ │ ├── test_fs.json │ │ │ │ ├── test_go.json │ │ │ │ ├── test_groovy.json │ │ │ │ ├── test_handlebars.json │ │ │ │ ├── test_hbs.json │ │ │ │ ├── test_hlsl.json │ │ │ │ ├── test_html.json │ │ │ │ ├── test_ini.json │ │ │ │ ├── test_jl.json │ │ │ │ ├── test_js.json │ │ │ │ ├── test_json.json │ │ │ │ ├── test_jsx.json │ │ │ │ ├── test_less.json │ │ │ │ ├── test_log.json │ │ │ │ ├── test_lua.json │ │ │ │ ├── test_m.json │ │ │ │ ├── test_md.json │ │ │ │ ├── test_mm.json │ │ │ │ ├── test_p6.json │ │ │ │ ├── test_php.json │ │ │ │ ├── test_pl.json │ │ │ │ ├── test_ps1.json │ │ │ │ ├── test_pug.json │ │ │ │ ├── test_py.json │ │ │ │ ├── test_r.json │ │ │ │ ├── test_rb.json │ │ │ │ ├── test_regexp.ts.json │ │ │ │ ├── test_rs.json │ │ │ │ ├── test_rst.json │ │ │ │ ├── test_scss.json │ │ │ │ ├── test_sh.json │ │ │ │ ├── test_shader.json │ │ │ │ ├── test_sql.json │ │ │ │ ├── test_sty.json │ │ │ │ ├── test_swift.json │ │ │ │ ├── test_tex.json │ │ │ │ ├── test_ts.json │ │ │ │ ├── test_vb.json │ │ │ │ ├── test_xml.json │ │ │ │ ├── test_yaml.json │ │ │ │ └── tsconfig_off_json.json │ │ │ └── semantic-test/ │ │ │ ├── .vscode/ │ │ │ │ └── settings.json │ │ │ └── semantic-test.json │ │ └── tsconfig.json │ ├── vscode-test-resolver/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .vscode/ │ │ │ └── launch.json │ │ ├── .vscodeignore │ │ ├── extension-browser.webpack.config.js │ │ ├── package.json │ │ ├── scripts/ │ │ │ └── terminateProcess.sh │ │ ├── src/ │ │ │ ├── download.ts │ │ │ ├── extension.browser.ts │ │ │ ├── extension.ts │ │ │ └── util/ │ │ │ └── processes.ts │ │ └── tsconfig.json │ ├── xml/ │ │ ├── .vscodeignore │ │ ├── cgmanifest.json │ │ ├── package.json │ │ ├── package.nls.json │ │ ├── syntaxes/ │ │ │ ├── xml.tmLanguage.json │ │ │ └── xsl.tmLanguage.json │ │ ├── xml.language-configuration.json │ │ └── xsl.language-configuration.json │ └── yaml/ │ ├── .vscodeignore │ ├── build/ │ │ └── update-grammar.js │ ├── cgmanifest.json │ ├── language-configuration.json │ ├── package.json │ ├── package.nls.json │ └── syntaxes/ │ ├── yaml-1.0.tmLanguage.json │ ├── yaml-1.1.tmLanguage.json │ ├── yaml-1.2.tmLanguage.json │ ├── yaml-1.3.tmLanguage.json │ ├── yaml-embedded.tmLanguage.json │ └── yaml.tmLanguage.json ├── gulpfile.js ├── package.json ├── product.json ├── remote/ │ ├── .npmrc │ ├── package.json │ └── web/ │ ├── .npmrc │ └── package.json ├── resources/ │ ├── completions/ │ │ ├── bash/ │ │ │ └── code │ │ └── zsh/ │ │ └── _code │ ├── darwin/ │ │ ├── bat.icns │ │ ├── bin/ │ │ │ └── code.sh │ │ ├── bower.icns │ │ ├── c.icns │ │ ├── code.icns │ │ ├── config.icns │ │ ├── cpp.icns │ │ ├── csharp.icns │ │ ├── css.icns │ │ ├── default.icns │ │ ├── go.icns │ │ ├── html.icns │ │ ├── jade.icns │ │ ├── java.icns │ │ ├── javascript.icns │ │ ├── json.icns │ │ ├── less.icns │ │ ├── markdown.icns │ │ ├── php.icns │ │ ├── powershell.icns │ │ ├── python.icns │ │ ├── react.icns │ │ ├── ruby.icns │ │ ├── sass.icns │ │ ├── shell.icns │ │ ├── sql.icns │ │ ├── typescript.icns │ │ ├── vue.icns │ │ ├── xml.icns │ │ └── yaml.icns │ ├── linux/ │ │ ├── bin/ │ │ │ └── code.sh │ │ ├── code-url-handler.desktop │ │ ├── code-workspace.xml │ │ ├── code.appdata.xml │ │ ├── code.desktop │ │ ├── debian/ │ │ │ ├── control.template │ │ │ ├── postinst.template │ │ │ ├── postrm.template │ │ │ ├── prerm.template │ │ │ └── templates.template │ │ ├── rpm/ │ │ │ ├── code.spec.template │ │ │ └── code.xpm │ │ └── snap/ │ │ ├── electron-launch │ │ └── snapcraft.yaml │ ├── server/ │ │ ├── bin/ │ │ │ ├── code-server-darwin.sh │ │ │ ├── code-server-linux.sh │ │ │ ├── code-server.cmd │ │ │ ├── helpers/ │ │ │ │ ├── browser-darwin.sh │ │ │ │ ├── browser-linux.sh │ │ │ │ ├── browser.cmd │ │ │ │ └── check-requirements-linux.sh │ │ │ └── remote-cli/ │ │ │ ├── code-darwin.sh │ │ │ ├── code-linux.sh │ │ │ └── code.cmd │ │ ├── bin-dev/ │ │ │ ├── helpers/ │ │ │ │ ├── browser.cmd │ │ │ │ └── browser.sh │ │ │ └── remote-cli/ │ │ │ ├── code.cmd │ │ │ └── code.sh │ │ └── manifest.json │ └── win32/ │ ├── VisualElementsManifest.xml │ └── bin/ │ ├── code.cmd │ └── code.sh ├── scripts/ │ ├── appimage/ │ │ ├── create-appimage-old.sh │ │ ├── create_appimage.sh │ │ ├── readme.md │ │ ├── void-url-handler.desktop │ │ └── void.desktop │ ├── code-cli.bat │ ├── code-cli.sh │ ├── code-perf.js │ ├── code-server.bat │ ├── code-server.js │ ├── code-server.sh │ ├── code-web.bat │ ├── code-web.js │ ├── code-web.sh │ ├── code.bat │ ├── code.sh │ ├── generate-definitelytyped.sh │ ├── node-electron.bat │ ├── node-electron.sh │ ├── package.json │ ├── playground-server.ts │ ├── test-documentation.bat │ ├── test-documentation.sh │ ├── test-integration.bat │ ├── test-integration.sh │ ├── test-remote-integration.bat │ ├── test-remote-integration.sh │ ├── test-web-integration.bat │ ├── test-web-integration.sh │ ├── test.bat │ ├── test.sh │ ├── xterm-symlink.ps1 │ ├── xterm-update.js │ └── xterm-update.ps1 ├── src/ │ ├── bootstrap-cli.ts │ ├── bootstrap-esm.ts │ ├── bootstrap-fork.ts │ ├── bootstrap-import.ts │ ├── bootstrap-meta.ts │ ├── bootstrap-node.ts │ ├── bootstrap-server.ts │ ├── bootstrap-window.ts │ ├── cli.ts │ ├── main.ts │ ├── server-cli.ts │ ├── server-main.ts │ ├── tsconfig.base.json │ ├── tsconfig.json │ ├── tsconfig.monaco.json │ ├── tsconfig.tsec.json │ ├── tsconfig.vscode-dts.json │ ├── tsconfig.vscode-proposed-dts.json │ ├── tsec.exemptions.json │ ├── typings/ │ │ ├── base-common.d.ts │ │ ├── crypto.d.ts │ │ ├── editContext.d.ts │ │ ├── thenable.d.ts │ │ ├── vscode-globals-nls.d.ts │ │ ├── vscode-globals-product.d.ts │ │ └── vscode-globals-ttp.d.ts │ ├── vs/ │ │ ├── amdX.ts │ │ ├── base/ │ │ │ ├── browser/ │ │ │ │ ├── broadcast.ts │ │ │ │ ├── browser.ts │ │ │ │ ├── canIUse.ts │ │ │ │ ├── contextmenu.ts │ │ │ │ ├── cssValue.ts │ │ │ │ ├── deviceAccess.ts │ │ │ │ ├── dnd.ts │ │ │ │ ├── dom.ts │ │ │ │ ├── domImpl/ │ │ │ │ │ ├── domObservable.ts │ │ │ │ │ └── n.ts │ │ │ │ ├── domStylesheets.ts │ │ │ │ ├── dompurify/ │ │ │ │ │ ├── cgmanifest.json │ │ │ │ │ ├── dompurify.d.ts │ │ │ │ │ ├── dompurify.js │ │ │ │ │ └── dompurify.license.txt │ │ │ │ ├── event.ts │ │ │ │ ├── fastDomNode.ts │ │ │ │ ├── fonts.ts │ │ │ │ ├── formattedTextRenderer.ts │ │ │ │ ├── globalPointerMoveMonitor.ts │ │ │ │ ├── history.ts │ │ │ │ ├── iframe.ts │ │ │ │ ├── indexedDB.ts │ │ │ │ ├── keyboardEvent.ts │ │ │ │ ├── markdownRenderer.ts │ │ │ │ ├── mouseEvent.ts │ │ │ │ ├── performance.ts │ │ │ │ ├── pixelRatio.ts │ │ │ │ ├── touch.ts │ │ │ │ ├── trustedTypes.ts │ │ │ │ ├── ui/ │ │ │ │ │ ├── actionbar/ │ │ │ │ │ │ ├── actionViewItems.ts │ │ │ │ │ │ ├── actionbar.css │ │ │ │ │ │ └── actionbar.ts │ │ │ │ │ ├── aria/ │ │ │ │ │ │ ├── aria.css │ │ │ │ │ │ └── aria.ts │ │ │ │ │ ├── breadcrumbs/ │ │ │ │ │ │ ├── breadcrumbsWidget.css │ │ │ │ │ │ └── breadcrumbsWidget.ts │ │ │ │ │ ├── button/ │ │ │ │ │ │ ├── button.css │ │ │ │ │ │ └── button.ts │ │ │ │ │ ├── centered/ │ │ │ │ │ │ └── centeredViewLayout.ts │ │ │ │ │ ├── codicons/ │ │ │ │ │ │ ├── codicon/ │ │ │ │ │ │ │ ├── codicon-modifiers.css │ │ │ │ │ │ │ └── codicon.css │ │ │ │ │ │ └── codiconStyles.ts │ │ │ │ │ ├── contextview/ │ │ │ │ │ │ ├── contextview.css │ │ │ │ │ │ └── contextview.ts │ │ │ │ │ ├── countBadge/ │ │ │ │ │ │ ├── countBadge.css │ │ │ │ │ │ └── countBadge.ts │ │ │ │ │ ├── dialog/ │ │ │ │ │ │ ├── dialog.css │ │ │ │ │ │ └── dialog.ts │ │ │ │ │ ├── dnd/ │ │ │ │ │ │ ├── dnd.css │ │ │ │ │ │ └── dnd.ts │ │ │ │ │ ├── dropdown/ │ │ │ │ │ │ ├── dropdown.css │ │ │ │ │ │ ├── dropdown.ts │ │ │ │ │ │ └── dropdownActionViewItem.ts │ │ │ │ │ ├── findinput/ │ │ │ │ │ │ ├── findInput.css │ │ │ │ │ │ ├── findInput.ts │ │ │ │ │ │ ├── findInputToggles.ts │ │ │ │ │ │ └── replaceInput.ts │ │ │ │ │ ├── grid/ │ │ │ │ │ │ ├── grid.ts │ │ │ │ │ │ ├── gridview.css │ │ │ │ │ │ └── gridview.ts │ │ │ │ │ ├── highlightedlabel/ │ │ │ │ │ │ └── highlightedLabel.ts │ │ │ │ │ ├── hover/ │ │ │ │ │ │ ├── hover.ts │ │ │ │ │ │ ├── hoverDelegate.ts │ │ │ │ │ │ ├── hoverDelegate2.ts │ │ │ │ │ │ ├── hoverDelegateFactory.ts │ │ │ │ │ │ ├── hoverWidget.css │ │ │ │ │ │ └── hoverWidget.ts │ │ │ │ │ ├── iconLabel/ │ │ │ │ │ │ ├── iconLabel.ts │ │ │ │ │ │ ├── iconLabels.ts │ │ │ │ │ │ ├── iconlabel.css │ │ │ │ │ │ └── simpleIconLabel.ts │ │ │ │ │ ├── icons/ │ │ │ │ │ │ ├── iconSelectBox.css │ │ │ │ │ │ └── iconSelectBox.ts │ │ │ │ │ ├── inputbox/ │ │ │ │ │ │ ├── inputBox.css │ │ │ │ │ │ └── inputBox.ts │ │ │ │ │ ├── keybindingLabel/ │ │ │ │ │ │ ├── keybindingLabel.css │ │ │ │ │ │ └── keybindingLabel.ts │ │ │ │ │ ├── list/ │ │ │ │ │ │ ├── list.css │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ ├── listPaging.ts │ │ │ │ │ │ ├── listView.ts │ │ │ │ │ │ ├── listWidget.ts │ │ │ │ │ │ ├── rangeMap.ts │ │ │ │ │ │ ├── rowCache.ts │ │ │ │ │ │ └── splice.ts │ │ │ │ │ ├── menu/ │ │ │ │ │ │ ├── menu.ts │ │ │ │ │ │ ├── menubar.css │ │ │ │ │ │ └── menubar.ts │ │ │ │ │ ├── mouseCursor/ │ │ │ │ │ │ ├── mouseCursor.css │ │ │ │ │ │ └── mouseCursor.ts │ │ │ │ │ ├── progressbar/ │ │ │ │ │ │ ├── progressAccessibilitySignal.ts │ │ │ │ │ │ ├── progressbar.css │ │ │ │ │ │ └── progressbar.ts │ │ │ │ │ ├── radio/ │ │ │ │ │ │ ├── radio.css │ │ │ │ │ │ └── radio.ts │ │ │ │ │ ├── resizable/ │ │ │ │ │ │ └── resizable.ts │ │ │ │ │ ├── sash/ │ │ │ │ │ │ ├── sash.css │ │ │ │ │ │ └── sash.ts │ │ │ │ │ ├── scrollbar/ │ │ │ │ │ │ ├── abstractScrollbar.ts │ │ │ │ │ │ ├── horizontalScrollbar.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── scrollbars.css │ │ │ │ │ │ ├── scrollableElement.ts │ │ │ │ │ │ ├── scrollableElementOptions.ts │ │ │ │ │ │ ├── scrollbarArrow.ts │ │ │ │ │ │ ├── scrollbarState.ts │ │ │ │ │ │ ├── scrollbarVisibilityController.ts │ │ │ │ │ │ └── verticalScrollbar.ts │ │ │ │ │ ├── selectBox/ │ │ │ │ │ │ ├── selectBox.css │ │ │ │ │ │ ├── selectBox.ts │ │ │ │ │ │ ├── selectBoxCustom.css │ │ │ │ │ │ ├── selectBoxCustom.ts │ │ │ │ │ │ └── selectBoxNative.ts │ │ │ │ │ ├── severityIcon/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── severityIcon.css │ │ │ │ │ │ └── severityIcon.ts │ │ │ │ │ ├── splitview/ │ │ │ │ │ │ ├── paneview.css │ │ │ │ │ │ ├── paneview.ts │ │ │ │ │ │ ├── splitview.css │ │ │ │ │ │ └── splitview.ts │ │ │ │ │ ├── table/ │ │ │ │ │ │ ├── table.css │ │ │ │ │ │ ├── table.ts │ │ │ │ │ │ └── tableWidget.ts │ │ │ │ │ ├── toggle/ │ │ │ │ │ │ ├── toggle.css │ │ │ │ │ │ └── toggle.ts │ │ │ │ │ ├── toolbar/ │ │ │ │ │ │ ├── toolbar.css │ │ │ │ │ │ └── toolbar.ts │ │ │ │ │ ├── tree/ │ │ │ │ │ │ ├── abstractTree.ts │ │ │ │ │ │ ├── asyncDataTree.ts │ │ │ │ │ │ ├── compressedObjectTreeModel.ts │ │ │ │ │ │ ├── dataTree.ts │ │ │ │ │ │ ├── indexTree.ts │ │ │ │ │ │ ├── indexTreeModel.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ ├── paneviewlet.css │ │ │ │ │ │ │ └── tree.css │ │ │ │ │ │ ├── objectTree.ts │ │ │ │ │ │ ├── objectTreeModel.ts │ │ │ │ │ │ ├── tree.ts │ │ │ │ │ │ └── treeDefaults.ts │ │ │ │ │ └── widget.ts │ │ │ │ ├── webWorkerFactory.ts │ │ │ │ └── window.ts │ │ │ ├── common/ │ │ │ │ ├── actions.ts │ │ │ │ ├── arrays.ts │ │ │ │ ├── arraysFind.ts │ │ │ │ ├── assert.ts │ │ │ │ ├── async.ts │ │ │ │ ├── buffer.ts │ │ │ │ ├── cache.ts │ │ │ │ ├── cancellation.ts │ │ │ │ ├── charCode.ts │ │ │ │ ├── codecs/ │ │ │ │ │ ├── asyncDecoder.ts │ │ │ │ │ ├── baseDecoder.ts │ │ │ │ │ └── types/ │ │ │ │ │ └── ICodec.d.ts │ │ │ │ ├── codicons.ts │ │ │ │ ├── codiconsLibrary.ts │ │ │ │ ├── codiconsUtil.ts │ │ │ │ ├── collections.ts │ │ │ │ ├── color.ts │ │ │ │ ├── comparers.ts │ │ │ │ ├── console.ts │ │ │ │ ├── controlFlow.ts │ │ │ │ ├── dataTransfer.ts │ │ │ │ ├── date.ts │ │ │ │ ├── decorators/ │ │ │ │ │ └── cancelPreviousCalls.ts │ │ │ │ ├── decorators.ts │ │ │ │ ├── desktopEnvironmentInfo.ts │ │ │ │ ├── diff/ │ │ │ │ │ ├── diff.ts │ │ │ │ │ └── diffChange.ts │ │ │ │ ├── envfile.ts │ │ │ │ ├── equals.ts │ │ │ │ ├── errorMessage.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── event.ts │ │ │ │ ├── extpath.ts │ │ │ │ ├── filters.ts │ │ │ │ ├── functional.ts │ │ │ │ ├── fuzzyScorer.ts │ │ │ │ ├── glob.ts │ │ │ │ ├── hash.ts │ │ │ │ ├── hierarchicalKind.ts │ │ │ │ ├── history.ts │ │ │ │ ├── hotReload.ts │ │ │ │ ├── hotReloadHelpers.ts │ │ │ │ ├── htmlContent.ts │ │ │ │ ├── iconLabels.ts │ │ │ │ ├── idGenerator.ts │ │ │ │ ├── ime.ts │ │ │ │ ├── iterator.ts │ │ │ │ ├── json.ts │ │ │ │ ├── jsonEdit.ts │ │ │ │ ├── jsonErrorMessages.ts │ │ │ │ ├── jsonFormatter.ts │ │ │ │ ├── jsonSchema.ts │ │ │ │ ├── jsonc.ts │ │ │ │ ├── keyCodes.ts │ │ │ │ ├── keybindingLabels.ts │ │ │ │ ├── keybindingParser.ts │ │ │ │ ├── keybindings.ts │ │ │ │ ├── labels.ts │ │ │ │ ├── lazy.ts │ │ │ │ ├── lifecycle.ts │ │ │ │ ├── linkedList.ts │ │ │ │ ├── linkedText.ts │ │ │ │ ├── map.ts │ │ │ │ ├── marked/ │ │ │ │ │ ├── cgmanifest.json │ │ │ │ │ ├── marked.d.ts │ │ │ │ │ ├── marked.js │ │ │ │ │ └── marked.license.txt │ │ │ │ ├── marshalling.ts │ │ │ │ ├── marshallingIds.ts │ │ │ │ ├── mime.ts │ │ │ │ ├── naturalLanguage/ │ │ │ │ │ └── korean.ts │ │ │ │ ├── navigator.ts │ │ │ │ ├── network.ts │ │ │ │ ├── normalization.ts │ │ │ │ ├── numbers.ts │ │ │ │ ├── objectCache.ts │ │ │ │ ├── objects.ts │ │ │ │ ├── observable.ts │ │ │ │ ├── observableDisposable.ts │ │ │ │ ├── observableInternal/ │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── autorun.ts │ │ │ │ │ ├── base.ts │ │ │ │ │ ├── commonFacade/ │ │ │ │ │ │ ├── cancellation.ts │ │ │ │ │ │ └── deps.ts │ │ │ │ │ ├── debugName.ts │ │ │ │ │ ├── derived.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── lazyObservableValue.ts │ │ │ │ │ ├── logging/ │ │ │ │ │ │ ├── consoleObservableLogger.ts │ │ │ │ │ │ ├── debugger/ │ │ │ │ │ │ │ ├── debuggerApi.d.ts │ │ │ │ │ │ │ ├── debuggerRpc.ts │ │ │ │ │ │ │ ├── devToolsLogger.ts │ │ │ │ │ │ │ ├── rpc.ts │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ └── logging.ts │ │ │ │ │ ├── promise.ts │ │ │ │ │ ├── utils.ts │ │ │ │ │ └── utilsCancellation.ts │ │ │ │ ├── paging.ts │ │ │ │ ├── parsers.ts │ │ │ │ ├── path.ts │ │ │ │ ├── performance.ts │ │ │ │ ├── platform.ts │ │ │ │ ├── policy.ts │ │ │ │ ├── ports.ts │ │ │ │ ├── prefixTree.ts │ │ │ │ ├── process.ts │ │ │ │ ├── processes.ts │ │ │ │ ├── product.ts │ │ │ │ ├── range.ts │ │ │ │ ├── resourceTree.ts │ │ │ │ ├── resources.ts │ │ │ │ ├── scrollable.ts │ │ │ │ ├── search.ts │ │ │ │ ├── semver/ │ │ │ │ │ ├── cgmanifest.json │ │ │ │ │ ├── semver.d.ts │ │ │ │ │ └── semver.js │ │ │ │ ├── sequence.ts │ │ │ │ ├── severity.ts │ │ │ │ ├── skipList.ts │ │ │ │ ├── stopwatch.ts │ │ │ │ ├── stream.ts │ │ │ │ ├── strings.ts │ │ │ │ ├── symbols.ts │ │ │ │ ├── ternarySearchTree.ts │ │ │ │ ├── tfIdf.ts │ │ │ │ ├── themables.ts │ │ │ │ ├── types.ts │ │ │ │ ├── uint.ts │ │ │ │ ├── uri.ts │ │ │ │ ├── uriIpc.ts │ │ │ │ ├── uuid.ts │ │ │ │ ├── verifier.ts │ │ │ │ └── worker/ │ │ │ │ ├── webWorker.ts │ │ │ │ └── webWorkerBootstrap.ts │ │ │ ├── node/ │ │ │ │ ├── cpuUsage.sh │ │ │ │ ├── crypto.ts │ │ │ │ ├── extpath.ts │ │ │ │ ├── id.ts │ │ │ │ ├── macAddress.ts │ │ │ │ ├── nls.ts │ │ │ │ ├── nodeStreams.ts │ │ │ │ ├── osDisplayProtocolInfo.ts │ │ │ │ ├── osReleaseInfo.ts │ │ │ │ ├── pfs.ts │ │ │ │ ├── ports.ts │ │ │ │ ├── powershell.ts │ │ │ │ ├── processes.ts │ │ │ │ ├── ps.sh │ │ │ │ ├── ps.ts │ │ │ │ ├── shell.ts │ │ │ │ ├── terminalEncoding.ts │ │ │ │ ├── terminateProcess.sh │ │ │ │ ├── unc.ts │ │ │ │ └── zip.ts │ │ │ ├── parts/ │ │ │ │ ├── contextmenu/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── contextmenu.ts │ │ │ │ │ ├── electron-main/ │ │ │ │ │ │ └── contextmenu.ts │ │ │ │ │ └── electron-sandbox/ │ │ │ │ │ └── contextmenu.ts │ │ │ │ ├── ipc/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── ipc.mp.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── ipc.electron.ts │ │ │ │ │ │ ├── ipc.mp.ts │ │ │ │ │ │ ├── ipc.net.ts │ │ │ │ │ │ └── ipc.ts │ │ │ │ │ ├── electron-main/ │ │ │ │ │ │ ├── ipc.electron.ts │ │ │ │ │ │ ├── ipc.mp.ts │ │ │ │ │ │ └── ipcMain.ts │ │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ │ ├── ipc.electron.ts │ │ │ │ │ │ └── ipc.mp.ts │ │ │ │ │ ├── node/ │ │ │ │ │ │ ├── ipc.cp.ts │ │ │ │ │ │ ├── ipc.mp.ts │ │ │ │ │ │ └── ipc.net.ts │ │ │ │ │ └── test/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── ipc.mp.test.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── ipc.test.ts │ │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ │ └── ipc.mp.test.ts │ │ │ │ │ └── node/ │ │ │ │ │ ├── ipc.cp.integrationTest.ts │ │ │ │ │ ├── ipc.net.test.ts │ │ │ │ │ ├── testApp.ts │ │ │ │ │ └── testService.ts │ │ │ │ ├── request/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── request.ts │ │ │ │ │ │ └── requestImpl.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── electron-main/ │ │ │ │ │ └── request.test.ts │ │ │ │ ├── sandbox/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── electronTypes.ts │ │ │ │ │ │ └── sandboxTypes.ts │ │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ │ ├── electronTypes.ts │ │ │ │ │ │ ├── globals.ts │ │ │ │ │ │ ├── preload-aux.ts │ │ │ │ │ │ └── preload.ts │ │ │ │ │ ├── node/ │ │ │ │ │ │ └── electronTypes.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── electron-sandbox/ │ │ │ │ │ └── globals.test.ts │ │ │ │ └── storage/ │ │ │ │ ├── common/ │ │ │ │ │ └── storage.ts │ │ │ │ ├── node/ │ │ │ │ │ └── storage.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ └── storage.integrationTest.ts │ │ │ └── test/ │ │ │ ├── browser/ │ │ │ │ ├── actionbar.test.ts │ │ │ │ ├── browser.test.ts │ │ │ │ ├── comparers.test.ts │ │ │ │ ├── dom.test.ts │ │ │ │ ├── formattedTextRenderer.test.ts │ │ │ │ ├── hash.test.ts │ │ │ │ ├── highlightedLabel.test.ts │ │ │ │ ├── iconLabels.test.ts │ │ │ │ ├── indexedDB.test.ts │ │ │ │ ├── markdownRenderer.test.ts │ │ │ │ ├── progressBar.test.ts │ │ │ │ └── ui/ │ │ │ │ ├── contextview/ │ │ │ │ │ └── contextview.test.ts │ │ │ │ ├── grid/ │ │ │ │ │ ├── grid.test.ts │ │ │ │ │ ├── gridview.test.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── list/ │ │ │ │ │ ├── listView.test.ts │ │ │ │ │ ├── listWidget.test.ts │ │ │ │ │ └── rangeMap.test.ts │ │ │ │ ├── menu/ │ │ │ │ │ └── menubar.test.ts │ │ │ │ ├── scrollbar/ │ │ │ │ │ ├── scrollableElement.test.ts │ │ │ │ │ └── scrollbarState.test.ts │ │ │ │ ├── splitview/ │ │ │ │ │ └── splitview.test.ts │ │ │ │ └── tree/ │ │ │ │ ├── asyncDataTree.test.ts │ │ │ │ ├── compressedObjectTreeModel.test.ts │ │ │ │ ├── dataTree.test.ts │ │ │ │ ├── indexTreeModel.test.ts │ │ │ │ ├── objectTree.test.ts │ │ │ │ └── objectTreeModel.test.ts │ │ │ ├── common/ │ │ │ │ ├── arrays.test.ts │ │ │ │ ├── arraysFind.test.ts │ │ │ │ ├── assert.test.ts │ │ │ │ ├── assertHeap.ts │ │ │ │ ├── async.test.ts │ │ │ │ ├── buffer.test.ts │ │ │ │ ├── cache.test.ts │ │ │ │ ├── cancelPreviousCalls.test.ts │ │ │ │ ├── cancellation.test.ts │ │ │ │ ├── charCode.test.ts │ │ │ │ ├── collections.test.ts │ │ │ │ ├── color.test.ts │ │ │ │ ├── console.test.ts │ │ │ │ ├── date.test.ts │ │ │ │ ├── decorators.test.ts │ │ │ │ ├── diff/ │ │ │ │ │ └── diff.test.ts │ │ │ │ ├── envfile.test.ts │ │ │ │ ├── errors.test.ts │ │ │ │ ├── event.test.ts │ │ │ │ ├── extpath.test.ts │ │ │ │ ├── filters.perf.data.d.ts │ │ │ │ ├── filters.perf.data.js │ │ │ │ ├── filters.perf.test.ts │ │ │ │ ├── filters.test.ts │ │ │ │ ├── fuzzyScorer.test.ts │ │ │ │ ├── glob.test.ts │ │ │ │ ├── history.test.ts │ │ │ │ ├── iconLabels.test.ts │ │ │ │ ├── iterator.test.ts │ │ │ │ ├── json.test.ts │ │ │ │ ├── jsonEdit.test.ts │ │ │ │ ├── jsonFormatter.test.ts │ │ │ │ ├── jsonParse.test.ts │ │ │ │ ├── jsonSchema.test.ts │ │ │ │ ├── keyCodes.test.ts │ │ │ │ ├── keybindings.test.ts │ │ │ │ ├── labels.test.ts │ │ │ │ ├── lazy.test.ts │ │ │ │ ├── lifecycle.test.ts │ │ │ │ ├── linkedList.test.ts │ │ │ │ ├── linkedText.test.ts │ │ │ │ ├── map.test.ts │ │ │ │ ├── markdownString.test.ts │ │ │ │ ├── marshalling.test.ts │ │ │ │ ├── mime.test.ts │ │ │ │ ├── mock.ts │ │ │ │ ├── naturalLanguage/ │ │ │ │ │ └── korean.test.ts │ │ │ │ ├── network.test.ts │ │ │ │ ├── normalization.test.ts │ │ │ │ ├── numbers.test.ts │ │ │ │ ├── objectCache.test.ts │ │ │ │ ├── objects.test.ts │ │ │ │ ├── observable.test.ts │ │ │ │ ├── observableDisposable.test.ts │ │ │ │ ├── paging.test.ts │ │ │ │ ├── path.test.ts │ │ │ │ ├── prefixTree.test.ts │ │ │ │ ├── processes.test.ts │ │ │ │ ├── resourceTree.test.ts │ │ │ │ ├── resources.test.ts │ │ │ │ ├── scrollable.test.ts │ │ │ │ ├── skipList.test.ts │ │ │ │ ├── snapshot.ts │ │ │ │ ├── stream.test.ts │ │ │ │ ├── strings.test.ts │ │ │ │ ├── ternarySearchtree.test.ts │ │ │ │ ├── testUtils.ts │ │ │ │ ├── tfIdf.test.ts │ │ │ │ ├── timeTravelScheduler.ts │ │ │ │ ├── troubleshooting.ts │ │ │ │ ├── types.test.ts │ │ │ │ ├── uri.test.ts │ │ │ │ ├── utils.ts │ │ │ │ └── uuid.test.ts │ │ │ └── node/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── snapshot_cleans_up_old_snapshots.0.snap │ │ │ │ ├── snapshot_cleans_up_old_snapshots.1.snap │ │ │ │ ├── snapshot_creates_a_snapshot.0.snap │ │ │ │ └── snapshot_formats_object_nicely.0.snap │ │ │ ├── crypto.test.ts │ │ │ ├── extpath.test.ts │ │ │ ├── id.test.ts │ │ │ ├── nodeStreams.test.ts │ │ │ ├── pfs/ │ │ │ │ ├── fixtures/ │ │ │ │ │ ├── examples/ │ │ │ │ │ │ ├── company.jxs │ │ │ │ │ │ ├── conway.jxs │ │ │ │ │ │ ├── employee.jxs │ │ │ │ │ │ └── small.jxs │ │ │ │ │ ├── index.html │ │ │ │ │ └── site.css │ │ │ │ └── pfs.test.ts │ │ │ ├── port.test.ts │ │ │ ├── powershell.test.ts │ │ │ ├── processes/ │ │ │ │ ├── fixtures/ │ │ │ │ │ ├── fork.ts │ │ │ │ │ └── fork_large.ts │ │ │ │ └── processes.integrationTest.ts │ │ │ ├── snapshot.test.ts │ │ │ ├── testUtils.ts │ │ │ ├── unc.test.ts │ │ │ ├── uri.perf.data.txt │ │ │ ├── uri.perf.test.ts │ │ │ ├── uri.test.data.txt │ │ │ └── zip/ │ │ │ └── zip.test.ts │ │ ├── code/ │ │ │ ├── browser/ │ │ │ │ └── workbench/ │ │ │ │ ├── callback.html │ │ │ │ ├── workbench-dev.html │ │ │ │ ├── workbench.html │ │ │ │ └── workbench.ts │ │ │ ├── electron-main/ │ │ │ │ ├── app.ts │ │ │ │ └── main.ts │ │ │ ├── electron-sandbox/ │ │ │ │ ├── processExplorer/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── processExplorer.css │ │ │ │ │ ├── processExplorer-dev.html │ │ │ │ │ ├── processExplorer.html │ │ │ │ │ ├── processExplorer.ts │ │ │ │ │ └── processExplorerMain.ts │ │ │ │ └── workbench/ │ │ │ │ ├── workbench-dev.html │ │ │ │ ├── workbench.html │ │ │ │ └── workbench.ts │ │ │ ├── electron-utility/ │ │ │ │ └── sharedProcess/ │ │ │ │ ├── contrib/ │ │ │ │ │ ├── codeCacheCleaner.ts │ │ │ │ │ ├── defaultExtensionsInitializer.ts │ │ │ │ │ ├── extensions.ts │ │ │ │ │ ├── languagePackCachedDataCleaner.ts │ │ │ │ │ ├── localizationsUpdater.ts │ │ │ │ │ ├── logsDataCleaner.ts │ │ │ │ │ ├── storageDataCleaner.ts │ │ │ │ │ └── userDataProfilesCleaner.ts │ │ │ │ └── sharedProcessMain.ts │ │ │ └── node/ │ │ │ ├── cli.ts │ │ │ └── cliProcessMain.ts │ │ ├── editor/ │ │ │ ├── browser/ │ │ │ │ ├── config/ │ │ │ │ │ ├── charWidthReader.ts │ │ │ │ │ ├── domFontInfo.ts │ │ │ │ │ ├── editorConfiguration.ts │ │ │ │ │ ├── elementSizeObserver.ts │ │ │ │ │ ├── fontMeasurements.ts │ │ │ │ │ ├── migrateOptions.ts │ │ │ │ │ └── tabFocus.ts │ │ │ │ ├── controller/ │ │ │ │ │ ├── editContext/ │ │ │ │ │ │ ├── clipboardUtils.ts │ │ │ │ │ │ ├── editContext.ts │ │ │ │ │ │ ├── native/ │ │ │ │ │ │ │ ├── debugEditContext.ts │ │ │ │ │ │ │ ├── editContextFactory.ts │ │ │ │ │ │ │ ├── nativeEditContext.css │ │ │ │ │ │ │ ├── nativeEditContext.ts │ │ │ │ │ │ │ ├── nativeEditContextRegistry.ts │ │ │ │ │ │ │ ├── nativeEditContextUtils.ts │ │ │ │ │ │ │ └── screenReaderSupport.ts │ │ │ │ │ │ ├── screenReaderUtils.ts │ │ │ │ │ │ └── textArea/ │ │ │ │ │ │ ├── textAreaEditContext.css │ │ │ │ │ │ ├── textAreaEditContext.ts │ │ │ │ │ │ ├── textAreaEditContextInput.ts │ │ │ │ │ │ └── textAreaEditContextState.ts │ │ │ │ │ ├── mouseHandler.ts │ │ │ │ │ ├── mouseTarget.ts │ │ │ │ │ └── pointerHandler.ts │ │ │ │ ├── coreCommands.ts │ │ │ │ ├── dnd.ts │ │ │ │ ├── editorBrowser.ts │ │ │ │ ├── editorDom.ts │ │ │ │ ├── editorExtensions.ts │ │ │ │ ├── gpu/ │ │ │ │ │ ├── atlas/ │ │ │ │ │ │ ├── atlas.ts │ │ │ │ │ │ ├── textureAtlas.ts │ │ │ │ │ │ ├── textureAtlasPage.ts │ │ │ │ │ │ ├── textureAtlasShelfAllocator.ts │ │ │ │ │ │ └── textureAtlasSlabAllocator.ts │ │ │ │ │ ├── bufferDirtyTracker.ts │ │ │ │ │ ├── contentSegmenter.ts │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── decorationCssRuleExtractor.ts │ │ │ │ │ │ ├── decorationStyleCache.ts │ │ │ │ │ │ └── media/ │ │ │ │ │ │ └── decorationCssRuleExtractor.css │ │ │ │ │ ├── gpu.ts │ │ │ │ │ ├── gpuDisposable.ts │ │ │ │ │ ├── gpuUtils.ts │ │ │ │ │ ├── objectCollectionBuffer.ts │ │ │ │ │ ├── raster/ │ │ │ │ │ │ ├── glyphRasterizer.ts │ │ │ │ │ │ └── raster.ts │ │ │ │ │ ├── rectangleRenderer.ts │ │ │ │ │ ├── rectangleRenderer.wgsl.ts │ │ │ │ │ ├── renderStrategy/ │ │ │ │ │ │ ├── baseRenderStrategy.ts │ │ │ │ │ │ ├── fullFileRenderStrategy.ts │ │ │ │ │ │ ├── fullFileRenderStrategy.wgsl.ts │ │ │ │ │ │ └── viewportRenderStrategy.ts │ │ │ │ │ ├── taskQueue.ts │ │ │ │ │ └── viewGpuContext.ts │ │ │ │ ├── observableCodeEditor.ts │ │ │ │ ├── point.ts │ │ │ │ ├── rect.ts │ │ │ │ ├── services/ │ │ │ │ │ ├── abstractCodeEditorService.ts │ │ │ │ │ ├── bulkEditService.ts │ │ │ │ │ ├── codeEditorService.ts │ │ │ │ │ ├── editorWorkerService.ts │ │ │ │ │ ├── hoverService/ │ │ │ │ │ │ ├── hover.css │ │ │ │ │ │ ├── hoverService.ts │ │ │ │ │ │ ├── hoverWidget.ts │ │ │ │ │ │ └── updatableHoverWidget.ts │ │ │ │ │ ├── markerDecorations.ts │ │ │ │ │ └── openerService.ts │ │ │ │ ├── stableEditorScroll.ts │ │ │ │ ├── view/ │ │ │ │ │ ├── domLineBreaksComputer.ts │ │ │ │ │ ├── dynamicViewOverlay.ts │ │ │ │ │ ├── renderingContext.ts │ │ │ │ │ ├── viewController.ts │ │ │ │ │ ├── viewLayer.ts │ │ │ │ │ ├── viewOverlays.ts │ │ │ │ │ ├── viewPart.ts │ │ │ │ │ └── viewUserInputEvents.ts │ │ │ │ ├── view.ts │ │ │ │ ├── viewParts/ │ │ │ │ │ ├── blockDecorations/ │ │ │ │ │ │ ├── blockDecorations.css │ │ │ │ │ │ └── blockDecorations.ts │ │ │ │ │ ├── contentWidgets/ │ │ │ │ │ │ └── contentWidgets.ts │ │ │ │ │ ├── currentLineHighlight/ │ │ │ │ │ │ ├── currentLineHighlight.css │ │ │ │ │ │ └── currentLineHighlight.ts │ │ │ │ │ ├── decorations/ │ │ │ │ │ │ ├── decorations.css │ │ │ │ │ │ └── decorations.ts │ │ │ │ │ ├── editorScrollbar/ │ │ │ │ │ │ └── editorScrollbar.ts │ │ │ │ │ ├── glyphMargin/ │ │ │ │ │ │ ├── glyphMargin.css │ │ │ │ │ │ └── glyphMargin.ts │ │ │ │ │ ├── gpuMark/ │ │ │ │ │ │ ├── gpuMark.css │ │ │ │ │ │ └── gpuMark.ts │ │ │ │ │ ├── indentGuides/ │ │ │ │ │ │ ├── indentGuides.css │ │ │ │ │ │ └── indentGuides.ts │ │ │ │ │ ├── lineNumbers/ │ │ │ │ │ │ ├── lineNumbers.css │ │ │ │ │ │ └── lineNumbers.ts │ │ │ │ │ ├── linesDecorations/ │ │ │ │ │ │ ├── linesDecorations.css │ │ │ │ │ │ └── linesDecorations.ts │ │ │ │ │ ├── margin/ │ │ │ │ │ │ ├── margin.css │ │ │ │ │ │ └── margin.ts │ │ │ │ │ ├── marginDecorations/ │ │ │ │ │ │ ├── marginDecorations.css │ │ │ │ │ │ └── marginDecorations.ts │ │ │ │ │ ├── minimap/ │ │ │ │ │ │ ├── minimap.css │ │ │ │ │ │ ├── minimap.ts │ │ │ │ │ │ ├── minimapCharRenderer.ts │ │ │ │ │ │ ├── minimapCharRendererFactory.ts │ │ │ │ │ │ ├── minimapCharSheet.ts │ │ │ │ │ │ └── minimapPreBaked.ts │ │ │ │ │ ├── overlayWidgets/ │ │ │ │ │ │ ├── overlayWidgets.css │ │ │ │ │ │ └── overlayWidgets.ts │ │ │ │ │ ├── overviewRuler/ │ │ │ │ │ │ ├── decorationsOverviewRuler.ts │ │ │ │ │ │ └── overviewRuler.ts │ │ │ │ │ ├── rulers/ │ │ │ │ │ │ ├── rulers.css │ │ │ │ │ │ └── rulers.ts │ │ │ │ │ ├── rulersGpu/ │ │ │ │ │ │ └── rulersGpu.ts │ │ │ │ │ ├── scrollDecoration/ │ │ │ │ │ │ ├── scrollDecoration.css │ │ │ │ │ │ └── scrollDecoration.ts │ │ │ │ │ ├── selections/ │ │ │ │ │ │ ├── selections.css │ │ │ │ │ │ └── selections.ts │ │ │ │ │ ├── viewCursors/ │ │ │ │ │ │ ├── viewCursor.ts │ │ │ │ │ │ ├── viewCursors.css │ │ │ │ │ │ └── viewCursors.ts │ │ │ │ │ ├── viewLines/ │ │ │ │ │ │ ├── domReadingContext.ts │ │ │ │ │ │ ├── rangeUtil.ts │ │ │ │ │ │ ├── viewLine.ts │ │ │ │ │ │ ├── viewLineOptions.ts │ │ │ │ │ │ ├── viewLines.css │ │ │ │ │ │ └── viewLines.ts │ │ │ │ │ ├── viewLinesGpu/ │ │ │ │ │ │ └── viewLinesGpu.ts │ │ │ │ │ ├── viewZones/ │ │ │ │ │ │ └── viewZones.ts │ │ │ │ │ └── whitespace/ │ │ │ │ │ ├── whitespace.css │ │ │ │ │ └── whitespace.ts │ │ │ │ └── widget/ │ │ │ │ ├── codeEditor/ │ │ │ │ │ ├── codeEditorContributions.ts │ │ │ │ │ ├── codeEditorWidget.ts │ │ │ │ │ ├── editor.css │ │ │ │ │ └── embeddedCodeEditorWidget.ts │ │ │ │ ├── diffEditor/ │ │ │ │ │ ├── commands.ts │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── accessibleDiffViewer.css │ │ │ │ │ │ ├── accessibleDiffViewer.ts │ │ │ │ │ │ ├── diffEditorDecorations.ts │ │ │ │ │ │ ├── diffEditorEditors.ts │ │ │ │ │ │ ├── diffEditorSash.ts │ │ │ │ │ │ └── diffEditorViewZones/ │ │ │ │ │ │ ├── diffEditorViewZones.ts │ │ │ │ │ │ ├── inlineDiffDeletedCodeMargin.ts │ │ │ │ │ │ └── renderLines.ts │ │ │ │ │ ├── delegatingEditorImpl.ts │ │ │ │ │ ├── diffEditor.contribution.ts │ │ │ │ │ ├── diffEditorOptions.ts │ │ │ │ │ ├── diffEditorViewModel.ts │ │ │ │ │ ├── diffEditorWidget.ts │ │ │ │ │ ├── diffProviderFactoryService.ts │ │ │ │ │ ├── embeddedDiffEditorWidget.ts │ │ │ │ │ ├── features/ │ │ │ │ │ │ ├── gutterFeature.ts │ │ │ │ │ │ ├── hideUnchangedRegionsFeature.ts │ │ │ │ │ │ ├── movedBlocksLinesFeature.ts │ │ │ │ │ │ ├── overviewRulerFeature.ts │ │ │ │ │ │ └── revertButtonsFeature.ts │ │ │ │ │ ├── registrations.contribution.ts │ │ │ │ │ ├── style.css │ │ │ │ │ ├── utils/ │ │ │ │ │ │ └── editorGutter.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── markdownRenderer/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── markdownRenderer.ts │ │ │ │ │ └── renderedMarkdown.css │ │ │ │ └── multiDiffEditor/ │ │ │ │ ├── colors.ts │ │ │ │ ├── diffEditorItemTemplate.ts │ │ │ │ ├── model.ts │ │ │ │ ├── multiDiffEditorViewModel.ts │ │ │ │ ├── multiDiffEditorWidget.ts │ │ │ │ ├── multiDiffEditorWidgetImpl.ts │ │ │ │ ├── objectPool.ts │ │ │ │ ├── style.css │ │ │ │ ├── utils.ts │ │ │ │ └── workbenchUIElementFactory.ts │ │ │ ├── common/ │ │ │ │ ├── codecs/ │ │ │ │ │ ├── baseToken.ts │ │ │ │ │ ├── linesCodec/ │ │ │ │ │ │ ├── linesDecoder.ts │ │ │ │ │ │ └── tokens/ │ │ │ │ │ │ ├── carriageReturn.ts │ │ │ │ │ │ ├── line.ts │ │ │ │ │ │ └── newLine.ts │ │ │ │ │ ├── markdownCodec/ │ │ │ │ │ │ ├── markdownDecoder.ts │ │ │ │ │ │ ├── parsers/ │ │ │ │ │ │ │ ├── markdownComment.ts │ │ │ │ │ │ │ ├── markdownImage.ts │ │ │ │ │ │ │ └── markdownLink.ts │ │ │ │ │ │ └── tokens/ │ │ │ │ │ │ ├── markdownComment.ts │ │ │ │ │ │ ├── markdownImage.ts │ │ │ │ │ │ ├── markdownLink.ts │ │ │ │ │ │ └── markdownToken.ts │ │ │ │ │ └── simpleCodec/ │ │ │ │ │ ├── parserBase.ts │ │ │ │ │ ├── simpleDecoder.ts │ │ │ │ │ └── tokens/ │ │ │ │ │ ├── angleBrackets.ts │ │ │ │ │ ├── brackets.ts │ │ │ │ │ ├── colon.ts │ │ │ │ │ ├── dash.ts │ │ │ │ │ ├── exclamationMark.ts │ │ │ │ │ ├── formFeed.ts │ │ │ │ │ ├── hash.ts │ │ │ │ │ ├── parentheses.ts │ │ │ │ │ ├── space.ts │ │ │ │ │ ├── tab.ts │ │ │ │ │ ├── verticalTab.ts │ │ │ │ │ └── word.ts │ │ │ │ ├── commands/ │ │ │ │ │ ├── replaceCommand.ts │ │ │ │ │ ├── shiftCommand.ts │ │ │ │ │ ├── surroundSelectionCommand.ts │ │ │ │ │ └── trimTrailingWhitespaceCommand.ts │ │ │ │ ├── config/ │ │ │ │ │ ├── diffEditor.ts │ │ │ │ │ ├── editorConfiguration.ts │ │ │ │ │ ├── editorConfigurationSchema.ts │ │ │ │ │ ├── editorOptions.ts │ │ │ │ │ ├── editorZoom.ts │ │ │ │ │ └── fontInfo.ts │ │ │ │ ├── core/ │ │ │ │ │ ├── characterClassifier.ts │ │ │ │ │ ├── cursorColumns.ts │ │ │ │ │ ├── dimension.ts │ │ │ │ │ ├── editOperation.ts │ │ │ │ │ ├── editorColorRegistry.ts │ │ │ │ │ ├── eolCounter.ts │ │ │ │ │ ├── indentation.ts │ │ │ │ │ ├── lineEdit.ts │ │ │ │ │ ├── lineRange.ts │ │ │ │ │ ├── offsetEdit.ts │ │ │ │ │ ├── offsetRange.ts │ │ │ │ │ ├── position.ts │ │ │ │ │ ├── positionToOffset.ts │ │ │ │ │ ├── range.ts │ │ │ │ │ ├── rangeMapping.ts │ │ │ │ │ ├── rgba.ts │ │ │ │ │ ├── selection.ts │ │ │ │ │ ├── stringBuilder.ts │ │ │ │ │ ├── textChange.ts │ │ │ │ │ ├── textEdit.ts │ │ │ │ │ ├── textLength.ts │ │ │ │ │ ├── textModelDefaults.ts │ │ │ │ │ ├── wordCharacterClassifier.ts │ │ │ │ │ └── wordHelper.ts │ │ │ │ ├── cursor/ │ │ │ │ │ ├── cursor.ts │ │ │ │ │ ├── cursorAtomicMoveOperations.ts │ │ │ │ │ ├── cursorCollection.ts │ │ │ │ │ ├── cursorColumnSelection.ts │ │ │ │ │ ├── cursorContext.ts │ │ │ │ │ ├── cursorDeleteOperations.ts │ │ │ │ │ ├── cursorMoveCommands.ts │ │ │ │ │ ├── cursorMoveOperations.ts │ │ │ │ │ ├── cursorTypeEditOperations.ts │ │ │ │ │ ├── cursorTypeOperations.ts │ │ │ │ │ ├── cursorWordOperations.ts │ │ │ │ │ └── oneCursor.ts │ │ │ │ ├── cursorCommon.ts │ │ │ │ ├── cursorEvents.ts │ │ │ │ ├── diff/ │ │ │ │ │ ├── defaultLinesDiffComputer/ │ │ │ │ │ │ ├── algorithms/ │ │ │ │ │ │ │ ├── diffAlgorithm.ts │ │ │ │ │ │ │ ├── dynamicProgrammingDiffing.ts │ │ │ │ │ │ │ └── myersDiffAlgorithm.ts │ │ │ │ │ │ ├── computeMovedLines.ts │ │ │ │ │ │ ├── defaultLinesDiffComputer.ts │ │ │ │ │ │ ├── heuristicSequenceOptimizations.ts │ │ │ │ │ │ ├── lineSequence.ts │ │ │ │ │ │ ├── linesSliceCharSequence.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── documentDiffProvider.ts │ │ │ │ │ ├── legacyLinesDiffComputer.ts │ │ │ │ │ ├── linesDiffComputer.ts │ │ │ │ │ ├── linesDiffComputers.ts │ │ │ │ │ └── rangeMapping.ts │ │ │ │ ├── editorAction.ts │ │ │ │ ├── editorCommon.ts │ │ │ │ ├── editorContextKeys.ts │ │ │ │ ├── editorFeatures.ts │ │ │ │ ├── editorTheme.ts │ │ │ │ ├── encodedTokenAttributes.ts │ │ │ │ ├── inputMode.ts │ │ │ │ ├── languageFeatureRegistry.ts │ │ │ │ ├── languageSelector.ts │ │ │ │ ├── languages/ │ │ │ │ │ ├── autoIndent.ts │ │ │ │ │ ├── defaultDocumentColorsComputer.ts │ │ │ │ │ ├── enterAction.ts │ │ │ │ │ ├── highlights/ │ │ │ │ │ │ ├── css.scm │ │ │ │ │ │ ├── ini.scm │ │ │ │ │ │ ├── regex.scm │ │ │ │ │ │ └── typescript.scm │ │ │ │ │ ├── injections/ │ │ │ │ │ │ └── typescript.scm │ │ │ │ │ ├── language.ts │ │ │ │ │ ├── languageConfiguration.ts │ │ │ │ │ ├── languageConfigurationRegistry.ts │ │ │ │ │ ├── linkComputer.ts │ │ │ │ │ ├── modesRegistry.ts │ │ │ │ │ ├── nullTokenize.ts │ │ │ │ │ ├── supports/ │ │ │ │ │ │ ├── characterPair.ts │ │ │ │ │ │ ├── electricCharacter.ts │ │ │ │ │ │ ├── indentRules.ts │ │ │ │ │ │ ├── indentationLineProcessor.ts │ │ │ │ │ │ ├── inplaceReplaceSupport.ts │ │ │ │ │ │ ├── languageBracketsConfiguration.ts │ │ │ │ │ │ ├── onEnter.ts │ │ │ │ │ │ ├── richEditBrackets.ts │ │ │ │ │ │ └── tokenization.ts │ │ │ │ │ ├── supports.ts │ │ │ │ │ └── textToHtmlTokenizer.ts │ │ │ │ ├── languages.ts │ │ │ │ ├── model/ │ │ │ │ │ ├── bracketPairsTextModelPart/ │ │ │ │ │ │ ├── bracketPairsImpl.ts │ │ │ │ │ │ ├── bracketPairsTree/ │ │ │ │ │ │ │ ├── ast.ts │ │ │ │ │ │ │ ├── beforeEditPositionMapper.ts │ │ │ │ │ │ │ ├── bracketPairsTree.ts │ │ │ │ │ │ │ ├── brackets.ts │ │ │ │ │ │ │ ├── combineTextEditInfos.ts │ │ │ │ │ │ │ ├── concat23Trees.ts │ │ │ │ │ │ │ ├── length.ts │ │ │ │ │ │ │ ├── nodeReader.ts │ │ │ │ │ │ │ ├── parser.ts │ │ │ │ │ │ │ ├── smallImmutableSet.ts │ │ │ │ │ │ │ └── tokenizer.ts │ │ │ │ │ │ ├── colorizedBracketPairsDecorationProvider.ts │ │ │ │ │ │ └── fixBrackets.ts │ │ │ │ │ ├── decorationProvider.ts │ │ │ │ │ ├── editStack.ts │ │ │ │ │ ├── fixedArray.ts │ │ │ │ │ ├── guidesTextModelPart.ts │ │ │ │ │ ├── indentationGuesser.ts │ │ │ │ │ ├── intervalTree.ts │ │ │ │ │ ├── mirrorTextModel.ts │ │ │ │ │ ├── pieceTreeTextBuffer/ │ │ │ │ │ │ ├── pieceTreeBase.ts │ │ │ │ │ │ ├── pieceTreeTextBuffer.ts │ │ │ │ │ │ ├── pieceTreeTextBufferBuilder.ts │ │ │ │ │ │ └── rbTreeBase.ts │ │ │ │ │ ├── prefixSumComputer.ts │ │ │ │ │ ├── textModel.ts │ │ │ │ │ ├── textModelOffsetEdit.ts │ │ │ │ │ ├── textModelPart.ts │ │ │ │ │ ├── textModelSearch.ts │ │ │ │ │ ├── textModelText.ts │ │ │ │ │ ├── textModelTokens.ts │ │ │ │ │ ├── tokenStore.ts │ │ │ │ │ ├── tokenizationTextModelPart.ts │ │ │ │ │ ├── tokens.ts │ │ │ │ │ ├── treeSitterTokenStoreService.ts │ │ │ │ │ ├── treeSitterTokens.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── model.ts │ │ │ │ ├── modelLineProjectionData.ts │ │ │ │ ├── services/ │ │ │ │ │ ├── editorBaseApi.ts │ │ │ │ │ ├── editorWebWorker.ts │ │ │ │ │ ├── editorWebWorkerMain.ts │ │ │ │ │ ├── editorWorker.ts │ │ │ │ │ ├── editorWorkerHost.ts │ │ │ │ │ ├── findSectionHeaders.ts │ │ │ │ │ ├── getIconClasses.ts │ │ │ │ │ ├── languageFeatureDebounce.ts │ │ │ │ │ ├── languageFeatures.ts │ │ │ │ │ ├── languageFeaturesService.ts │ │ │ │ │ ├── languageService.ts │ │ │ │ │ ├── languagesAssociations.ts │ │ │ │ │ ├── languagesRegistry.ts │ │ │ │ │ ├── markerDecorations.ts │ │ │ │ │ ├── markerDecorationsService.ts │ │ │ │ │ ├── model.ts │ │ │ │ │ ├── modelService.ts │ │ │ │ │ ├── modelUndoRedoParticipant.ts │ │ │ │ │ ├── resolverService.ts │ │ │ │ │ ├── semanticTokensDto.ts │ │ │ │ │ ├── semanticTokensProviderStyling.ts │ │ │ │ │ ├── semanticTokensStyling.ts │ │ │ │ │ ├── semanticTokensStylingService.ts │ │ │ │ │ ├── textModelSync/ │ │ │ │ │ │ ├── textModelSync.impl.ts │ │ │ │ │ │ └── textModelSync.protocol.ts │ │ │ │ │ ├── textResourceConfiguration.ts │ │ │ │ │ ├── textResourceConfigurationService.ts │ │ │ │ │ ├── treeSitter/ │ │ │ │ │ │ ├── cursorUtils.ts │ │ │ │ │ │ ├── textModelTreeSitter.ts │ │ │ │ │ │ ├── treeSitterLanguages.ts │ │ │ │ │ │ └── treeSitterParserService.ts │ │ │ │ │ ├── treeSitterParserService.ts │ │ │ │ │ ├── treeViewsDnd.ts │ │ │ │ │ ├── treeViewsDndService.ts │ │ │ │ │ └── unicodeTextModelHighlighter.ts │ │ │ │ ├── standalone/ │ │ │ │ │ └── standaloneEnums.ts │ │ │ │ ├── standaloneStrings.ts │ │ │ │ ├── textModelBracketPairs.ts │ │ │ │ ├── textModelEvents.ts │ │ │ │ ├── textModelGuides.ts │ │ │ │ ├── tokenizationRegistry.ts │ │ │ │ ├── tokenizationTextModelPart.ts │ │ │ │ ├── tokens/ │ │ │ │ │ ├── contiguousMultilineTokens.ts │ │ │ │ │ ├── contiguousMultilineTokensBuilder.ts │ │ │ │ │ ├── contiguousTokensEditing.ts │ │ │ │ │ ├── contiguousTokensStore.ts │ │ │ │ │ ├── lineTokens.ts │ │ │ │ │ ├── sparseMultilineTokens.ts │ │ │ │ │ ├── sparseTokensStore.ts │ │ │ │ │ └── tokenArray.ts │ │ │ │ ├── viewEventHandler.ts │ │ │ │ ├── viewEvents.ts │ │ │ │ ├── viewLayout/ │ │ │ │ │ ├── lineDecorations.ts │ │ │ │ │ ├── linePart.ts │ │ │ │ │ ├── linesLayout.ts │ │ │ │ │ ├── viewLayout.ts │ │ │ │ │ ├── viewLineRenderer.ts │ │ │ │ │ └── viewLinesViewportData.ts │ │ │ │ ├── viewModel/ │ │ │ │ │ ├── glyphLanesModel.ts │ │ │ │ │ ├── minimapTokensColorTracker.ts │ │ │ │ │ ├── modelLineProjection.ts │ │ │ │ │ ├── monospaceLineBreaksComputer.ts │ │ │ │ │ ├── overviewZoneManager.ts │ │ │ │ │ ├── viewContext.ts │ │ │ │ │ ├── viewModelDecorations.ts │ │ │ │ │ ├── viewModelImpl.ts │ │ │ │ │ └── viewModelLines.ts │ │ │ │ ├── viewModel.ts │ │ │ │ └── viewModelEventDispatcher.ts │ │ │ ├── contrib/ │ │ │ │ ├── anchorSelect/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── anchorSelect.css │ │ │ │ │ └── anchorSelect.ts │ │ │ │ ├── bracketMatching/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── bracketMatching.css │ │ │ │ │ │ └── bracketMatching.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── bracketMatching.test.ts │ │ │ │ ├── caretOperations/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── caretOperations.ts │ │ │ │ │ │ ├── moveCaretCommand.ts │ │ │ │ │ │ └── transpose.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── moveCarretCommand.test.ts │ │ │ │ ├── clipboard/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── clipboard.ts │ │ │ │ ├── codeAction/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── codeAction.ts │ │ │ │ │ │ ├── codeActionCommands.ts │ │ │ │ │ │ ├── codeActionContributions.ts │ │ │ │ │ │ ├── codeActionController.ts │ │ │ │ │ │ ├── codeActionKeybindingResolver.ts │ │ │ │ │ │ ├── codeActionMenu.ts │ │ │ │ │ │ ├── codeActionModel.ts │ │ │ │ │ │ ├── lightBulbWidget.css │ │ │ │ │ │ └── lightBulbWidget.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── types.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── codeAction.test.ts │ │ │ │ │ ├── codeActionKeybindingResolver.test.ts │ │ │ │ │ └── codeActionModel.test.ts │ │ │ │ ├── codelens/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── codeLensCache.ts │ │ │ │ │ ├── codelens.ts │ │ │ │ │ ├── codelensController.ts │ │ │ │ │ ├── codelensWidget.css │ │ │ │ │ └── codelensWidget.ts │ │ │ │ ├── colorPicker/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── color.ts │ │ │ │ │ ├── colorDetector.ts │ │ │ │ │ ├── colorPicker.css │ │ │ │ │ ├── colorPickerContribution.ts │ │ │ │ │ ├── colorPickerModel.ts │ │ │ │ │ ├── colorPickerParticipantUtils.ts │ │ │ │ │ ├── colorPickerParts/ │ │ │ │ │ │ ├── colorPickerBody.ts │ │ │ │ │ │ ├── colorPickerCloseButton.ts │ │ │ │ │ │ ├── colorPickerHeader.ts │ │ │ │ │ │ ├── colorPickerInsertButton.ts │ │ │ │ │ │ ├── colorPickerSaturationBox.ts │ │ │ │ │ │ └── colorPickerStrip.ts │ │ │ │ │ ├── colorPickerWidget.ts │ │ │ │ │ ├── defaultDocumentColorProvider.ts │ │ │ │ │ ├── hoverColorPicker/ │ │ │ │ │ │ ├── hoverColorPicker.ts │ │ │ │ │ │ ├── hoverColorPickerContribution.ts │ │ │ │ │ │ └── hoverColorPickerParticipant.ts │ │ │ │ │ └── standaloneColorPicker/ │ │ │ │ │ ├── standaloneColorPickerActions.ts │ │ │ │ │ ├── standaloneColorPickerController.ts │ │ │ │ │ ├── standaloneColorPickerParticipant.ts │ │ │ │ │ └── standaloneColorPickerWidget.ts │ │ │ │ ├── comment/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── blockCommentCommand.ts │ │ │ │ │ │ ├── comment.ts │ │ │ │ │ │ └── lineCommentCommand.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── blockCommentCommand.test.ts │ │ │ │ │ └── lineCommentCommand.test.ts │ │ │ │ ├── contextmenu/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── contextmenu.ts │ │ │ │ ├── cursorUndo/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── cursorUndo.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── cursorUndo.test.ts │ │ │ │ ├── diffEditorBreadcrumbs/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── contribution.ts │ │ │ │ ├── dnd/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── dnd.css │ │ │ │ │ ├── dnd.ts │ │ │ │ │ └── dragAndDropCommand.ts │ │ │ │ ├── documentSymbols/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── documentSymbols.ts │ │ │ │ │ │ └── outlineModel.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── outlineModel.test.ts │ │ │ │ ├── dropOrPasteInto/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── copyPasteContribution.ts │ │ │ │ │ │ ├── copyPasteController.ts │ │ │ │ │ │ ├── defaultProviders.ts │ │ │ │ │ │ ├── dropIntoEditorContribution.ts │ │ │ │ │ │ ├── dropIntoEditorController.ts │ │ │ │ │ │ ├── edit.ts │ │ │ │ │ │ ├── postEditWidget.css │ │ │ │ │ │ └── postEditWidget.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── editSort.test.ts │ │ │ │ ├── editorState/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── editorState.ts │ │ │ │ │ │ └── keybindingCancellation.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── editorState.test.ts │ │ │ │ ├── find/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── findController.ts │ │ │ │ │ │ ├── findDecorations.ts │ │ │ │ │ │ ├── findModel.ts │ │ │ │ │ │ ├── findOptionsWidget.css │ │ │ │ │ │ ├── findOptionsWidget.ts │ │ │ │ │ │ ├── findState.ts │ │ │ │ │ │ ├── findWidget.css │ │ │ │ │ │ ├── findWidget.ts │ │ │ │ │ │ ├── findWidgetSearchHistory.ts │ │ │ │ │ │ ├── replaceAllCommand.ts │ │ │ │ │ │ ├── replacePattern.ts │ │ │ │ │ │ └── replaceWidgetHistory.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── find.test.ts │ │ │ │ │ ├── findController.test.ts │ │ │ │ │ ├── findModel.test.ts │ │ │ │ │ └── replacePattern.test.ts │ │ │ │ ├── folding/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── folding.css │ │ │ │ │ │ ├── folding.ts │ │ │ │ │ │ ├── foldingDecorations.ts │ │ │ │ │ │ ├── foldingModel.ts │ │ │ │ │ │ ├── foldingRanges.ts │ │ │ │ │ │ ├── hiddenRangeModel.ts │ │ │ │ │ │ ├── indentRangeProvider.ts │ │ │ │ │ │ └── syntaxRangeProvider.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── foldingModel.test.ts │ │ │ │ │ ├── foldingRanges.test.ts │ │ │ │ │ ├── hiddenRangeModel.test.ts │ │ │ │ │ ├── indentFold.test.ts │ │ │ │ │ ├── indentRangeProvider.test.ts │ │ │ │ │ └── syntaxFold.test.ts │ │ │ │ ├── fontZoom/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── fontZoom.ts │ │ │ │ ├── format/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── format.ts │ │ │ │ │ ├── formatActions.ts │ │ │ │ │ └── formattingEdit.ts │ │ │ │ ├── gotoError/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── gotoError.ts │ │ │ │ │ ├── gotoErrorWidget.ts │ │ │ │ │ ├── markerNavigationService.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── gotoErrorWidget.css │ │ │ │ ├── gotoSymbol/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── goToCommands.ts │ │ │ │ │ │ ├── goToSymbol.ts │ │ │ │ │ │ ├── link/ │ │ │ │ │ │ │ ├── clickLinkGesture.ts │ │ │ │ │ │ │ ├── goToDefinitionAtPosition.css │ │ │ │ │ │ │ └── goToDefinitionAtPosition.ts │ │ │ │ │ │ ├── peek/ │ │ │ │ │ │ │ ├── referencesController.ts │ │ │ │ │ │ │ ├── referencesTree.ts │ │ │ │ │ │ │ ├── referencesWidget.css │ │ │ │ │ │ │ └── referencesWidget.ts │ │ │ │ │ │ ├── referencesModel.ts │ │ │ │ │ │ └── symbolNavigation.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── referencesModel.test.ts │ │ │ │ ├── gpu/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── gpuActions.ts │ │ │ │ ├── hover/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── contentHoverComputer.ts │ │ │ │ │ │ ├── contentHoverController.ts │ │ │ │ │ │ ├── contentHoverRendered.ts │ │ │ │ │ │ ├── contentHoverStatusBar.ts │ │ │ │ │ │ ├── contentHoverTypes.ts │ │ │ │ │ │ ├── contentHoverWidget.ts │ │ │ │ │ │ ├── contentHoverWidgetWrapper.ts │ │ │ │ │ │ ├── getHover.ts │ │ │ │ │ │ ├── glyphHoverComputer.ts │ │ │ │ │ │ ├── glyphHoverController.ts │ │ │ │ │ │ ├── glyphHoverWidget.ts │ │ │ │ │ │ ├── hover.css │ │ │ │ │ │ ├── hoverAccessibleViews.ts │ │ │ │ │ │ ├── hoverActionIds.ts │ │ │ │ │ │ ├── hoverActions.ts │ │ │ │ │ │ ├── hoverContribution.ts │ │ │ │ │ │ ├── hoverOperation.ts │ │ │ │ │ │ ├── hoverTypes.ts │ │ │ │ │ │ ├── hoverUtils.ts │ │ │ │ │ │ ├── markdownHoverParticipant.ts │ │ │ │ │ │ ├── markerHoverParticipant.ts │ │ │ │ │ │ └── resizableContentWidget.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── contentHover.test.ts │ │ │ │ ├── inPlaceReplace/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── inPlaceReplace.css │ │ │ │ │ ├── inPlaceReplace.ts │ │ │ │ │ └── inPlaceReplaceCommand.ts │ │ │ │ ├── indentation/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── indentation.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── indentUtils.ts │ │ │ │ │ │ └── indentation.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── indentation.test.ts │ │ │ │ │ └── indentationLineProcessor.test.ts │ │ │ │ ├── inlayHints/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── inlayHints.ts │ │ │ │ │ ├── inlayHintsContribution.ts │ │ │ │ │ ├── inlayHintsController.ts │ │ │ │ │ ├── inlayHintsHover.ts │ │ │ │ │ └── inlayHintsLocations.ts │ │ │ │ ├── inlineCompletions/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ ├── commandIds.ts │ │ │ │ │ │ │ ├── commands.ts │ │ │ │ │ │ │ ├── inlineCompletionContextKeys.ts │ │ │ │ │ │ │ └── inlineCompletionsController.ts │ │ │ │ │ │ ├── hintsWidget/ │ │ │ │ │ │ │ ├── hoverParticipant.ts │ │ │ │ │ │ │ ├── inlineCompletionsHintsWidget.css │ │ │ │ │ │ │ └── inlineCompletionsHintsWidget.ts │ │ │ │ │ │ ├── inlineCompletions.contribution.ts │ │ │ │ │ │ ├── inlineCompletionsAccessibleView.ts │ │ │ │ │ │ ├── model/ │ │ │ │ │ │ │ ├── animation.ts │ │ │ │ │ │ │ ├── changeRecorder.ts │ │ │ │ │ │ │ ├── computeGhostText.ts │ │ │ │ │ │ │ ├── ghostText.ts │ │ │ │ │ │ │ ├── inlineCompletionsModel.ts │ │ │ │ │ │ │ ├── inlineCompletionsSource.ts │ │ │ │ │ │ │ ├── inlineEdit.ts │ │ │ │ │ │ │ ├── inlineEditsAdapter.ts │ │ │ │ │ │ │ ├── provideInlineCompletions.ts │ │ │ │ │ │ │ ├── singleTextEditHelpers.ts │ │ │ │ │ │ │ └── suggestWidgetAdapter.ts │ │ │ │ │ │ ├── structuredLogger.ts │ │ │ │ │ │ ├── utils.ts │ │ │ │ │ │ └── view/ │ │ │ │ │ │ ├── ghostText/ │ │ │ │ │ │ │ ├── ghostTextView.css │ │ │ │ │ │ │ └── ghostTextView.ts │ │ │ │ │ │ ├── inlineCompletionsView.ts │ │ │ │ │ │ └── inlineEdits/ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── gutterIndicatorMenu.ts │ │ │ │ │ │ │ ├── gutterIndicatorView.ts │ │ │ │ │ │ │ └── indicatorView.ts │ │ │ │ │ │ ├── inlineEditWithChanges.ts │ │ │ │ │ │ ├── inlineEditsModel.ts │ │ │ │ │ │ ├── inlineEditsView.ts │ │ │ │ │ │ ├── inlineEditsViewInterface.ts │ │ │ │ │ │ ├── inlineEditsViewProducer.ts │ │ │ │ │ │ ├── inlineEditsViews/ │ │ │ │ │ │ │ ├── debugVisualization.ts │ │ │ │ │ │ │ ├── inlineEditsCollapsedView.ts │ │ │ │ │ │ │ ├── inlineEditsDeletionView.ts │ │ │ │ │ │ │ ├── inlineEditsInsertionView.ts │ │ │ │ │ │ │ ├── inlineEditsLineReplacementView.ts │ │ │ │ │ │ │ ├── inlineEditsSideBySideView.ts │ │ │ │ │ │ │ ├── inlineEditsWordInsertView.ts │ │ │ │ │ │ │ ├── inlineEditsWordReplacementView.ts │ │ │ │ │ │ │ └── originalEditorInlineDiffView.ts │ │ │ │ │ │ ├── theme.ts │ │ │ │ │ │ ├── utils/ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ └── view.css │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── inlineCompletionsModel.test.ts │ │ │ │ │ ├── inlineCompletionsProvider.test.ts │ │ │ │ │ ├── suggestWidgetModel.test.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── inlineProgress/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── inlineProgress.ts │ │ │ │ │ └── inlineProgressWidget.css │ │ │ │ ├── insertFinalNewLine/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── insertFinalNewLine.ts │ │ │ │ │ └── insertFinalNewLineCommand.ts │ │ │ │ ├── lineSelection/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── lineSelection.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── lineSelection.test.ts │ │ │ │ ├── linesOperations/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── copyLinesCommand.ts │ │ │ │ │ │ ├── linesOperations.ts │ │ │ │ │ │ ├── moveLinesCommand.ts │ │ │ │ │ │ └── sortLinesCommand.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── copyLinesCommand.test.ts │ │ │ │ │ ├── linesOperations.test.ts │ │ │ │ │ ├── moveLinesCommand.test.ts │ │ │ │ │ └── sortLinesCommand.test.ts │ │ │ │ ├── linkedEditing/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── linkedEditing.css │ │ │ │ │ │ └── linkedEditing.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── linkedEditing.test.ts │ │ │ │ ├── links/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── getLinks.ts │ │ │ │ │ ├── links.css │ │ │ │ │ └── links.ts │ │ │ │ ├── longLinesHelper/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── longLinesHelper.ts │ │ │ │ ├── message/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── messageController.css │ │ │ │ │ └── messageController.ts │ │ │ │ ├── multicursor/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── multicursor.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── multicursor.test.ts │ │ │ │ ├── parameterHints/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── parameterHints.css │ │ │ │ │ │ ├── parameterHints.ts │ │ │ │ │ │ ├── parameterHintsModel.ts │ │ │ │ │ │ ├── parameterHintsWidget.ts │ │ │ │ │ │ └── provideSignatureHelp.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── parameterHintsModel.test.ts │ │ │ │ ├── peekView/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── peekViewWidget.css │ │ │ │ │ └── peekView.ts │ │ │ │ ├── placeholderText/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── placeholderText.contribution.ts │ │ │ │ │ ├── placeholderText.css │ │ │ │ │ └── placeholderTextContribution.ts │ │ │ │ ├── quickAccess/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── commandsQuickAccess.ts │ │ │ │ │ ├── editorNavigationQuickAccess.ts │ │ │ │ │ ├── gotoLineQuickAccess.ts │ │ │ │ │ └── gotoSymbolQuickAccess.ts │ │ │ │ ├── readOnlyMessage/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── contribution.ts │ │ │ │ ├── rename/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── rename.ts │ │ │ │ │ ├── renameWidget.css │ │ │ │ │ └── renameWidget.ts │ │ │ │ ├── sectionHeaders/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── sectionHeaders.ts │ │ │ │ ├── semanticTokens/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── documentSemanticTokens.ts │ │ │ │ │ │ └── viewportSemanticTokens.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── getSemanticTokens.ts │ │ │ │ │ │ └── semanticTokensConfig.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── documentSemanticTokens.test.ts │ │ │ │ │ └── getSemanticTokens.test.ts │ │ │ │ ├── smartSelect/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── bracketSelections.ts │ │ │ │ │ │ ├── smartSelect.ts │ │ │ │ │ │ └── wordSelections.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── smartSelect.test.ts │ │ │ │ ├── snippet/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── snippet.md │ │ │ │ │ │ ├── snippetController2.ts │ │ │ │ │ │ ├── snippetParser.ts │ │ │ │ │ │ ├── snippetSession.css │ │ │ │ │ │ ├── snippetSession.ts │ │ │ │ │ │ └── snippetVariables.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── snippetController2.old.test.ts │ │ │ │ │ ├── snippetController2.test.ts │ │ │ │ │ ├── snippetParser.test.ts │ │ │ │ │ ├── snippetSession.test.ts │ │ │ │ │ └── snippetVariables.test.ts │ │ │ │ ├── stickyScroll/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── stickyScroll.css │ │ │ │ │ │ ├── stickyScrollActions.ts │ │ │ │ │ │ ├── stickyScrollContribution.ts │ │ │ │ │ │ ├── stickyScrollController.ts │ │ │ │ │ │ ├── stickyScrollElement.ts │ │ │ │ │ │ ├── stickyScrollModelProvider.ts │ │ │ │ │ │ ├── stickyScrollProvider.ts │ │ │ │ │ │ └── stickyScrollWidget.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── stickyScroll.test.ts │ │ │ │ ├── suggest/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── completionModel.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── suggest.css │ │ │ │ │ │ ├── suggest.ts │ │ │ │ │ │ ├── suggestAlternatives.ts │ │ │ │ │ │ ├── suggestCommitCharacters.ts │ │ │ │ │ │ ├── suggestController.ts │ │ │ │ │ │ ├── suggestInlineCompletions.ts │ │ │ │ │ │ ├── suggestMemory.ts │ │ │ │ │ │ ├── suggestModel.ts │ │ │ │ │ │ ├── suggestOvertypingCapturer.ts │ │ │ │ │ │ ├── suggestWidget.ts │ │ │ │ │ │ ├── suggestWidgetDetails.ts │ │ │ │ │ │ ├── suggestWidgetRenderer.ts │ │ │ │ │ │ ├── suggestWidgetStatus.ts │ │ │ │ │ │ ├── wordContextKey.ts │ │ │ │ │ │ └── wordDistance.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── completionModel.test.ts │ │ │ │ │ ├── suggest.test.ts │ │ │ │ │ ├── suggestController.test.ts │ │ │ │ │ ├── suggestInlineCompletions.test.ts │ │ │ │ │ ├── suggestMemory.test.ts │ │ │ │ │ ├── suggestModel.test.ts │ │ │ │ │ └── wordDistance.test.ts │ │ │ │ ├── symbolIcons/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── symbolIcons.css │ │ │ │ │ └── symbolIcons.ts │ │ │ │ ├── toggleTabFocusMode/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── toggleTabFocusMode.ts │ │ │ │ ├── tokenization/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── tokenization.ts │ │ │ │ ├── unicodeHighlighter/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── bannerController.css │ │ │ │ │ ├── bannerController.ts │ │ │ │ │ ├── unicodeHighlighter.css │ │ │ │ │ └── unicodeHighlighter.ts │ │ │ │ ├── unusualLineTerminators/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── unusualLineTerminators.ts │ │ │ │ ├── wordHighlighter/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── highlightDecorations.css │ │ │ │ │ ├── highlightDecorations.ts │ │ │ │ │ ├── textualHighlightProvider.ts │ │ │ │ │ └── wordHighlighter.ts │ │ │ │ ├── wordOperations/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── wordOperations.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── wordOperations.test.ts │ │ │ │ │ └── wordTestUtils.ts │ │ │ │ ├── wordPartOperations/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── wordPartOperations.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── utils.ts │ │ │ │ │ └── wordPartOperations.test.ts │ │ │ │ └── zoneWidget/ │ │ │ │ └── browser/ │ │ │ │ ├── zoneWidget.css │ │ │ │ └── zoneWidget.ts │ │ │ ├── editor.all.ts │ │ │ ├── editor.api.ts │ │ │ ├── editor.main.ts │ │ │ ├── editor.worker.start.ts │ │ │ ├── standalone/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── colorizer.ts │ │ │ │ │ ├── iPadShowKeyboard/ │ │ │ │ │ │ ├── iPadShowKeyboard.css │ │ │ │ │ │ └── iPadShowKeyboard.ts │ │ │ │ │ ├── inspectTokens/ │ │ │ │ │ │ ├── inspectTokens.css │ │ │ │ │ │ └── inspectTokens.ts │ │ │ │ │ ├── quickAccess/ │ │ │ │ │ │ ├── standaloneCommandsQuickAccess.ts │ │ │ │ │ │ ├── standaloneGotoLineQuickAccess.ts │ │ │ │ │ │ ├── standaloneGotoSymbolQuickAccess.ts │ │ │ │ │ │ └── standaloneHelpQuickAccess.ts │ │ │ │ │ ├── quickInput/ │ │ │ │ │ │ ├── standaloneQuickInput.css │ │ │ │ │ │ └── standaloneQuickInputService.ts │ │ │ │ │ ├── referenceSearch/ │ │ │ │ │ │ └── standaloneReferenceSearch.ts │ │ │ │ │ ├── standalone-tokens.css │ │ │ │ │ ├── standaloneCodeEditor.ts │ │ │ │ │ ├── standaloneCodeEditorService.ts │ │ │ │ │ ├── standaloneEditor.ts │ │ │ │ │ ├── standaloneLanguages.ts │ │ │ │ │ ├── standaloneLayoutService.ts │ │ │ │ │ ├── standaloneServices.ts │ │ │ │ │ ├── standaloneThemeService.ts │ │ │ │ │ ├── standaloneTreeSitterService.ts │ │ │ │ │ ├── standaloneWebWorker.ts │ │ │ │ │ └── toggleHighContrast/ │ │ │ │ │ └── toggleHighContrast.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── monarch/ │ │ │ │ │ │ ├── monarchCommon.ts │ │ │ │ │ │ ├── monarchCompile.ts │ │ │ │ │ │ ├── monarchLexer.ts │ │ │ │ │ │ └── monarchTypes.ts │ │ │ │ │ ├── standaloneTheme.ts │ │ │ │ │ └── themes.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── monarch.test.ts │ │ │ │ ├── standaloneLanguages.test.ts │ │ │ │ └── standaloneServices.test.ts │ │ │ └── test/ │ │ │ ├── browser/ │ │ │ │ ├── commands/ │ │ │ │ │ ├── shiftCommand.test.ts │ │ │ │ │ ├── sideEditing.test.ts │ │ │ │ │ └── trimTrailingWhitespaceCommand.test.ts │ │ │ │ ├── config/ │ │ │ │ │ ├── editorConfiguration.test.ts │ │ │ │ │ ├── editorLayoutProvider.test.ts │ │ │ │ │ └── testConfiguration.ts │ │ │ │ ├── controller/ │ │ │ │ │ ├── cursor.integrationTest.ts │ │ │ │ │ ├── cursor.test.ts │ │ │ │ │ ├── cursorMoveCommand.test.ts │ │ │ │ │ ├── imeRecordedTypes.ts │ │ │ │ │ ├── imeRecorder.html │ │ │ │ │ ├── imeRecorder.ts │ │ │ │ │ ├── imeTester.html │ │ │ │ │ ├── imeTester.ts │ │ │ │ │ ├── textAreaInput.test.ts │ │ │ │ │ └── textAreaState.test.ts │ │ │ │ ├── diff/ │ │ │ │ │ └── testDiffProviderFactoryService.ts │ │ │ │ ├── editorTestServices.ts │ │ │ │ ├── gpu/ │ │ │ │ │ ├── atlas/ │ │ │ │ │ │ ├── testUtil.ts │ │ │ │ │ │ ├── textureAtlas.test.ts │ │ │ │ │ │ └── textureAtlasAllocator.test.ts │ │ │ │ │ ├── bufferDirtyTracker.test.ts │ │ │ │ │ ├── decorationCssRulerExtractor.test.ts │ │ │ │ │ └── objectCollectionBuffer.test.ts │ │ │ │ ├── services/ │ │ │ │ │ ├── decorationRenderOptions.test.ts │ │ │ │ │ ├── openerService.test.ts │ │ │ │ │ └── treeSitterParserService.test.ts │ │ │ │ ├── testCodeEditor.ts │ │ │ │ ├── testCommand.ts │ │ │ │ ├── view/ │ │ │ │ │ ├── minimapCharRenderer.test.ts │ │ │ │ │ └── viewLayer.test.ts │ │ │ │ ├── viewModel/ │ │ │ │ │ ├── modelLineProjection.test.ts │ │ │ │ │ ├── testViewModel.ts │ │ │ │ │ ├── viewModelDecorations.test.ts │ │ │ │ │ └── viewModelImpl.test.ts │ │ │ │ └── widget/ │ │ │ │ ├── codeEditorWidget.test.ts │ │ │ │ ├── diffEditorWidget.test.ts │ │ │ │ └── observableCodeEditor.test.ts │ │ │ ├── common/ │ │ │ │ ├── codecs/ │ │ │ │ │ ├── linesDecoder.test.ts │ │ │ │ │ ├── markdownDecoder.test.ts │ │ │ │ │ └── simpleDecoder.test.ts │ │ │ │ ├── controller/ │ │ │ │ │ └── cursorAtomicMoveOperations.test.ts │ │ │ │ ├── core/ │ │ │ │ │ ├── characterClassifier.test.ts │ │ │ │ │ ├── cursorColumns.test.ts │ │ │ │ │ ├── lineRange.test.ts │ │ │ │ │ ├── lineTokens.test.ts │ │ │ │ │ ├── positionOffsetTransformer.test.ts │ │ │ │ │ ├── random.ts │ │ │ │ │ ├── range.test.ts │ │ │ │ │ ├── stringBuilder.test.ts │ │ │ │ │ ├── testLineToken.ts │ │ │ │ │ └── textEdit.test.ts │ │ │ │ ├── diff/ │ │ │ │ │ └── diffComputer.test.ts │ │ │ │ ├── model/ │ │ │ │ │ ├── bracketPairColorizer/ │ │ │ │ │ │ ├── beforeEditPositionMapper.test.ts │ │ │ │ │ │ ├── brackets.test.ts │ │ │ │ │ │ ├── combineTextEditInfos.test.ts │ │ │ │ │ │ ├── concat23Trees.test.ts │ │ │ │ │ │ ├── getBracketPairsInRange.test.ts │ │ │ │ │ │ ├── length.test.ts │ │ │ │ │ │ ├── smallImmutableSet.test.ts │ │ │ │ │ │ └── tokenizer.test.ts │ │ │ │ │ ├── editStack.test.ts │ │ │ │ │ ├── editableTextModel.test.ts │ │ │ │ │ ├── editableTextModelAuto.test.ts │ │ │ │ │ ├── editableTextModelTestUtils.ts │ │ │ │ │ ├── intervalTree.test.ts │ │ │ │ │ ├── linesTextBuffer/ │ │ │ │ │ │ ├── linesTextBuffer.test.ts │ │ │ │ │ │ └── linesTextBufferBuilder.test.ts │ │ │ │ │ ├── model.line.test.ts │ │ │ │ │ ├── model.modes.test.ts │ │ │ │ │ ├── model.test.ts │ │ │ │ │ ├── modelDecorations.test.ts │ │ │ │ │ ├── modelEditOperation.test.ts │ │ │ │ │ ├── modelInjectedText.test.ts │ │ │ │ │ ├── pieceTreeTextBuffer/ │ │ │ │ │ │ └── pieceTreeTextBuffer.test.ts │ │ │ │ │ ├── textChange.test.ts │ │ │ │ │ ├── textModel.test.ts │ │ │ │ │ ├── textModelSearch.test.ts │ │ │ │ │ ├── textModelTokens.test.ts │ │ │ │ │ ├── textModelWithTokens.test.ts │ │ │ │ │ ├── tokenStore.test.ts │ │ │ │ │ └── tokensStore.test.ts │ │ │ │ ├── modes/ │ │ │ │ │ ├── languageConfiguration.test.ts │ │ │ │ │ ├── languageSelector.test.ts │ │ │ │ │ ├── linkComputer.test.ts │ │ │ │ │ ├── supports/ │ │ │ │ │ │ ├── autoClosingPairsRules.ts │ │ │ │ │ │ ├── bracketRules.ts │ │ │ │ │ │ ├── characterPair.test.ts │ │ │ │ │ │ ├── electricCharacter.test.ts │ │ │ │ │ │ ├── indentationRules.ts │ │ │ │ │ │ ├── onEnter.test.ts │ │ │ │ │ │ ├── onEnterRules.ts │ │ │ │ │ │ ├── richEditBrackets.test.ts │ │ │ │ │ │ └── tokenization.test.ts │ │ │ │ │ ├── testLanguageConfigurationService.ts │ │ │ │ │ └── textToHtmlTokenizer.test.ts │ │ │ │ ├── modesTestUtils.ts │ │ │ │ ├── services/ │ │ │ │ │ ├── editorWebWorker.test.ts │ │ │ │ │ ├── findSectionHeaders.test.ts │ │ │ │ │ ├── languageService.test.ts │ │ │ │ │ ├── languagesAssociations.test.ts │ │ │ │ │ ├── languagesRegistry.test.ts │ │ │ │ │ ├── modelService.test.ts │ │ │ │ │ ├── semanticTokensDto.test.ts │ │ │ │ │ ├── semanticTokensProviderStyling.test.ts │ │ │ │ │ ├── testEditorWorkerService.ts │ │ │ │ │ ├── testTextResourcePropertiesService.ts │ │ │ │ │ ├── testTreeSitterService.ts │ │ │ │ │ ├── textResourceConfigurationService.test.ts │ │ │ │ │ └── unicodeTextModelHighlighter.test.ts │ │ │ │ ├── testTextModel.ts │ │ │ │ ├── utils/ │ │ │ │ │ └── testDecoder.ts │ │ │ │ ├── view/ │ │ │ │ │ └── overviewZoneManager.test.ts │ │ │ │ ├── viewLayout/ │ │ │ │ │ ├── lineDecorations.test.ts │ │ │ │ │ ├── linesLayout.test.ts │ │ │ │ │ └── viewLineRenderer.test.ts │ │ │ │ └── viewModel/ │ │ │ │ ├── glyphLanesModel.test.ts │ │ │ │ ├── lineBreakData.test.ts │ │ │ │ ├── monospaceLineBreaksComputer.test.ts │ │ │ │ └── prefixSumComputer.test.ts │ │ │ └── node/ │ │ │ └── diffing/ │ │ │ ├── README.md │ │ │ ├── defaultLinesDiffComputer.test.ts │ │ │ ├── fixtures/ │ │ │ │ ├── bracket-aligning/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── class-replacement/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ ├── advanced.human.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── deletion/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── difficult-move/ │ │ │ │ │ ├── 1.js │ │ │ │ │ ├── 2.js │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── equals/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── false-positive-move/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── fuzzy-matching/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── import-shifting/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── indentation/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── intra-block-align/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── invalid-diff-bug/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── invalid-diff-trimws/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── invalid-ranges/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-131091/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-185779/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-201713/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-202147-trimws/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-204948/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── issue-214049/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── json-brackets/ │ │ │ │ │ ├── 1.json │ │ │ │ │ ├── 2.json │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── just-whitespace/ │ │ │ │ │ ├── 1.js │ │ │ │ │ ├── 2.js │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── method-splitting/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── minimal-diff-character/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── move-1/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── noise-1/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── noise-2/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── noisy-move1/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── penalize-fragmentation/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ ├── advanced.human.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── random-match-1/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── random-match-2/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── random-match-3/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── shifting-parameters/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── shifting-twice/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── sorted-offsets/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── subword/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── trivial/ │ │ │ │ │ ├── 1.txt │ │ │ │ │ ├── 2.txt │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-advanced-bug/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-class/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ ├── advanced.human.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-comments/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-confusing/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-confusing-2/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-diff-word-split/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-example1/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-example2-ts/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-fragmented-eager-diffing/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-fragmented-eager-diffing2/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-fragmented-eager-diffing3/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-import-ws-affinity/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-insert/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-methods/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-shift-to-ws/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-shifting/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-strings/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-too-much-minimization/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-unfragmented-diffing/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── ts-unit-test/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ ├── word-shared-letters/ │ │ │ │ │ ├── 1.tst │ │ │ │ │ ├── 2.tst │ │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ │ └── legacy.expected.diff.json │ │ │ │ └── ws-alignment/ │ │ │ │ ├── 1.tsx │ │ │ │ ├── 2.tsx │ │ │ │ ├── advanced.expected.diff.json │ │ │ │ └── legacy.expected.diff.json │ │ │ └── fixtures.test.ts │ │ ├── loader.js │ │ ├── monaco.d.ts │ │ ├── nls.messages.ts │ │ ├── nls.ts │ │ ├── platform/ │ │ │ ├── accessibility/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── accessibilityService.ts │ │ │ │ │ ├── accessibleView.ts │ │ │ │ │ └── accessibleViewRegistry.ts │ │ │ │ ├── common/ │ │ │ │ │ └── accessibility.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── testAccessibilityService.ts │ │ │ ├── accessibilitySignal/ │ │ │ │ └── browser/ │ │ │ │ ├── accessibilitySignalService.ts │ │ │ │ └── progressAccessibilitySignalScheduler.ts │ │ │ ├── action/ │ │ │ │ └── common/ │ │ │ │ ├── action.ts │ │ │ │ └── actionCommonCategories.ts │ │ │ ├── actionWidget/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── actionList.ts │ │ │ │ │ ├── actionWidget.css │ │ │ │ │ └── actionWidget.ts │ │ │ │ └── common/ │ │ │ │ └── actionWidget.ts │ │ │ ├── actions/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── actionViewItemService.ts │ │ │ │ │ ├── buttonbar.ts │ │ │ │ │ ├── dropdownActionViewItemWithKeybinding.ts │ │ │ │ │ ├── dropdownWithPrimaryActionViewItem.ts │ │ │ │ │ ├── floatingMenu.ts │ │ │ │ │ ├── menuEntryActionViewItem.css │ │ │ │ │ ├── menuEntryActionViewItem.ts │ │ │ │ │ └── toolbar.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── actions.contribution.ts │ │ │ │ │ ├── actions.ts │ │ │ │ │ ├── menuResetAction.ts │ │ │ │ │ └── menuService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── menuService.test.ts │ │ │ ├── assignment/ │ │ │ │ └── common/ │ │ │ │ ├── assignment.ts │ │ │ │ └── assignmentService.ts │ │ │ ├── auxiliaryWindow/ │ │ │ │ └── electron-main/ │ │ │ │ ├── auxiliaryWindow.ts │ │ │ │ ├── auxiliaryWindows.ts │ │ │ │ └── auxiliaryWindowsMainService.ts │ │ │ ├── backup/ │ │ │ │ ├── common/ │ │ │ │ │ └── backup.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── backup.ts │ │ │ │ │ └── backupMainService.ts │ │ │ │ ├── node/ │ │ │ │ │ └── backup.ts │ │ │ │ └── test/ │ │ │ │ └── electron-main/ │ │ │ │ └── backupMainService.test.ts │ │ │ ├── checksum/ │ │ │ │ ├── common/ │ │ │ │ │ └── checksumService.ts │ │ │ │ ├── node/ │ │ │ │ │ └── checksumService.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ ├── checksumService.test.ts │ │ │ │ └── fixtures/ │ │ │ │ └── lorem.txt │ │ │ ├── clipboard/ │ │ │ │ ├── browser/ │ │ │ │ │ └── clipboardService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── clipboardService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── testClipboardService.ts │ │ │ ├── commands/ │ │ │ │ ├── common/ │ │ │ │ │ └── commands.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── commands.test.ts │ │ │ │ └── nullCommandService.ts │ │ │ ├── configuration/ │ │ │ │ ├── common/ │ │ │ │ │ ├── configuration.ts │ │ │ │ │ ├── configurationModels.ts │ │ │ │ │ ├── configurationRegistry.ts │ │ │ │ │ ├── configurationService.ts │ │ │ │ │ └── configurations.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── configuration.test.ts │ │ │ │ ├── configurationModels.test.ts │ │ │ │ ├── configurationRegistry.test.ts │ │ │ │ ├── configurationService.test.ts │ │ │ │ ├── configurations.test.ts │ │ │ │ ├── policyConfiguration.test.ts │ │ │ │ └── testConfigurationService.ts │ │ │ ├── contextkey/ │ │ │ │ ├── browser/ │ │ │ │ │ └── contextKeyService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── contextkey.ts │ │ │ │ │ ├── contextkeys.ts │ │ │ │ │ └── scanner.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── contextkey.test.ts │ │ │ │ └── common/ │ │ │ │ ├── contextkey.test.ts │ │ │ │ ├── parser.test.ts │ │ │ │ └── scanner.test.ts │ │ │ ├── contextview/ │ │ │ │ └── browser/ │ │ │ │ ├── contextMenuHandler.ts │ │ │ │ ├── contextMenuService.ts │ │ │ │ ├── contextView.ts │ │ │ │ └── contextViewService.ts │ │ │ ├── cssDev/ │ │ │ │ └── node/ │ │ │ │ └── cssDevService.ts │ │ │ ├── debug/ │ │ │ │ ├── common/ │ │ │ │ │ ├── extensionHostDebug.ts │ │ │ │ │ └── extensionHostDebugIpc.ts │ │ │ │ └── electron-main/ │ │ │ │ └── extensionHostDebugIpc.ts │ │ │ ├── diagnostics/ │ │ │ │ ├── common/ │ │ │ │ │ └── diagnostics.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── diagnosticsMainService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── diagnosticsService.ts │ │ │ │ └── node/ │ │ │ │ └── diagnosticsService.ts │ │ │ ├── dialogs/ │ │ │ │ ├── browser/ │ │ │ │ │ └── dialog.ts │ │ │ │ ├── common/ │ │ │ │ │ └── dialogs.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── dialogMainService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── dialog.test.ts │ │ │ │ └── testDialogService.ts │ │ │ ├── dnd/ │ │ │ │ └── browser/ │ │ │ │ └── dnd.ts │ │ │ ├── download/ │ │ │ │ └── common/ │ │ │ │ ├── download.ts │ │ │ │ ├── downloadIpc.ts │ │ │ │ └── downloadService.ts │ │ │ ├── editor/ │ │ │ │ └── common/ │ │ │ │ └── editor.ts │ │ │ ├── encryption/ │ │ │ │ ├── common/ │ │ │ │ │ └── encryptionService.ts │ │ │ │ └── electron-main/ │ │ │ │ └── encryptionMainService.ts │ │ │ ├── environment/ │ │ │ │ ├── common/ │ │ │ │ │ ├── argv.ts │ │ │ │ │ ├── environment.ts │ │ │ │ │ └── environmentService.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── environmentMainService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── argv.ts │ │ │ │ │ ├── argvHelper.ts │ │ │ │ │ ├── environmentService.ts │ │ │ │ │ ├── stdin.ts │ │ │ │ │ ├── userDataPath.ts │ │ │ │ │ └── wait.ts │ │ │ │ └── test/ │ │ │ │ ├── electron-main/ │ │ │ │ │ └── environmentMainService.test.ts │ │ │ │ └── node/ │ │ │ │ ├── argv.test.ts │ │ │ │ ├── environmentService.test.ts │ │ │ │ ├── nativeModules.integrationTest.ts │ │ │ │ └── userDataPath.test.ts │ │ │ ├── extensionManagement/ │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractExtensionManagementService.ts │ │ │ │ │ ├── allowedExtensionsService.ts │ │ │ │ │ ├── configRemotes.ts │ │ │ │ │ ├── extensionEnablementService.ts │ │ │ │ │ ├── extensionGalleryManifest.ts │ │ │ │ │ ├── extensionGalleryManifestService.ts │ │ │ │ │ ├── extensionGalleryManifestServiceIpc.ts │ │ │ │ │ ├── extensionGalleryService.ts │ │ │ │ │ ├── extensionManagement.ts │ │ │ │ │ ├── extensionManagementCLI.ts │ │ │ │ │ ├── extensionManagementIpc.ts │ │ │ │ │ ├── extensionManagementUtil.ts │ │ │ │ │ ├── extensionNls.ts │ │ │ │ │ ├── extensionStorage.ts │ │ │ │ │ ├── extensionTipsService.ts │ │ │ │ │ ├── extensionsProfileScannerService.ts │ │ │ │ │ ├── extensionsScannerService.ts │ │ │ │ │ ├── implicitActivationEvents.ts │ │ │ │ │ └── unsupportedExtensionsMigration.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── extensionsProfileScannerService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── extensionDownloader.ts │ │ │ │ │ ├── extensionLifecycle.ts │ │ │ │ │ ├── extensionManagementService.ts │ │ │ │ │ ├── extensionManagementUtil.ts │ │ │ │ │ ├── extensionSignatureVerificationService.ts │ │ │ │ │ ├── extensionTipsService.ts │ │ │ │ │ ├── extensionsManifestCache.ts │ │ │ │ │ ├── extensionsProfileScannerService.ts │ │ │ │ │ ├── extensionsScannerService.ts │ │ │ │ │ └── extensionsWatcher.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ ├── allowedExtensionsService.test.ts │ │ │ │ │ ├── configRemotes.test.ts │ │ │ │ │ ├── extensionGalleryService.test.ts │ │ │ │ │ ├── extensionManagement.test.ts │ │ │ │ │ ├── extensionNls.test.ts │ │ │ │ │ └── extensionsProfileScannerService.test.ts │ │ │ │ └── node/ │ │ │ │ ├── extensionDownloader.test.ts │ │ │ │ └── extensionsScannerService.test.ts │ │ │ ├── extensionRecommendations/ │ │ │ │ └── common/ │ │ │ │ ├── extensionRecommendations.ts │ │ │ │ └── extensionRecommendationsIpc.ts │ │ │ ├── extensionResourceLoader/ │ │ │ │ ├── browser/ │ │ │ │ │ └── extensionResourceLoaderService.ts │ │ │ │ └── common/ │ │ │ │ ├── extensionResourceLoader.ts │ │ │ │ └── extensionResourceLoaderService.ts │ │ │ ├── extensions/ │ │ │ │ ├── common/ │ │ │ │ │ ├── extensionHostStarter.ts │ │ │ │ │ ├── extensionValidator.ts │ │ │ │ │ ├── extensions.ts │ │ │ │ │ └── extensionsApiProposals.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── extensionHostStarter.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── extensionValidator.test.ts │ │ │ │ └── extensions.test.ts │ │ │ ├── externalServices/ │ │ │ │ └── common/ │ │ │ │ ├── marketplace.ts │ │ │ │ └── serviceMachineId.ts │ │ │ ├── externalTerminal/ │ │ │ │ ├── common/ │ │ │ │ │ └── externalTerminal.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── externalTerminal.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── externalTerminalService.ts │ │ │ │ ├── node/ │ │ │ │ │ └── externalTerminalService.ts │ │ │ │ └── test/ │ │ │ │ └── electron-main/ │ │ │ │ └── externalTerminalService.test.ts │ │ │ ├── files/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── htmlFileSystemProvider.ts │ │ │ │ │ ├── indexedDBFileSystemProvider.ts │ │ │ │ │ └── webFileSystemAccess.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── diskFileSystemProvider.ts │ │ │ │ │ ├── diskFileSystemProviderClient.ts │ │ │ │ │ ├── fileService.ts │ │ │ │ │ ├── files.ts │ │ │ │ │ ├── inMemoryFilesystemProvider.ts │ │ │ │ │ ├── io.ts │ │ │ │ │ └── watcher.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── diskFileSystemProviderServer.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── diskFileSystemProvider.ts │ │ │ │ │ ├── diskFileSystemProviderServer.ts │ │ │ │ │ └── watcher/ │ │ │ │ │ ├── baseWatcher.ts │ │ │ │ │ ├── nodejs/ │ │ │ │ │ │ ├── nodejsClient.ts │ │ │ │ │ │ ├── nodejsWatcher.ts │ │ │ │ │ │ └── nodejsWatcherLib.ts │ │ │ │ │ ├── parcel/ │ │ │ │ │ │ └── parcelWatcher.ts │ │ │ │ │ ├── watcher.ts │ │ │ │ │ ├── watcherClient.ts │ │ │ │ │ ├── watcherMain.ts │ │ │ │ │ └── watcherStats.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── fileService.test.ts │ │ │ │ │ └── indexedDBFileService.integrationTest.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── files.test.ts │ │ │ │ │ ├── nullFileSystemProvider.ts │ │ │ │ │ └── watcher.test.ts │ │ │ │ └── node/ │ │ │ │ ├── diskFileService.integrationTest.ts │ │ │ │ ├── fixtures/ │ │ │ │ │ ├── resolver/ │ │ │ │ │ │ ├── examples/ │ │ │ │ │ │ │ ├── company.js │ │ │ │ │ │ │ ├── conway.js │ │ │ │ │ │ │ ├── employee.js │ │ │ │ │ │ │ └── small.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── other/ │ │ │ │ │ │ │ └── deep/ │ │ │ │ │ │ │ ├── company.js │ │ │ │ │ │ │ ├── conway.js │ │ │ │ │ │ │ ├── employee.js │ │ │ │ │ │ │ └── small.js │ │ │ │ │ │ └── site.css │ │ │ │ │ └── service/ │ │ │ │ │ ├── binary.txt │ │ │ │ │ ├── deep/ │ │ │ │ │ │ ├── company.js │ │ │ │ │ │ ├── conway.js │ │ │ │ │ │ ├── employee.js │ │ │ │ │ │ └── small.js │ │ │ │ │ ├── index.html │ │ │ │ │ ├── lorem.txt │ │ │ │ │ ├── small.txt │ │ │ │ │ ├── small_umlaut.txt │ │ │ │ │ ├── some_utf16le.css │ │ │ │ │ └── some_utf8_bom.txt │ │ │ │ ├── nodejsWatcher.test.ts │ │ │ │ └── parcelWatcher.test.ts │ │ │ ├── history/ │ │ │ │ └── browser/ │ │ │ │ ├── contextScopedHistoryWidget.ts │ │ │ │ └── historyWidgetKeybindingHint.ts │ │ │ ├── hover/ │ │ │ │ ├── browser/ │ │ │ │ │ └── hover.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── nullHoverService.ts │ │ │ ├── instantiation/ │ │ │ │ ├── common/ │ │ │ │ │ ├── descriptors.ts │ │ │ │ │ ├── extensions.ts │ │ │ │ │ ├── graph.ts │ │ │ │ │ ├── instantiation.ts │ │ │ │ │ ├── instantiationService.ts │ │ │ │ │ └── serviceCollection.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── graph.test.ts │ │ │ │ ├── instantiationService.test.ts │ │ │ │ └── instantiationServiceMock.ts │ │ │ ├── ipc/ │ │ │ │ ├── common/ │ │ │ │ │ ├── mainProcessService.ts │ │ │ │ │ └── services.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── mainProcessService.ts │ │ │ │ └── services.ts │ │ │ ├── jsonschemas/ │ │ │ │ └── common/ │ │ │ │ └── jsonContributionRegistry.ts │ │ │ ├── keybinding/ │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractKeybindingService.ts │ │ │ │ │ ├── baseResolvedKeybinding.ts │ │ │ │ │ ├── keybinding.ts │ │ │ │ │ ├── keybindingResolver.ts │ │ │ │ │ ├── keybindingsRegistry.ts │ │ │ │ │ ├── resolvedKeybindingItem.ts │ │ │ │ │ └── usLayoutResolvedKeybinding.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── abstractKeybindingService.test.ts │ │ │ │ ├── keybindingLabels.test.ts │ │ │ │ ├── keybindingResolver.test.ts │ │ │ │ ├── keybindingsTestUtils.ts │ │ │ │ └── mockKeybindingService.ts │ │ │ ├── keyboardLayout/ │ │ │ │ ├── common/ │ │ │ │ │ ├── keyboardConfig.ts │ │ │ │ │ ├── keyboardLayout.ts │ │ │ │ │ ├── keyboardLayoutService.ts │ │ │ │ │ └── keyboardMapper.ts │ │ │ │ └── electron-main/ │ │ │ │ └── keyboardLayoutMainService.ts │ │ │ ├── label/ │ │ │ │ └── common/ │ │ │ │ └── label.ts │ │ │ ├── languagePacks/ │ │ │ │ ├── browser/ │ │ │ │ │ └── languagePacks.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── languagePacks.ts │ │ │ │ │ └── localizedStrings.ts │ │ │ │ └── node/ │ │ │ │ └── languagePacks.ts │ │ │ ├── launch/ │ │ │ │ └── electron-main/ │ │ │ │ └── launchMainService.ts │ │ │ ├── layout/ │ │ │ │ └── browser/ │ │ │ │ ├── layoutService.ts │ │ │ │ └── zIndexRegistry.ts │ │ │ ├── lifecycle/ │ │ │ │ ├── common/ │ │ │ │ │ └── lifecycle.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── lifecycleMainService.ts │ │ │ │ └── node/ │ │ │ │ └── sharedProcessLifecycleService.ts │ │ │ ├── list/ │ │ │ │ └── browser/ │ │ │ │ └── listService.ts │ │ │ ├── log/ │ │ │ │ ├── browser/ │ │ │ │ │ └── log.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── bufferLog.ts │ │ │ │ │ ├── fileLog.ts │ │ │ │ │ ├── log.ts │ │ │ │ │ ├── logIpc.ts │ │ │ │ │ └── logService.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── logIpc.ts │ │ │ │ │ └── loggerService.ts │ │ │ │ └── node/ │ │ │ │ ├── loggerService.ts │ │ │ │ └── spdlogLog.ts │ │ │ ├── markers/ │ │ │ │ ├── common/ │ │ │ │ │ ├── markerService.ts │ │ │ │ │ └── markers.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── markerService.test.ts │ │ │ ├── mcp/ │ │ │ │ ├── common/ │ │ │ │ │ ├── mcpManagementCli.ts │ │ │ │ │ ├── mcpPlatformTypes.ts │ │ │ │ │ └── nativeMcpDiscoveryHelper.ts │ │ │ │ └── node/ │ │ │ │ ├── nativeMcpDiscoveryHelperChannel.ts │ │ │ │ └── nativeMcpDiscoveryHelperService.ts │ │ │ ├── menubar/ │ │ │ │ ├── common/ │ │ │ │ │ └── menubar.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── menubar.ts │ │ │ │ │ └── menubarMainService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── menubar.ts │ │ │ ├── native/ │ │ │ │ ├── common/ │ │ │ │ │ ├── native.ts │ │ │ │ │ └── nativeHostService.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── auth.ts │ │ │ │ └── nativeHostMainService.ts │ │ │ ├── notification/ │ │ │ │ ├── common/ │ │ │ │ │ └── notification.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── testNotificationService.ts │ │ │ ├── observable/ │ │ │ │ └── common/ │ │ │ │ ├── observableMemento.ts │ │ │ │ ├── platformObservableUtils.ts │ │ │ │ ├── wrapInHotClass.ts │ │ │ │ └── wrapInReloadableClass.ts │ │ │ ├── opener/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── link.css │ │ │ │ │ └── link.ts │ │ │ │ ├── common/ │ │ │ │ │ └── opener.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── nullOpenerService.ts │ │ │ │ └── opener.test.ts │ │ │ ├── policy/ │ │ │ │ ├── common/ │ │ │ │ │ ├── filePolicyService.ts │ │ │ │ │ ├── policy.ts │ │ │ │ │ └── policyIpc.ts │ │ │ │ └── node/ │ │ │ │ └── nativePolicyService.ts │ │ │ ├── process/ │ │ │ │ ├── common/ │ │ │ │ │ └── process.ts │ │ │ │ └── electron-main/ │ │ │ │ └── processMainService.ts │ │ │ ├── product/ │ │ │ │ └── common/ │ │ │ │ ├── product.ts │ │ │ │ └── productService.ts │ │ │ ├── profiling/ │ │ │ │ ├── common/ │ │ │ │ │ ├── profiling.ts │ │ │ │ │ ├── profilingModel.ts │ │ │ │ │ └── profilingTelemetrySpec.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── windowProfiling.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── profileAnalysisWorker.ts │ │ │ │ │ ├── profileAnalysisWorkerMain.ts │ │ │ │ │ ├── profileAnalysisWorkerService.ts │ │ │ │ │ └── profilingService.ts │ │ │ │ └── node/ │ │ │ │ └── profilingService.ts │ │ │ ├── progress/ │ │ │ │ ├── common/ │ │ │ │ │ └── progress.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── progress.test.ts │ │ │ ├── prompts/ │ │ │ │ ├── common/ │ │ │ │ │ ├── config.ts │ │ │ │ │ └── constants.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── config.test.ts │ │ │ │ ├── constants.test.ts │ │ │ │ └── utils/ │ │ │ │ ├── mock.test.ts │ │ │ │ └── mock.ts │ │ │ ├── protocol/ │ │ │ │ └── electron-main/ │ │ │ │ ├── protocol.ts │ │ │ │ └── protocolMainService.ts │ │ │ ├── quickinput/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── commandsQuickAccess.ts │ │ │ │ │ ├── helpQuickAccess.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── quickInput.css │ │ │ │ │ ├── pickerQuickAccess.ts │ │ │ │ │ ├── quickAccess.ts │ │ │ │ │ ├── quickInput.ts │ │ │ │ │ ├── quickInputActions.ts │ │ │ │ │ ├── quickInputBox.ts │ │ │ │ │ ├── quickInputController.ts │ │ │ │ │ ├── quickInputService.ts │ │ │ │ │ ├── quickInputTree.ts │ │ │ │ │ ├── quickInputUtils.ts │ │ │ │ │ └── quickPickPin.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── quickAccess.ts │ │ │ │ │ └── quickInput.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── quickinput.test.ts │ │ │ ├── registry/ │ │ │ │ ├── common/ │ │ │ │ │ └── platform.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── platform.test.ts │ │ │ ├── remote/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserSocketFactory.ts │ │ │ │ │ └── remoteAuthorityResolverService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── electronRemoteResources.ts │ │ │ │ │ ├── managedSocket.ts │ │ │ │ │ ├── remote.ts │ │ │ │ │ ├── remoteAgentConnection.ts │ │ │ │ │ ├── remoteAgentEnvironment.ts │ │ │ │ │ ├── remoteAuthorityResolver.ts │ │ │ │ │ ├── remoteExtensionsScanner.ts │ │ │ │ │ ├── remoteHosts.ts │ │ │ │ │ ├── remoteSocketFactoryService.ts │ │ │ │ │ └── sharedProcessTunnelService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── electronRemoteResourceLoader.ts │ │ │ │ │ ├── remoteAuthorityResolverService.ts │ │ │ │ │ └── sharedProcessTunnelService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── nodeSocketFactory.ts │ │ │ │ │ └── wsl.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ └── remoteHosts.test.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── remoteAuthorityResolverService.test.ts │ │ │ ├── remoteTunnel/ │ │ │ │ ├── common/ │ │ │ │ │ └── remoteTunnel.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── remoteTunnelService.ts │ │ │ │ └── node/ │ │ │ │ └── remoteTunnelService.ts │ │ │ ├── request/ │ │ │ │ ├── common/ │ │ │ │ │ ├── request.ts │ │ │ │ │ └── requestIpc.ts │ │ │ │ ├── electron-utility/ │ │ │ │ │ └── requestService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── proxy.ts │ │ │ │ │ └── requestService.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ └── requestService.test.ts │ │ │ ├── secrets/ │ │ │ │ ├── common/ │ │ │ │ │ └── secrets.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── secrets.test.ts │ │ │ │ └── testSecretStorageService.ts │ │ │ ├── sharedProcess/ │ │ │ │ ├── common/ │ │ │ │ │ └── sharedProcess.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── sharedProcess.ts │ │ │ │ └── node/ │ │ │ │ └── sharedProcess.ts │ │ │ ├── shell/ │ │ │ │ └── node/ │ │ │ │ └── shellEnv.ts │ │ │ ├── sign/ │ │ │ │ ├── browser/ │ │ │ │ │ └── signService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractSignService.ts │ │ │ │ │ └── sign.ts │ │ │ │ └── node/ │ │ │ │ └── signService.ts │ │ │ ├── state/ │ │ │ │ ├── node/ │ │ │ │ │ ├── state.ts │ │ │ │ │ └── stateService.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ └── state.test.ts │ │ │ ├── storage/ │ │ │ │ ├── common/ │ │ │ │ │ ├── storage.ts │ │ │ │ │ ├── storageIpc.ts │ │ │ │ │ └── storageService.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── storageIpc.ts │ │ │ │ │ ├── storageMain.ts │ │ │ │ │ └── storageMainService.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ └── storageService.test.ts │ │ │ │ └── electron-main/ │ │ │ │ └── storageMainService.test.ts │ │ │ ├── telemetry/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── 1dsAppender.ts │ │ │ │ │ └── errorTelemetry.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── 1dsAppender.ts │ │ │ │ │ ├── commonProperties.ts │ │ │ │ │ ├── errorTelemetry.ts │ │ │ │ │ ├── gdprTypings.ts │ │ │ │ │ ├── remoteTelemetryChannel.ts │ │ │ │ │ ├── serverTelemetryService.ts │ │ │ │ │ ├── telemetry.ts │ │ │ │ │ ├── telemetryIpc.ts │ │ │ │ │ ├── telemetryLogAppender.ts │ │ │ │ │ ├── telemetryService.ts │ │ │ │ │ └── telemetryUtils.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── errorTelemetry.ts │ │ │ │ │ └── telemetryUtils.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── customEndpointTelemetryService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── 1dsAppender.ts │ │ │ │ │ ├── customEndpointTelemetryService.ts │ │ │ │ │ ├── errorTelemetry.ts │ │ │ │ │ ├── telemetry.ts │ │ │ │ │ └── telemetryUtils.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── 1dsAppender.test.ts │ │ │ │ │ └── telemetryService.test.ts │ │ │ │ └── common/ │ │ │ │ └── telemetryLogAppender.test.ts │ │ │ ├── terminal/ │ │ │ │ ├── common/ │ │ │ │ │ ├── capabilities/ │ │ │ │ │ │ ├── bufferMarkCapability.ts │ │ │ │ │ │ ├── capabilities.ts │ │ │ │ │ │ ├── commandDetection/ │ │ │ │ │ │ │ ├── promptInputModel.ts │ │ │ │ │ │ │ └── terminalCommand.ts │ │ │ │ │ │ ├── commandDetectionCapability.ts │ │ │ │ │ │ ├── cwdDetectionCapability.ts │ │ │ │ │ │ ├── naiveCwdDetectionCapability.ts │ │ │ │ │ │ ├── partialCommandDetectionCapability.ts │ │ │ │ │ │ ├── shellEnvDetectionCapability.ts │ │ │ │ │ │ └── terminalCapabilityStore.ts │ │ │ │ │ ├── environmentVariable.ts │ │ │ │ │ ├── environmentVariableCollection.ts │ │ │ │ │ ├── environmentVariableShared.ts │ │ │ │ │ ├── requestStore.ts │ │ │ │ │ ├── terminal.ts │ │ │ │ │ ├── terminalDataBuffering.ts │ │ │ │ │ ├── terminalEnvironment.ts │ │ │ │ │ ├── terminalLogService.ts │ │ │ │ │ ├── terminalPlatformConfiguration.ts │ │ │ │ │ ├── terminalProcess.ts │ │ │ │ │ ├── terminalProfiles.ts │ │ │ │ │ ├── terminalRecorder.ts │ │ │ │ │ ├── terminalStrings.ts │ │ │ │ │ └── xterm/ │ │ │ │ │ └── shellIntegrationAddon.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── electronPtyHostStarter.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── childProcessMonitor.ts │ │ │ │ │ ├── heartbeatService.ts │ │ │ │ │ ├── nodePtyHostStarter.ts │ │ │ │ │ ├── ptyHost.ts │ │ │ │ │ ├── ptyHostMain.ts │ │ │ │ │ ├── ptyHostService.ts │ │ │ │ │ ├── ptyService.ts │ │ │ │ │ ├── terminalContrib/ │ │ │ │ │ │ └── autoReplies/ │ │ │ │ │ │ ├── autoRepliesContribController.ts │ │ │ │ │ │ └── terminalAutoResponder.ts │ │ │ │ │ ├── terminalEnvironment.ts │ │ │ │ │ ├── terminalProcess.ts │ │ │ │ │ ├── terminalProfiles.ts │ │ │ │ │ └── windowsShellHelper.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ ├── capabilities/ │ │ │ │ │ │ └── commandDetection/ │ │ │ │ │ │ └── promptInputModel.test.ts │ │ │ │ │ ├── requestStore.test.ts │ │ │ │ │ ├── terminalEnvironment.test.ts │ │ │ │ │ ├── terminalProcess.test.ts │ │ │ │ │ ├── terminalProfiles.test.ts │ │ │ │ │ └── terminalRecorder.test.ts │ │ │ │ └── node/ │ │ │ │ └── terminalEnvironment.test.ts │ │ │ ├── test/ │ │ │ │ └── electron-main/ │ │ │ │ └── workbenchTestServices.ts │ │ │ ├── theme/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── defaultStyles.ts │ │ │ │ │ └── iconsStyleSheet.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── colorRegistry.ts │ │ │ │ │ ├── colorUtils.ts │ │ │ │ │ ├── colors/ │ │ │ │ │ │ ├── baseColors.ts │ │ │ │ │ │ ├── chartsColors.ts │ │ │ │ │ │ ├── editorColors.ts │ │ │ │ │ │ ├── inputColors.ts │ │ │ │ │ │ ├── listColors.ts │ │ │ │ │ │ ├── menuColors.ts │ │ │ │ │ │ ├── minimapColors.ts │ │ │ │ │ │ ├── miscColors.ts │ │ │ │ │ │ ├── quickpickColors.ts │ │ │ │ │ │ └── searchColors.ts │ │ │ │ │ ├── iconRegistry.ts │ │ │ │ │ ├── theme.ts │ │ │ │ │ ├── themeService.ts │ │ │ │ │ └── tokenClassificationRegistry.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── themeMainService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── testThemeService.ts │ │ │ ├── tunnel/ │ │ │ │ ├── common/ │ │ │ │ │ └── tunnel.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── sharedProcessTunnelService.ts │ │ │ │ │ └── tunnelService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── tunnel.test.ts │ │ │ ├── undoRedo/ │ │ │ │ ├── common/ │ │ │ │ │ ├── undoRedo.ts │ │ │ │ │ └── undoRedoService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── undoRedoService.test.ts │ │ │ ├── update/ │ │ │ │ ├── common/ │ │ │ │ │ ├── update.config.contribution.ts │ │ │ │ │ ├── update.ts │ │ │ │ │ └── updateIpc.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── abstractUpdateService.ts │ │ │ │ ├── updateService.darwin.ts │ │ │ │ ├── updateService.linux.ts │ │ │ │ ├── updateService.snap.ts │ │ │ │ └── updateService.win32.ts │ │ │ ├── uriIdentity/ │ │ │ │ ├── common/ │ │ │ │ │ ├── uriIdentity.ts │ │ │ │ │ └── uriIdentityService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── uriIdentityService.test.ts │ │ │ ├── url/ │ │ │ │ ├── common/ │ │ │ │ │ ├── url.ts │ │ │ │ │ ├── urlIpc.ts │ │ │ │ │ └── urlService.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── electronUrlListener.ts │ │ │ │ └── url.ts │ │ │ ├── userData/ │ │ │ │ ├── common/ │ │ │ │ │ └── fileUserDataProvider.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── fileUserDataProvider.test.ts │ │ │ ├── userDataProfile/ │ │ │ │ ├── browser/ │ │ │ │ │ └── userDataProfile.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── userDataProfile.ts │ │ │ │ │ ├── userDataProfileIpc.ts │ │ │ │ │ └── userDataProfileStorageService.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── userDataProfile.ts │ │ │ │ │ ├── userDataProfileStorageIpc.ts │ │ │ │ │ └── userDataProfilesHandler.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── userDataProfileStorageService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── userDataProfile.ts │ │ │ │ │ └── userDataProfileStorageService.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ ├── userDataProfileService.test.ts │ │ │ │ │ └── userDataProfileStorageService.test.ts │ │ │ │ └── electron-main/ │ │ │ │ └── userDataProfileMainService.test.ts │ │ │ ├── userDataSync/ │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractSynchronizer.ts │ │ │ │ │ ├── content.ts │ │ │ │ │ ├── extensionsMerge.ts │ │ │ │ │ ├── extensionsSync.ts │ │ │ │ │ ├── globalStateMerge.ts │ │ │ │ │ ├── globalStateSync.ts │ │ │ │ │ ├── ignoredExtensions.ts │ │ │ │ │ ├── keybindingsMerge.ts │ │ │ │ │ ├── keybindingsSync.ts │ │ │ │ │ ├── promptsSync/ │ │ │ │ │ │ ├── promptsMerge.ts │ │ │ │ │ │ └── promptsSync.ts │ │ │ │ │ ├── settingsMerge.ts │ │ │ │ │ ├── settingsSync.ts │ │ │ │ │ ├── snippetsMerge.ts │ │ │ │ │ ├── snippetsSync.ts │ │ │ │ │ ├── tasksSync.ts │ │ │ │ │ ├── userDataAutoSyncService.ts │ │ │ │ │ ├── userDataProfilesManifestMerge.ts │ │ │ │ │ ├── userDataProfilesManifestSync.ts │ │ │ │ │ ├── userDataSync.ts │ │ │ │ │ ├── userDataSyncAccount.ts │ │ │ │ │ ├── userDataSyncEnablementService.ts │ │ │ │ │ ├── userDataSyncIpc.ts │ │ │ │ │ ├── userDataSyncLocalStoreService.ts │ │ │ │ │ ├── userDataSyncLog.ts │ │ │ │ │ ├── userDataSyncMachines.ts │ │ │ │ │ ├── userDataSyncResourceProvider.ts │ │ │ │ │ ├── userDataSyncService.ts │ │ │ │ │ ├── userDataSyncServiceIpc.ts │ │ │ │ │ └── userDataSyncStoreService.ts │ │ │ │ ├── node/ │ │ │ │ │ └── userDataAutoSyncService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── extensionsMerge.test.ts │ │ │ │ ├── globalStateMerge.test.ts │ │ │ │ ├── globalStateSync.test.ts │ │ │ │ ├── keybindingsMerge.test.ts │ │ │ │ ├── keybindingsSync.test.ts │ │ │ │ ├── promptsSync/ │ │ │ │ │ └── promptsSync.test.ts │ │ │ │ ├── settingsMerge.test.ts │ │ │ │ ├── settingsSync.test.ts │ │ │ │ ├── snippetsMerge.test.ts │ │ │ │ ├── snippetsSync.test.ts │ │ │ │ ├── synchronizer.test.ts │ │ │ │ ├── tasksSync.test.ts │ │ │ │ ├── userDataAutoSyncService.test.ts │ │ │ │ ├── userDataProfilesManifestMerge.test.ts │ │ │ │ ├── userDataProfilesManifestSync.test.ts │ │ │ │ ├── userDataSyncClient.ts │ │ │ │ ├── userDataSyncService.test.ts │ │ │ │ └── userDataSyncStoreService.test.ts │ │ │ ├── utilityProcess/ │ │ │ │ ├── common/ │ │ │ │ │ └── utilityProcessWorkerService.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── utilityProcess.ts │ │ │ │ └── utilityProcessWorkerMainService.ts │ │ │ ├── webContentExtractor/ │ │ │ │ ├── common/ │ │ │ │ │ └── webContentExtractor.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── cdpAccessibilityDomain.ts │ │ │ │ │ └── webContentExtractorService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── webContentExtractorService.ts │ │ │ │ └── node/ │ │ │ │ └── sharedWebContentExtractorService.ts │ │ │ ├── webview/ │ │ │ │ ├── common/ │ │ │ │ │ ├── mimeTypes.ts │ │ │ │ │ ├── webviewManagerService.ts │ │ │ │ │ └── webviewPortMapping.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── webviewMainService.ts │ │ │ │ └── webviewProtocolProvider.ts │ │ │ ├── window/ │ │ │ │ ├── common/ │ │ │ │ │ └── window.ts │ │ │ │ ├── electron-main/ │ │ │ │ │ └── window.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── window.ts │ │ │ ├── windows/ │ │ │ │ ├── electron-main/ │ │ │ │ │ ├── windowImpl.ts │ │ │ │ │ ├── windows.ts │ │ │ │ │ ├── windowsFinder.ts │ │ │ │ │ ├── windowsMainService.ts │ │ │ │ │ └── windowsStateHandler.ts │ │ │ │ ├── node/ │ │ │ │ │ └── windowTracker.ts │ │ │ │ └── test/ │ │ │ │ └── electron-main/ │ │ │ │ ├── windowsFinder.test.ts │ │ │ │ └── windowsStateHandler.test.ts │ │ │ ├── workspace/ │ │ │ │ ├── common/ │ │ │ │ │ ├── canonicalUri.ts │ │ │ │ │ ├── editSessions.ts │ │ │ │ │ ├── virtualWorkspace.ts │ │ │ │ │ ├── workspace.ts │ │ │ │ │ └── workspaceTrust.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── testWorkspace.ts │ │ │ │ └── workspace.test.ts │ │ │ └── workspaces/ │ │ │ ├── common/ │ │ │ │ └── workspaces.ts │ │ │ ├── electron-main/ │ │ │ │ ├── workspacesHistoryMainService.ts │ │ │ │ ├── workspacesMainService.ts │ │ │ │ └── workspacesManagementMainService.ts │ │ │ ├── node/ │ │ │ │ └── workspaces.ts │ │ │ └── test/ │ │ │ ├── common/ │ │ │ │ └── workspaces.test.ts │ │ │ └── electron-main/ │ │ │ ├── workspaces.test.ts │ │ │ ├── workspacesHistoryStorage.test.ts │ │ │ └── workspacesManagementMainService.test.ts │ │ ├── server/ │ │ │ ├── node/ │ │ │ │ ├── extensionHostConnection.ts │ │ │ │ ├── extensionHostStatusService.ts │ │ │ │ ├── extensionsScannerService.ts │ │ │ │ ├── remoteAgentEnvironmentImpl.ts │ │ │ │ ├── remoteExtensionHostAgentCli.ts │ │ │ │ ├── remoteExtensionHostAgentServer.ts │ │ │ │ ├── remoteExtensionManagement.ts │ │ │ │ ├── remoteExtensionsScanner.ts │ │ │ │ ├── remoteFileSystemProviderServer.ts │ │ │ │ ├── remoteLanguagePacks.ts │ │ │ │ ├── remoteTerminalChannel.ts │ │ │ │ ├── server.cli.ts │ │ │ │ ├── server.main.ts │ │ │ │ ├── serverConnectionToken.ts │ │ │ │ ├── serverEnvironmentService.ts │ │ │ │ ├── serverServices.ts │ │ │ │ └── webClientServer.ts │ │ │ └── test/ │ │ │ └── node/ │ │ │ └── serverConnectionToken.test.ts │ │ └── workbench/ │ │ ├── api/ │ │ │ ├── browser/ │ │ │ │ ├── extensionHost.contribution.ts │ │ │ │ ├── mainThreadAiEmbeddingVector.ts │ │ │ │ ├── mainThreadAiRelatedInformation.ts │ │ │ │ ├── mainThreadAuthentication.ts │ │ │ │ ├── mainThreadBulkEdits.ts │ │ │ │ ├── mainThreadCLICommands.ts │ │ │ │ ├── mainThreadChatAgents2.ts │ │ │ │ ├── mainThreadChatCodeMapper.ts │ │ │ │ ├── mainThreadChatStatus.ts │ │ │ │ ├── mainThreadClipboard.ts │ │ │ │ ├── mainThreadCodeInsets.ts │ │ │ │ ├── mainThreadCommands.ts │ │ │ │ ├── mainThreadComments.ts │ │ │ │ ├── mainThreadConfiguration.ts │ │ │ │ ├── mainThreadConsole.ts │ │ │ │ ├── mainThreadCustomEditors.ts │ │ │ │ ├── mainThreadDebugService.ts │ │ │ │ ├── mainThreadDecorations.ts │ │ │ │ ├── mainThreadDiagnostics.ts │ │ │ │ ├── mainThreadDialogs.ts │ │ │ │ ├── mainThreadDocumentContentProviders.ts │ │ │ │ ├── mainThreadDocuments.ts │ │ │ │ ├── mainThreadDocumentsAndEditors.ts │ │ │ │ ├── mainThreadDownloadService.ts │ │ │ │ ├── mainThreadEditSessionIdentityParticipant.ts │ │ │ │ ├── mainThreadEditor.ts │ │ │ │ ├── mainThreadEditorTabs.ts │ │ │ │ ├── mainThreadEditors.ts │ │ │ │ ├── mainThreadEmbeddings.ts │ │ │ │ ├── mainThreadErrors.ts │ │ │ │ ├── mainThreadExtensionService.ts │ │ │ │ ├── mainThreadFileSystem.ts │ │ │ │ ├── mainThreadFileSystemEventService.ts │ │ │ │ ├── mainThreadInteractive.ts │ │ │ │ ├── mainThreadLabelService.ts │ │ │ │ ├── mainThreadLanguageFeatures.ts │ │ │ │ ├── mainThreadLanguageModelTools.ts │ │ │ │ ├── mainThreadLanguageModels.ts │ │ │ │ ├── mainThreadLanguages.ts │ │ │ │ ├── mainThreadLocalization.ts │ │ │ │ ├── mainThreadLogService.ts │ │ │ │ ├── mainThreadManagedSockets.ts │ │ │ │ ├── mainThreadMcp.ts │ │ │ │ ├── mainThreadMessageService.ts │ │ │ │ ├── mainThreadNotebook.ts │ │ │ │ ├── mainThreadNotebookDocuments.ts │ │ │ │ ├── mainThreadNotebookDocumentsAndEditors.ts │ │ │ │ ├── mainThreadNotebookDto.ts │ │ │ │ ├── mainThreadNotebookEditors.ts │ │ │ │ ├── mainThreadNotebookKernels.ts │ │ │ │ ├── mainThreadNotebookRenderers.ts │ │ │ │ ├── mainThreadNotebookSaveParticipant.ts │ │ │ │ ├── mainThreadOutputService.ts │ │ │ │ ├── mainThreadProfileContentHandlers.ts │ │ │ │ ├── mainThreadProgress.ts │ │ │ │ ├── mainThreadQuickDiff.ts │ │ │ │ ├── mainThreadQuickOpen.ts │ │ │ │ ├── mainThreadRemoteConnectionData.ts │ │ │ │ ├── mainThreadSCM.ts │ │ │ │ ├── mainThreadSaveParticipant.ts │ │ │ │ ├── mainThreadSearch.ts │ │ │ │ ├── mainThreadSecretState.ts │ │ │ │ ├── mainThreadShare.ts │ │ │ │ ├── mainThreadSpeech.ts │ │ │ │ ├── mainThreadStatusBar.ts │ │ │ │ ├── mainThreadStorage.ts │ │ │ │ ├── mainThreadTask.ts │ │ │ │ ├── mainThreadTelemetry.ts │ │ │ │ ├── mainThreadTerminalService.ts │ │ │ │ ├── mainThreadTerminalShellIntegration.ts │ │ │ │ ├── mainThreadTesting.ts │ │ │ │ ├── mainThreadTheming.ts │ │ │ │ ├── mainThreadTimeline.ts │ │ │ │ ├── mainThreadTreeViews.ts │ │ │ │ ├── mainThreadTunnelService.ts │ │ │ │ ├── mainThreadUriOpeners.ts │ │ │ │ ├── mainThreadUrls.ts │ │ │ │ ├── mainThreadWebviewManager.ts │ │ │ │ ├── mainThreadWebviewPanels.ts │ │ │ │ ├── mainThreadWebviewViews.ts │ │ │ │ ├── mainThreadWebviews.ts │ │ │ │ ├── mainThreadWindow.ts │ │ │ │ ├── mainThreadWorkspace.ts │ │ │ │ ├── statusBarExtensionPoint.ts │ │ │ │ └── viewsExtensionPoint.ts │ │ │ ├── common/ │ │ │ │ ├── cache.ts │ │ │ │ ├── configurationExtensionPoint.ts │ │ │ │ ├── extHost.api.impl.ts │ │ │ │ ├── extHost.common.services.ts │ │ │ │ ├── extHost.protocol.ts │ │ │ │ ├── extHostAiRelatedInformation.ts │ │ │ │ ├── extHostApiCommands.ts │ │ │ │ ├── extHostApiDeprecationService.ts │ │ │ │ ├── extHostAuthentication.ts │ │ │ │ ├── extHostBulkEdits.ts │ │ │ │ ├── extHostChatAgents2.ts │ │ │ │ ├── extHostChatStatus.ts │ │ │ │ ├── extHostClipboard.ts │ │ │ │ ├── extHostCodeInsets.ts │ │ │ │ ├── extHostCodeMapper.ts │ │ │ │ ├── extHostCommands.ts │ │ │ │ ├── extHostComments.ts │ │ │ │ ├── extHostConfiguration.ts │ │ │ │ ├── extHostConsoleForwarder.ts │ │ │ │ ├── extHostCustomEditors.ts │ │ │ │ ├── extHostDebugService.ts │ │ │ │ ├── extHostDecorations.ts │ │ │ │ ├── extHostDiagnostics.ts │ │ │ │ ├── extHostDialogs.ts │ │ │ │ ├── extHostDocumentContentProviders.ts │ │ │ │ ├── extHostDocumentData.ts │ │ │ │ ├── extHostDocumentSaveParticipant.ts │ │ │ │ ├── extHostDocuments.ts │ │ │ │ ├── extHostDocumentsAndEditors.ts │ │ │ │ ├── extHostEditorTabs.ts │ │ │ │ ├── extHostEmbedding.ts │ │ │ │ ├── extHostEmbeddingVector.ts │ │ │ │ ├── extHostExtensionActivator.ts │ │ │ │ ├── extHostExtensionService.ts │ │ │ │ ├── extHostFileSystem.ts │ │ │ │ ├── extHostFileSystemConsumer.ts │ │ │ │ ├── extHostFileSystemEventService.ts │ │ │ │ ├── extHostFileSystemInfo.ts │ │ │ │ ├── extHostInitDataService.ts │ │ │ │ ├── extHostInteractive.ts │ │ │ │ ├── extHostLabelService.ts │ │ │ │ ├── extHostLanguageFeatures.ts │ │ │ │ ├── extHostLanguageModelTools.ts │ │ │ │ ├── extHostLanguageModels.ts │ │ │ │ ├── extHostLanguages.ts │ │ │ │ ├── extHostLocalizationService.ts │ │ │ │ ├── extHostLogService.ts │ │ │ │ ├── extHostLoggerService.ts │ │ │ │ ├── extHostManagedSockets.ts │ │ │ │ ├── extHostMcp.ts │ │ │ │ ├── extHostMemento.ts │ │ │ │ ├── extHostMessageService.ts │ │ │ │ ├── extHostNotebook.ts │ │ │ │ ├── extHostNotebookDocument.ts │ │ │ │ ├── extHostNotebookDocumentSaveParticipant.ts │ │ │ │ ├── extHostNotebookDocuments.ts │ │ │ │ ├── extHostNotebookEditor.ts │ │ │ │ ├── extHostNotebookEditors.ts │ │ │ │ ├── extHostNotebookKernels.ts │ │ │ │ ├── extHostNotebookRenderers.ts │ │ │ │ ├── extHostOutput.ts │ │ │ │ ├── extHostProfileContentHandler.ts │ │ │ │ ├── extHostProgress.ts │ │ │ │ ├── extHostQuickDiff.ts │ │ │ │ ├── extHostQuickOpen.ts │ │ │ │ ├── extHostRequireInterceptor.ts │ │ │ │ ├── extHostRpcService.ts │ │ │ │ ├── extHostSCM.ts │ │ │ │ ├── extHostSearch.ts │ │ │ │ ├── extHostSecretState.ts │ │ │ │ ├── extHostSecrets.ts │ │ │ │ ├── extHostShare.ts │ │ │ │ ├── extHostSpeech.ts │ │ │ │ ├── extHostStatusBar.ts │ │ │ │ ├── extHostStorage.ts │ │ │ │ ├── extHostStoragePaths.ts │ │ │ │ ├── extHostTask.ts │ │ │ │ ├── extHostTelemetry.ts │ │ │ │ ├── extHostTerminalService.ts │ │ │ │ ├── extHostTerminalShellIntegration.ts │ │ │ │ ├── extHostTestItem.ts │ │ │ │ ├── extHostTesting.ts │ │ │ │ ├── extHostTestingPrivateApi.ts │ │ │ │ ├── extHostTextEditor.ts │ │ │ │ ├── extHostTextEditors.ts │ │ │ │ ├── extHostTheming.ts │ │ │ │ ├── extHostTimeline.ts │ │ │ │ ├── extHostTreeViews.ts │ │ │ │ ├── extHostTunnelService.ts │ │ │ │ ├── extHostTypeConverters.ts │ │ │ │ ├── extHostTypes.ts │ │ │ │ ├── extHostUriOpener.ts │ │ │ │ ├── extHostUriTransformerService.ts │ │ │ │ ├── extHostUrls.ts │ │ │ │ ├── extHostVariableResolverService.ts │ │ │ │ ├── extHostWebview.ts │ │ │ │ ├── extHostWebviewMessaging.ts │ │ │ │ ├── extHostWebviewPanels.ts │ │ │ │ ├── extHostWebviewView.ts │ │ │ │ ├── extHostWindow.ts │ │ │ │ ├── extHostWorkspace.ts │ │ │ │ ├── extensionHostMain.ts │ │ │ │ ├── jsonValidationExtensionPoint.ts │ │ │ │ └── shared/ │ │ │ │ ├── dataTransferCache.ts │ │ │ │ └── tasks.ts │ │ │ ├── node/ │ │ │ │ ├── extHost.node.services.ts │ │ │ │ ├── extHostCLIServer.ts │ │ │ │ ├── extHostConsoleForwarder.ts │ │ │ │ ├── extHostDebugService.ts │ │ │ │ ├── extHostDiskFileSystemProvider.ts │ │ │ │ ├── extHostDownloadService.ts │ │ │ │ ├── extHostExtensionService.ts │ │ │ │ ├── extHostLoggerService.ts │ │ │ │ ├── extHostMpcNode.ts │ │ │ │ ├── extHostSearch.ts │ │ │ │ ├── extHostStoragePaths.ts │ │ │ │ ├── extHostTask.ts │ │ │ │ ├── extHostTerminalService.ts │ │ │ │ ├── extHostTunnelService.ts │ │ │ │ ├── extHostVariableResolverService.ts │ │ │ │ ├── extensionHostProcess.ts │ │ │ │ ├── proxyResolver.ts │ │ │ │ └── uriTransformer.ts │ │ │ ├── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── extHost.api.impl.test.ts │ │ │ │ │ ├── extHostApiCommands.test.ts │ │ │ │ │ ├── extHostAuthentication.integrationTest.ts │ │ │ │ │ ├── extHostBulkEdits.test.ts │ │ │ │ │ ├── extHostCommands.test.ts │ │ │ │ │ ├── extHostConfiguration.test.ts │ │ │ │ │ ├── extHostDecorations.test.ts │ │ │ │ │ ├── extHostDiagnostics.test.ts │ │ │ │ │ ├── extHostDocumentContentProvider.test.ts │ │ │ │ │ ├── extHostDocumentData.test.perf-data.ts │ │ │ │ │ ├── extHostDocumentData.test.ts │ │ │ │ │ ├── extHostDocumentSaveParticipant.test.ts │ │ │ │ │ ├── extHostDocumentsAndEditors.test.ts │ │ │ │ │ ├── extHostEditorTabs.test.ts │ │ │ │ │ ├── extHostFileSystemEventService.test.ts │ │ │ │ │ ├── extHostLanguageFeatures.test.ts │ │ │ │ │ ├── extHostMessagerService.test.ts │ │ │ │ │ ├── extHostNotebook.test.ts │ │ │ │ │ ├── extHostNotebookKernel.test.ts │ │ │ │ │ ├── extHostTelemetry.test.ts │ │ │ │ │ ├── extHostTesting.test.ts │ │ │ │ │ ├── extHostTextEditor.test.ts │ │ │ │ │ ├── extHostTreeViews.test.ts │ │ │ │ │ ├── extHostTypeConverter.test.ts │ │ │ │ │ ├── extHostTypes.test.ts │ │ │ │ │ ├── extHostWebview.test.ts │ │ │ │ │ ├── extHostWorkspace.test.ts │ │ │ │ │ ├── mainThreadBulkEdits.test.ts │ │ │ │ │ ├── mainThreadCommands.test.ts │ │ │ │ │ ├── mainThreadConfiguration.test.ts │ │ │ │ │ ├── mainThreadDiagnostics.test.ts │ │ │ │ │ ├── mainThreadDocumentContentProviders.test.ts │ │ │ │ │ ├── mainThreadDocuments.test.ts │ │ │ │ │ ├── mainThreadDocumentsAndEditors.test.ts │ │ │ │ │ ├── mainThreadEditors.test.ts │ │ │ │ │ ├── mainThreadManagedSockets.test.ts │ │ │ │ │ ├── mainThreadTreeViews.test.ts │ │ │ │ │ └── mainThreadWorkspace.test.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── extHostExtensionActivator.test.ts │ │ │ │ │ ├── extHostTerminalShellIntegration.test.ts │ │ │ │ │ ├── extensionHostMain.test.ts │ │ │ │ │ └── testRPCProtocol.ts │ │ │ │ └── node/ │ │ │ │ ├── extHostSearch.test.ts │ │ │ │ └── extHostTunnelService.test.ts │ │ │ └── worker/ │ │ │ ├── extHost.worker.services.ts │ │ │ ├── extHostConsoleForwarder.ts │ │ │ ├── extHostExtensionService.ts │ │ │ ├── extensionHostWorker.ts │ │ │ └── extensionHostWorkerMain.ts │ │ ├── browser/ │ │ │ ├── actions/ │ │ │ │ ├── developerActions.ts │ │ │ │ ├── helpActions.ts │ │ │ │ ├── layoutActions.ts │ │ │ │ ├── listCommands.ts │ │ │ │ ├── media/ │ │ │ │ │ └── actions.css │ │ │ │ ├── navigationActions.ts │ │ │ │ ├── quickAccessActions.ts │ │ │ │ ├── textInputActions.ts │ │ │ │ ├── widgetNavigationCommands.ts │ │ │ │ ├── windowActions.ts │ │ │ │ ├── workspaceActions.ts │ │ │ │ └── workspaceCommands.ts │ │ │ ├── actions.ts │ │ │ ├── codeeditor.ts │ │ │ ├── composite.ts │ │ │ ├── contextkeys.ts │ │ │ ├── dnd.ts │ │ │ ├── editor.ts │ │ │ ├── labels.ts │ │ │ ├── layout.ts │ │ │ ├── media/ │ │ │ │ ├── part.css │ │ │ │ └── style.css │ │ │ ├── panecomposite.ts │ │ │ ├── part.ts │ │ │ ├── parts/ │ │ │ │ ├── activitybar/ │ │ │ │ │ ├── activitybarPart.ts │ │ │ │ │ └── media/ │ │ │ │ │ ├── activityaction.css │ │ │ │ │ └── activitybarpart.css │ │ │ │ ├── auxiliarybar/ │ │ │ │ │ ├── auxiliaryBarActions.ts │ │ │ │ │ ├── auxiliaryBarPart.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── auxiliaryBarPart.css │ │ │ │ ├── banner/ │ │ │ │ │ ├── bannerPart.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── bannerpart.css │ │ │ │ ├── compositeBar.ts │ │ │ │ ├── compositeBarActions.ts │ │ │ │ ├── compositePart.ts │ │ │ │ ├── dialogs/ │ │ │ │ │ ├── dialog.web.contribution.ts │ │ │ │ │ └── dialogHandler.ts │ │ │ │ ├── editor/ │ │ │ │ │ ├── auxiliaryEditorPart.ts │ │ │ │ │ ├── binaryDiffEditor.ts │ │ │ │ │ ├── binaryEditor.ts │ │ │ │ │ ├── breadcrumbs.ts │ │ │ │ │ ├── breadcrumbsControl.ts │ │ │ │ │ ├── breadcrumbsModel.ts │ │ │ │ │ ├── breadcrumbsPicker.ts │ │ │ │ │ ├── diffEditorCommands.ts │ │ │ │ │ ├── editor.contribution.ts │ │ │ │ │ ├── editor.ts │ │ │ │ │ ├── editorActions.ts │ │ │ │ │ ├── editorAutoSave.ts │ │ │ │ │ ├── editorCommands.ts │ │ │ │ │ ├── editorCommandsContext.ts │ │ │ │ │ ├── editorConfiguration.ts │ │ │ │ │ ├── editorDropTarget.ts │ │ │ │ │ ├── editorGroupView.ts │ │ │ │ │ ├── editorGroupWatermark.ts │ │ │ │ │ ├── editorPane.ts │ │ │ │ │ ├── editorPanes.ts │ │ │ │ │ ├── editorPart.ts │ │ │ │ │ ├── editorParts.ts │ │ │ │ │ ├── editorPlaceholder.ts │ │ │ │ │ ├── editorQuickAccess.ts │ │ │ │ │ ├── editorStatus.ts │ │ │ │ │ ├── editorTabsControl.ts │ │ │ │ │ ├── editorTitleControl.ts │ │ │ │ │ ├── editorWithViewState.ts │ │ │ │ │ ├── editorsObserver.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── breadcrumbscontrol.css │ │ │ │ │ │ ├── editordroptarget.css │ │ │ │ │ │ ├── editorgroupview.css │ │ │ │ │ │ ├── editorplaceholder.css │ │ │ │ │ │ ├── editorquickaccess.css │ │ │ │ │ │ ├── editorstatus.css │ │ │ │ │ │ ├── editortabscontrol.css │ │ │ │ │ │ ├── editortitlecontrol.css │ │ │ │ │ │ ├── multieditortabscontrol.css │ │ │ │ │ │ ├── sidebysideeditor.css │ │ │ │ │ │ └── singleeditortabscontrol.css │ │ │ │ │ ├── multiEditorTabsControl.ts │ │ │ │ │ ├── multiRowEditorTabsControl.ts │ │ │ │ │ ├── noEditorTabsControl.ts │ │ │ │ │ ├── sideBySideEditor.ts │ │ │ │ │ ├── singleEditorTabsControl.ts │ │ │ │ │ ├── textCodeEditor.ts │ │ │ │ │ ├── textDiffEditor.ts │ │ │ │ │ ├── textEditor.ts │ │ │ │ │ └── textResourceEditor.ts │ │ │ │ ├── globalCompositeBar.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── compositepart.css │ │ │ │ │ └── paneCompositePart.css │ │ │ │ ├── notifications/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── notificationsActions.css │ │ │ │ │ │ ├── notificationsCenter.css │ │ │ │ │ │ ├── notificationsList.css │ │ │ │ │ │ └── notificationsToasts.css │ │ │ │ │ ├── notificationAccessibleView.ts │ │ │ │ │ ├── notificationsActions.ts │ │ │ │ │ ├── notificationsAlerts.ts │ │ │ │ │ ├── notificationsCenter.ts │ │ │ │ │ ├── notificationsCommands.ts │ │ │ │ │ ├── notificationsList.ts │ │ │ │ │ ├── notificationsStatus.ts │ │ │ │ │ ├── notificationsToasts.ts │ │ │ │ │ └── notificationsViewer.ts │ │ │ │ ├── paneCompositeBar.ts │ │ │ │ ├── paneCompositePart.ts │ │ │ │ ├── paneCompositePartService.ts │ │ │ │ ├── panel/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── panelpart.css │ │ │ │ │ ├── panelActions.ts │ │ │ │ │ └── panelPart.ts │ │ │ │ ├── sidebar/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── sidebarpart.css │ │ │ │ │ ├── sidebarActions.ts │ │ │ │ │ └── sidebarPart.ts │ │ │ │ ├── statusbar/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── statusbarpart.css │ │ │ │ │ ├── statusbarActions.ts │ │ │ │ │ ├── statusbarItem.ts │ │ │ │ │ ├── statusbarModel.ts │ │ │ │ │ └── statusbarPart.ts │ │ │ │ ├── titlebar/ │ │ │ │ │ ├── commandCenterControl.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── menubarControl.css │ │ │ │ │ │ └── titlebarpart.css │ │ │ │ │ ├── menubarControl.ts │ │ │ │ │ ├── titlebarActions.ts │ │ │ │ │ ├── titlebarPart.ts │ │ │ │ │ └── windowTitle.ts │ │ │ │ └── views/ │ │ │ │ ├── checkbox.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── paneviewlet.css │ │ │ │ │ └── views.css │ │ │ │ ├── treeView.ts │ │ │ │ ├── viewFilter.ts │ │ │ │ ├── viewPane.ts │ │ │ │ ├── viewPaneContainer.ts │ │ │ │ └── viewsViewlet.ts │ │ │ ├── quickaccess.ts │ │ │ ├── style.ts │ │ │ ├── web.api.ts │ │ │ ├── web.factory.ts │ │ │ ├── web.main.ts │ │ │ ├── window.ts │ │ │ ├── workbench.contribution.ts │ │ │ └── workbench.ts │ │ ├── common/ │ │ │ ├── activity.ts │ │ │ ├── comments.ts │ │ │ ├── component.ts │ │ │ ├── composite.ts │ │ │ ├── configuration.ts │ │ │ ├── contextkeys.ts │ │ │ ├── contributions.ts │ │ │ ├── dialogs.ts │ │ │ ├── editor/ │ │ │ │ ├── binaryEditorModel.ts │ │ │ │ ├── diffEditorInput.ts │ │ │ │ ├── diffEditorModel.ts │ │ │ │ ├── editorGroupModel.ts │ │ │ │ ├── editorInput.ts │ │ │ │ ├── editorModel.ts │ │ │ │ ├── editorOptions.ts │ │ │ │ ├── filteredEditorGroupModel.ts │ │ │ │ ├── resourceEditorInput.ts │ │ │ │ ├── sideBySideEditorInput.ts │ │ │ │ ├── textDiffEditorModel.ts │ │ │ │ ├── textEditorModel.ts │ │ │ │ ├── textResourceEditorInput.ts │ │ │ │ └── textResourceEditorModel.ts │ │ │ ├── editor.ts │ │ │ ├── memento.ts │ │ │ ├── notifications.ts │ │ │ ├── panecomposite.ts │ │ │ ├── resources.ts │ │ │ ├── theme.ts │ │ │ └── views.ts │ │ ├── contrib/ │ │ │ ├── accessibility/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── accessibility.contribution.ts │ │ │ │ │ ├── accessibilityConfiguration.ts │ │ │ │ │ ├── accessibilityStatus.ts │ │ │ │ │ ├── accessibleView.ts │ │ │ │ │ ├── accessibleViewActions.ts │ │ │ │ │ ├── accessibleViewContributions.ts │ │ │ │ │ ├── accessibleViewKeybindingResolver.ts │ │ │ │ │ ├── editorAccessibilityHelp.ts │ │ │ │ │ ├── extensionAccesibilityHelp.contribution.ts │ │ │ │ │ └── unfocusedViewDimmingContribution.ts │ │ │ │ └── common/ │ │ │ │ └── accessibilityCommands.ts │ │ │ ├── accessibilitySignals/ │ │ │ │ └── browser/ │ │ │ │ ├── accessibilitySignal.contribution.ts │ │ │ │ ├── accessibilitySignalDebuggerContribution.ts │ │ │ │ ├── commands.ts │ │ │ │ ├── editorTextPropertySignalsContribution.ts │ │ │ │ ├── openDiffEditorAnnouncement.ts │ │ │ │ └── saveAccessibilitySignal.ts │ │ │ ├── authentication/ │ │ │ │ └── browser/ │ │ │ │ ├── actions/ │ │ │ │ │ ├── manageAccountPreferencesForExtensionAction.ts │ │ │ │ │ ├── manageTrustedExtensionsForAccountAction.ts │ │ │ │ │ └── signOutOfAccountAction.ts │ │ │ │ └── authentication.contribution.ts │ │ │ ├── bracketPairColorizer2Telemetry/ │ │ │ │ └── browser/ │ │ │ │ └── bracketPairColorizer2Telemetry.contribution.ts │ │ │ ├── bulkEdit/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── bulkCellEdits.ts │ │ │ │ │ ├── bulkEditService.ts │ │ │ │ │ ├── bulkFileEdits.ts │ │ │ │ │ ├── bulkTextEdits.ts │ │ │ │ │ ├── conflicts.ts │ │ │ │ │ ├── opaqueEdits.ts │ │ │ │ │ └── preview/ │ │ │ │ │ ├── bulkEdit.contribution.ts │ │ │ │ │ ├── bulkEdit.css │ │ │ │ │ ├── bulkEditPane.ts │ │ │ │ │ ├── bulkEditPreview.ts │ │ │ │ │ └── bulkEditTree.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── bulkCellEdits.test.ts │ │ │ │ └── bulkEditPreview.test.ts │ │ │ ├── callHierarchy/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── callHierarchy.contribution.ts │ │ │ │ │ ├── callHierarchyPeek.ts │ │ │ │ │ ├── callHierarchyTree.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── callHierarchy.css │ │ │ │ └── common/ │ │ │ │ └── callHierarchy.ts │ │ │ ├── chat/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── actions/ │ │ │ │ │ │ ├── chatAccessibilityHelp.ts │ │ │ │ │ │ ├── chatActions.ts │ │ │ │ │ │ ├── chatAttachPromptAction/ │ │ │ │ │ │ │ ├── chatAttachPromptAction.ts │ │ │ │ │ │ │ └── dialogs/ │ │ │ │ │ │ │ └── askToSelectPrompt/ │ │ │ │ │ │ │ ├── askToSelectPrompt.ts │ │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ │ ├── attachPrompts.ts │ │ │ │ │ │ │ ├── createPlaceholderText.ts │ │ │ │ │ │ │ ├── createPromptPickItem.ts │ │ │ │ │ │ │ └── handleButtonClick.ts │ │ │ │ │ │ ├── chatClear.ts │ │ │ │ │ │ ├── chatClearActions.ts │ │ │ │ │ │ ├── chatCodeblockActions.ts │ │ │ │ │ │ ├── chatContextActions.ts │ │ │ │ │ │ ├── chatCopyActions.ts │ │ │ │ │ │ ├── chatDeveloperActions.ts │ │ │ │ │ │ ├── chatExecuteActions.ts │ │ │ │ │ │ ├── chatFileTreeActions.ts │ │ │ │ │ │ ├── chatGettingStarted.ts │ │ │ │ │ │ ├── chatImportExport.ts │ │ │ │ │ │ ├── chatMoveActions.ts │ │ │ │ │ │ ├── chatQuickInputActions.ts │ │ │ │ │ │ ├── chatTitleActions.ts │ │ │ │ │ │ ├── chatToolActions.ts │ │ │ │ │ │ ├── chatTransfer.ts │ │ │ │ │ │ └── codeBlockOperations.ts │ │ │ │ │ ├── attachments/ │ │ │ │ │ │ ├── implicitContextAttachment.ts │ │ │ │ │ │ └── promptAttachments/ │ │ │ │ │ │ ├── promptAttachmentWidget.ts │ │ │ │ │ │ └── promptAttachmentsCollectionWidget.ts │ │ │ │ │ ├── chat.contribution.ts │ │ │ │ │ ├── chat.ts │ │ │ │ │ ├── chatAccessibilityProvider.ts │ │ │ │ │ ├── chatAccessibilityService.ts │ │ │ │ │ ├── chatAgentHover.ts │ │ │ │ │ ├── chatAttachmentModel/ │ │ │ │ │ │ ├── chatPromptAttachmentModel.ts │ │ │ │ │ │ └── chatPromptAttachmentsCollection.ts │ │ │ │ │ ├── chatAttachmentModel.ts │ │ │ │ │ ├── chatAttachmentWidgets.ts │ │ │ │ │ ├── chatContentParts/ │ │ │ │ │ │ ├── chatAgentCommandContentPart.ts │ │ │ │ │ │ ├── chatAttachmentsContentPart.ts │ │ │ │ │ │ ├── chatCodeCitationContentPart.ts │ │ │ │ │ │ ├── chatCollapsibleContentPart.ts │ │ │ │ │ │ ├── chatCollections.ts │ │ │ │ │ │ ├── chatCommandContentPart.ts │ │ │ │ │ │ ├── chatConfirmationContentPart.ts │ │ │ │ │ │ ├── chatConfirmationWidget.ts │ │ │ │ │ │ ├── chatContentParts.ts │ │ │ │ │ │ ├── chatMarkdownAnchorService.ts │ │ │ │ │ │ ├── chatMarkdownContentPart.ts │ │ │ │ │ │ ├── chatProgressContentPart.ts │ │ │ │ │ │ ├── chatQuotaExceededPart.ts │ │ │ │ │ │ ├── chatReferencesContentPart.ts │ │ │ │ │ │ ├── chatTaskContentPart.ts │ │ │ │ │ │ ├── chatTextEditContentPart.ts │ │ │ │ │ │ ├── chatToolInvocationPart.ts │ │ │ │ │ │ ├── chatTreeContentPart.ts │ │ │ │ │ │ ├── chatWarningContentPart.ts │ │ │ │ │ │ └── media/ │ │ │ │ │ │ └── chatConfirmationWidget.css │ │ │ │ │ ├── chatDragAndDrop.ts │ │ │ │ │ ├── chatEdinputInputContentProvider.ts │ │ │ │ │ ├── chatEditing/ │ │ │ │ │ │ ├── chatEditing.ts │ │ │ │ │ │ ├── chatEditingActions.ts │ │ │ │ │ │ ├── chatEditingCodeEditorIntegration.ts │ │ │ │ │ │ ├── chatEditingEditorAccessibility.ts │ │ │ │ │ │ ├── chatEditingEditorActions.ts │ │ │ │ │ │ ├── chatEditingEditorContextKeys.ts │ │ │ │ │ │ ├── chatEditingEditorOverlay.ts │ │ │ │ │ │ ├── chatEditingModifiedDocumentEntry.ts │ │ │ │ │ │ ├── chatEditingModifiedFileEntry.ts │ │ │ │ │ │ ├── chatEditingModifiedNotebookEntry.ts │ │ │ │ │ │ ├── chatEditingServiceImpl.ts │ │ │ │ │ │ ├── chatEditingSession.ts │ │ │ │ │ │ ├── chatEditingTextModelContentProviders.ts │ │ │ │ │ │ └── notebook/ │ │ │ │ │ │ ├── chatEditingModifiedNotebookDiff.ts │ │ │ │ │ │ ├── chatEditingModifiedNotebookSnapshot.ts │ │ │ │ │ │ ├── chatEditingNewNotebookContentEdits.ts │ │ │ │ │ │ ├── chatEditingNotebookCellEntry.ts │ │ │ │ │ │ ├── chatEditingNotebookEditorIntegration.ts │ │ │ │ │ │ ├── chatEditingNotebookFileSystemProvider.ts │ │ │ │ │ │ ├── helpers.ts │ │ │ │ │ │ └── notebookCellChanges.ts │ │ │ │ │ ├── chatEditor.ts │ │ │ │ │ ├── chatEditorInput.ts │ │ │ │ │ ├── chatFollowups.ts │ │ │ │ │ ├── chatInlineAnchorWidget.ts │ │ │ │ │ ├── chatInputPart.ts │ │ │ │ │ ├── chatListRenderer.ts │ │ │ │ │ ├── chatMarkdownDecorationsRenderer.ts │ │ │ │ │ ├── chatMarkdownRenderer.ts │ │ │ │ │ ├── chatOptions.ts │ │ │ │ │ ├── chatParticipant.contribution.ts │ │ │ │ │ ├── chatPasteProviders.ts │ │ │ │ │ ├── chatQuick.ts │ │ │ │ │ ├── chatResponseAccessibleView.ts │ │ │ │ │ ├── chatSelectedTools.ts │ │ │ │ │ ├── chatSetup.ts │ │ │ │ │ ├── chatStatus.ts │ │ │ │ │ ├── chatStatusItemService.ts │ │ │ │ │ ├── chatVariables.ts │ │ │ │ │ ├── chatViewPane.ts │ │ │ │ │ ├── chatWidget.ts │ │ │ │ │ ├── codeBlockContextProviderService.ts │ │ │ │ │ ├── codeBlockPart.css │ │ │ │ │ ├── codeBlockPart.ts │ │ │ │ │ ├── contrib/ │ │ │ │ │ │ ├── chatDynamicVariables/ │ │ │ │ │ │ │ └── chatFileReference.ts │ │ │ │ │ │ ├── chatDynamicVariables.ts │ │ │ │ │ │ ├── chatImplicitContext.ts │ │ │ │ │ │ ├── chatInputCompletions.ts │ │ │ │ │ │ ├── chatInputEditorContrib.ts │ │ │ │ │ │ ├── chatInputEditorHover.ts │ │ │ │ │ │ ├── chatInputRelatedFilesContrib.ts │ │ │ │ │ │ ├── editorHoverWrapper.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── editorHoverWrapper.css │ │ │ │ │ │ └── screenshot.ts │ │ │ │ │ ├── imageUtils.ts │ │ │ │ │ ├── languageModelToolsService.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── chat.css │ │ │ │ │ │ ├── chatAgentHover.css │ │ │ │ │ │ ├── chatCodeBlockPill.css │ │ │ │ │ │ ├── chatEditingEditorOverlay.css │ │ │ │ │ │ ├── chatEditorController.css │ │ │ │ │ │ ├── chatEditorOverlay.css │ │ │ │ │ │ ├── chatInlineAnchorWidget.css │ │ │ │ │ │ ├── chatSetup.css │ │ │ │ │ │ ├── chatStatus.css │ │ │ │ │ │ ├── chatViewSetup.css │ │ │ │ │ │ └── chatViewWelcome.css │ │ │ │ │ ├── promptSyntax/ │ │ │ │ │ │ └── contributions/ │ │ │ │ │ │ ├── createPromptCommand/ │ │ │ │ │ │ │ ├── createPromptCommand.ts │ │ │ │ │ │ │ ├── dialogs/ │ │ │ │ │ │ │ │ ├── askForPromptName.ts │ │ │ │ │ │ │ │ └── askForPromptSourceFolder.ts │ │ │ │ │ │ │ ├── errors.ts │ │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ │ └── createPromptFile.ts │ │ │ │ │ │ └── usePromptCommand.ts │ │ │ │ │ └── viewsWelcome/ │ │ │ │ │ ├── chatViewWelcomeController.ts │ │ │ │ │ ├── chatViewsWelcome.ts │ │ │ │ │ └── chatViewsWelcomeHandler.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── annotations.ts │ │ │ │ │ ├── chat.ts │ │ │ │ │ ├── chatActions.ts │ │ │ │ │ ├── chatAgents.ts │ │ │ │ │ ├── chatCodeMapperService.ts │ │ │ │ │ ├── chatColors.ts │ │ │ │ │ ├── chatContextKeys.ts │ │ │ │ │ ├── chatEditingService.ts │ │ │ │ │ ├── chatEntitlementService.ts │ │ │ │ │ ├── chatModel.ts │ │ │ │ │ ├── chatParserTypes.ts │ │ │ │ │ ├── chatParticipantContribTypes.ts │ │ │ │ │ ├── chatProgressTypes/ │ │ │ │ │ │ └── chatToolInvocation.ts │ │ │ │ │ ├── chatRequestParser.ts │ │ │ │ │ ├── chatService.ts │ │ │ │ │ ├── chatServiceImpl.ts │ │ │ │ │ ├── chatServiceTelemetry.ts │ │ │ │ │ ├── chatSessionStore.ts │ │ │ │ │ ├── chatSlashCommands.ts │ │ │ │ │ ├── chatTransferService.ts │ │ │ │ │ ├── chatVariables.ts │ │ │ │ │ ├── chatViewModel.ts │ │ │ │ │ ├── chatWidgetHistoryService.ts │ │ │ │ │ ├── chatWordCounter.ts │ │ │ │ │ ├── codeBlockModelCollection.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── ignoredFiles.ts │ │ │ │ │ ├── languageModelStats.ts │ │ │ │ │ ├── languageModelToolsService.ts │ │ │ │ │ ├── languageModels.ts │ │ │ │ │ ├── promptFileReferenceErrors.ts │ │ │ │ │ ├── promptSyntax/ │ │ │ │ │ │ ├── codecs/ │ │ │ │ │ │ │ ├── chatPromptCodec.ts │ │ │ │ │ │ │ ├── chatPromptDecoder.ts │ │ │ │ │ │ │ ├── parsers/ │ │ │ │ │ │ │ │ └── promptVariableParser.ts │ │ │ │ │ │ │ └── tokens/ │ │ │ │ │ │ │ ├── fileReference.ts │ │ │ │ │ │ │ ├── promptToken.ts │ │ │ │ │ │ │ └── promptVariable.ts │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ ├── contentProviders/ │ │ │ │ │ │ │ ├── filePromptContentsProvider.ts │ │ │ │ │ │ │ ├── promptContentsProviderBase.ts │ │ │ │ │ │ │ ├── textModelContentsProvider.ts │ │ │ │ │ │ │ └── types.d.ts │ │ │ │ │ │ ├── languageFeatures/ │ │ │ │ │ │ │ ├── promptLinkDiagnosticsProvider.ts │ │ │ │ │ │ │ ├── promptLinkProvider.ts │ │ │ │ │ │ │ ├── promptPathAutocompletion.ts │ │ │ │ │ │ │ └── types.d.ts │ │ │ │ │ │ ├── parsers/ │ │ │ │ │ │ │ ├── basePromptParser.ts │ │ │ │ │ │ │ ├── filePromptParser.ts │ │ │ │ │ │ │ ├── textModelPromptParser.ts │ │ │ │ │ │ │ ├── topError.ts │ │ │ │ │ │ │ └── types.d.ts │ │ │ │ │ │ ├── service/ │ │ │ │ │ │ │ ├── promptsService.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ └── promptFilesLocator.ts │ │ │ │ │ ├── tools/ │ │ │ │ │ │ ├── editFileTool.ts │ │ │ │ │ │ ├── insertNotebookCellsTool.ts │ │ │ │ │ │ ├── languageModelToolsContribution.ts │ │ │ │ │ │ ├── languageModelToolsParametersSchema.ts │ │ │ │ │ │ ├── promptTsxTypes.ts │ │ │ │ │ │ └── tools.ts │ │ │ │ │ └── voiceChatService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── actions/ │ │ │ │ │ │ ├── chatDeveloperActions.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── voiceChatActions.css │ │ │ │ │ │ └── voiceChatActions.ts │ │ │ │ │ ├── chat.contribution.ts │ │ │ │ │ └── tools/ │ │ │ │ │ └── fetchPageTool.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ ├── ChatMarkdownRenderer_CDATA.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_html_comments.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_invalid_HTML.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_invalid_HTML_with_attributes.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_mixed_valid_and_invalid_HTML.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_remote_images.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_self-closing_elements.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_simple.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_supportHtml_with_one-line_markdown.0.snap │ │ │ │ │ │ ├── ChatMarkdownRenderer_supportHtml_with_one-line_markdown.1.snap │ │ │ │ │ │ └── ChatMarkdownRenderer_valid_HTML.0.snap │ │ │ │ │ ├── chatEditingModifiedNotebookEntry.test.ts │ │ │ │ │ ├── chatEditingService.test.ts │ │ │ │ │ ├── chatMarkdownRenderer.test.ts │ │ │ │ │ ├── languageModelToolsService.test.ts │ │ │ │ │ └── mockChatWidget.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_multiline.0.snap │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_multiline.1.snap │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_multiple_vulns.0.snap │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_multiple_vulns.1.snap │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_single_line.0.snap │ │ │ │ │ │ ├── Annotations_extractVulnerabilitiesFromText_single_line.1.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_and_subcommand_after_newline.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_and_subcommand_with_leading_whitespace.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_but_edit_mode.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_not_first.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_with_question_mark.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agent_with_subcommand_after_text.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agents__subCommand.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agents_and_tools_and_multiline.0.snap │ │ │ │ │ │ ├── ChatRequestParser_agents_and_tools_and_multiline__part2.0.snap │ │ │ │ │ │ ├── ChatRequestParser_invalid_slash_command.0.snap │ │ │ │ │ │ ├── ChatRequestParser_multiple_slash_commands.0.snap │ │ │ │ │ │ ├── ChatRequestParser_plain_text.0.snap │ │ │ │ │ │ ├── ChatRequestParser_plain_text_with_newlines.0.snap │ │ │ │ │ │ ├── ChatRequestParser_slash_command.0.snap │ │ │ │ │ │ ├── ChatService_can_deserialize.0.snap │ │ │ │ │ │ ├── ChatService_can_deserialize_with_response.0.snap │ │ │ │ │ │ ├── ChatService_can_serialize.0.snap │ │ │ │ │ │ ├── ChatService_can_serialize.1.snap │ │ │ │ │ │ ├── ChatService_sendRequest_fails.0.snap │ │ │ │ │ │ ├── Response_async_content.0.snap │ │ │ │ │ │ ├── Response_async_content.1.snap │ │ │ │ │ │ ├── Response_content__markdown.0.snap │ │ │ │ │ │ ├── Response_inline_reference.0.snap │ │ │ │ │ │ ├── Response_markdown__content.0.snap │ │ │ │ │ │ ├── Response_markdown__markdown.0.snap │ │ │ │ │ │ ├── Response_mergeable_markdown.0.snap │ │ │ │ │ │ └── Response_not_mergeable_markdown.0.snap │ │ │ │ │ ├── annotations.test.ts │ │ │ │ │ ├── chatAgents.test.ts │ │ │ │ │ ├── chatModel.test.ts │ │ │ │ │ ├── chatRequestParser.test.ts │ │ │ │ │ ├── chatService.test.ts │ │ │ │ │ ├── chatWordCounter.test.ts │ │ │ │ │ ├── languageModels.test.ts │ │ │ │ │ ├── mockChatService.ts │ │ │ │ │ ├── mockChatVariables.ts │ │ │ │ │ ├── mockLanguageModelToolsService.ts │ │ │ │ │ ├── promptSyntax/ │ │ │ │ │ │ ├── codecs/ │ │ │ │ │ │ │ ├── chatPromptCodec.test.ts │ │ │ │ │ │ │ ├── chatPromptDecoder.test.ts │ │ │ │ │ │ │ └── tokens/ │ │ │ │ │ │ │ ├── fileReference.test.ts │ │ │ │ │ │ │ └── markdownLink.test.ts │ │ │ │ │ │ ├── contentProviders/ │ │ │ │ │ │ │ └── filePromptContentsProvider.test.ts │ │ │ │ │ │ ├── parsers/ │ │ │ │ │ │ │ └── textModelPromptParser.test.ts │ │ │ │ │ │ ├── promptFileReference.test.ts │ │ │ │ │ │ ├── service/ │ │ │ │ │ │ │ └── promptsService.test.ts │ │ │ │ │ │ ├── testUtils/ │ │ │ │ │ │ │ ├── createUri.ts │ │ │ │ │ │ │ ├── expectedReference.ts │ │ │ │ │ │ │ ├── mockFilesystem.test.ts │ │ │ │ │ │ │ └── mockFilesystem.ts │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ └── promptFilesLocator.test.ts │ │ │ │ │ └── voiceChatService.test.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── voiceChatActions.test.ts │ │ │ ├── codeActions/ │ │ │ │ └── browser/ │ │ │ │ ├── codeActions.contribution.ts │ │ │ │ └── codeActionsContribution.ts │ │ │ ├── codeEditor/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── accessibility/ │ │ │ │ │ │ ├── accessibility.css │ │ │ │ │ │ └── accessibility.ts │ │ │ │ │ ├── codeEditor.contribution.ts │ │ │ │ │ ├── dictation/ │ │ │ │ │ │ ├── editorDictation.css │ │ │ │ │ │ └── editorDictation.ts │ │ │ │ │ ├── diffEditorAccessibilityHelp.ts │ │ │ │ │ ├── diffEditorHelper.ts │ │ │ │ │ ├── editorFeatures.ts │ │ │ │ │ ├── editorLineNumberMenu.ts │ │ │ │ │ ├── editorSettingsMigration.ts │ │ │ │ │ ├── emptyTextEditorHint/ │ │ │ │ │ │ ├── emptyTextEditorHint.css │ │ │ │ │ │ └── emptyTextEditorHint.ts │ │ │ │ │ ├── find/ │ │ │ │ │ │ ├── simpleFindWidget.css │ │ │ │ │ │ └── simpleFindWidget.ts │ │ │ │ │ ├── inspectEditorTokens/ │ │ │ │ │ │ ├── inspectEditorTokens.css │ │ │ │ │ │ └── inspectEditorTokens.ts │ │ │ │ │ ├── inspectKeybindings.ts │ │ │ │ │ ├── largeFileOptimizations.ts │ │ │ │ │ ├── menuPreventer.ts │ │ │ │ │ ├── outline/ │ │ │ │ │ │ ├── documentSymbolsOutline.ts │ │ │ │ │ │ ├── documentSymbolsTree.css │ │ │ │ │ │ └── documentSymbolsTree.ts │ │ │ │ │ ├── quickaccess/ │ │ │ │ │ │ ├── gotoLineQuickAccess.ts │ │ │ │ │ │ └── gotoSymbolQuickAccess.ts │ │ │ │ │ ├── saveParticipants.ts │ │ │ │ │ ├── selectionClipboard.ts │ │ │ │ │ ├── simpleEditorOptions.ts │ │ │ │ │ ├── suggestEnabledInput/ │ │ │ │ │ │ ├── suggestEnabledInput.css │ │ │ │ │ │ └── suggestEnabledInput.ts │ │ │ │ │ ├── toggleColumnSelection.ts │ │ │ │ │ ├── toggleMinimap.ts │ │ │ │ │ ├── toggleMultiCursorModifier.ts │ │ │ │ │ ├── toggleOvertype.ts │ │ │ │ │ ├── toggleRenderControlCharacter.ts │ │ │ │ │ ├── toggleRenderWhitespace.ts │ │ │ │ │ ├── toggleWordWrap.ts │ │ │ │ │ ├── workbenchEditorWorkerService.ts │ │ │ │ │ └── workbenchReferenceSearch.ts │ │ │ │ ├── common/ │ │ │ │ │ └── languageConfigurationExtensionPoint.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── codeEditor.contribution.ts │ │ │ │ │ ├── displayChangeRemeasureFonts.ts │ │ │ │ │ ├── inputClipboardActions.ts │ │ │ │ │ ├── selectionClipboard.ts │ │ │ │ │ ├── sleepResumeRepaintMinimap.ts │ │ │ │ │ └── startDebugTextMate.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── saveParticipant.test.ts │ │ │ │ └── node/ │ │ │ │ ├── autoindent.test.ts │ │ │ │ └── language-configuration.json │ │ │ ├── commands/ │ │ │ │ └── common/ │ │ │ │ └── commands.contribution.ts │ │ │ ├── comments/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── commentColors.ts │ │ │ │ │ ├── commentFormActions.ts │ │ │ │ │ ├── commentGlyphWidget.ts │ │ │ │ │ ├── commentMenus.ts │ │ │ │ │ ├── commentNode.ts │ │ │ │ │ ├── commentReply.ts │ │ │ │ │ ├── commentService.ts │ │ │ │ │ ├── commentThreadAdditionalActions.ts │ │ │ │ │ ├── commentThreadBody.ts │ │ │ │ │ ├── commentThreadHeader.ts │ │ │ │ │ ├── commentThreadRangeDecorator.ts │ │ │ │ │ ├── commentThreadWidget.ts │ │ │ │ │ ├── commentThreadZoneWidget.ts │ │ │ │ │ ├── comments.contribution.ts │ │ │ │ │ ├── comments.ts │ │ │ │ │ ├── commentsAccessibility.ts │ │ │ │ │ ├── commentsAccessibleView.ts │ │ │ │ │ ├── commentsController.ts │ │ │ │ │ ├── commentsEditorContribution.ts │ │ │ │ │ ├── commentsFilterOptions.ts │ │ │ │ │ ├── commentsInputContentProvider.ts │ │ │ │ │ ├── commentsModel.ts │ │ │ │ │ ├── commentsTreeViewer.ts │ │ │ │ │ ├── commentsView.ts │ │ │ │ │ ├── commentsViewActions.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── panel.css │ │ │ │ │ │ └── review.css │ │ │ │ │ ├── reactionsAction.ts │ │ │ │ │ ├── simpleCommentEditor.ts │ │ │ │ │ └── timestamp.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── commentCommandIds.ts │ │ │ │ │ ├── commentContextKeys.ts │ │ │ │ │ ├── commentModel.ts │ │ │ │ │ ├── commentThreadWidget.ts │ │ │ │ │ └── commentsConfiguration.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── commentsView.test.ts │ │ │ ├── contextmenu/ │ │ │ │ └── browser/ │ │ │ │ └── contextmenu.contribution.ts │ │ │ ├── customEditor/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── customEditor.contribution.ts │ │ │ │ │ ├── customEditorInput.ts │ │ │ │ │ ├── customEditorInputFactory.ts │ │ │ │ │ ├── customEditors.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── customEditor.css │ │ │ │ └── common/ │ │ │ │ ├── contributedCustomEditors.ts │ │ │ │ ├── customEditor.ts │ │ │ │ ├── customEditorModelManager.ts │ │ │ │ ├── customTextEditorModel.ts │ │ │ │ └── extensionPoint.ts │ │ │ ├── debug/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── baseDebugView.ts │ │ │ │ │ ├── breakpointEditorContribution.ts │ │ │ │ │ ├── breakpointWidget.ts │ │ │ │ │ ├── breakpointsView.ts │ │ │ │ │ ├── callStackEditorContribution.ts │ │ │ │ │ ├── callStackView.ts │ │ │ │ │ ├── callStackWidget.ts │ │ │ │ │ ├── debug.contribution.ts │ │ │ │ │ ├── debugANSIHandling.ts │ │ │ │ │ ├── debugActionViewItems.ts │ │ │ │ │ ├── debugAdapterManager.ts │ │ │ │ │ ├── debugColors.ts │ │ │ │ │ ├── debugCommands.ts │ │ │ │ │ ├── debugConfigurationManager.ts │ │ │ │ │ ├── debugConsoleQuickAccess.ts │ │ │ │ │ ├── debugEditorActions.ts │ │ │ │ │ ├── debugEditorContribution.ts │ │ │ │ │ ├── debugExpressionRenderer.ts │ │ │ │ │ ├── debugHover.ts │ │ │ │ │ ├── debugIcons.ts │ │ │ │ │ ├── debugMemory.ts │ │ │ │ │ ├── debugProgress.ts │ │ │ │ │ ├── debugQuickAccess.ts │ │ │ │ │ ├── debugService.ts │ │ │ │ │ ├── debugSession.ts │ │ │ │ │ ├── debugSessionPicker.ts │ │ │ │ │ ├── debugSettingMigration.ts │ │ │ │ │ ├── debugStatus.ts │ │ │ │ │ ├── debugTaskRunner.ts │ │ │ │ │ ├── debugTitle.ts │ │ │ │ │ ├── debugToolBar.ts │ │ │ │ │ ├── debugViewlet.ts │ │ │ │ │ ├── disassemblyView.ts │ │ │ │ │ ├── exceptionWidget.ts │ │ │ │ │ ├── extensionHostDebugService.ts │ │ │ │ │ ├── linkDetector.ts │ │ │ │ │ ├── loadedScriptsView.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── breakpointWidget.css │ │ │ │ │ │ ├── callStackEditorContribution.css │ │ │ │ │ │ ├── callStackWidget.css │ │ │ │ │ │ ├── debug.contribution.css │ │ │ │ │ │ ├── debugHover.css │ │ │ │ │ │ ├── debugToolBar.css │ │ │ │ │ │ ├── debugViewlet.css │ │ │ │ │ │ ├── exceptionWidget.css │ │ │ │ │ │ └── repl.css │ │ │ │ │ ├── rawDebugSession.ts │ │ │ │ │ ├── repl.ts │ │ │ │ │ ├── replAccessibilityHelp.ts │ │ │ │ │ ├── replAccessibleView.ts │ │ │ │ │ ├── replFilter.ts │ │ │ │ │ ├── replViewer.ts │ │ │ │ │ ├── runAndDebugAccessibilityHelp.ts │ │ │ │ │ ├── statusbarColorProvider.ts │ │ │ │ │ ├── variablesView.ts │ │ │ │ │ ├── watchExpressionsView.ts │ │ │ │ │ └── welcomeView.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractDebugAdapter.ts │ │ │ │ │ ├── breakpoints.ts │ │ │ │ │ ├── debug.ts │ │ │ │ │ ├── debugAccessibilityAnnouncer.ts │ │ │ │ │ ├── debugCompoundRoot.ts │ │ │ │ │ ├── debugContentProvider.ts │ │ │ │ │ ├── debugContext.ts │ │ │ │ │ ├── debugLifecycle.ts │ │ │ │ │ ├── debugModel.ts │ │ │ │ │ ├── debugProtocol.d.ts │ │ │ │ │ ├── debugSchemas.ts │ │ │ │ │ ├── debugSource.ts │ │ │ │ │ ├── debugStorage.ts │ │ │ │ │ ├── debugTelemetry.ts │ │ │ │ │ ├── debugUtils.ts │ │ │ │ │ ├── debugViewModel.ts │ │ │ │ │ ├── debugVisualizers.ts │ │ │ │ │ ├── debugger.ts │ │ │ │ │ ├── disassemblyViewInput.ts │ │ │ │ │ ├── loadedScriptsPicker.ts │ │ │ │ │ ├── replAccessibilityAnnouncer.ts │ │ │ │ │ └── replModel.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── extensionHostDebugService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── debugAdapter.ts │ │ │ │ │ ├── telemetryApp.ts │ │ │ │ │ └── terminals.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── baseDebugView.test.ts │ │ │ │ │ ├── breakpoints.test.ts │ │ │ │ │ ├── callStack.test.ts │ │ │ │ │ ├── debugANSIHandling.test.ts │ │ │ │ │ ├── debugConfigurationManager.test.ts │ │ │ │ │ ├── debugHover.test.ts │ │ │ │ │ ├── debugMemory.test.ts │ │ │ │ │ ├── debugSession.test.ts │ │ │ │ │ ├── debugSource.test.ts │ │ │ │ │ ├── debugUtils.test.ts │ │ │ │ │ ├── debugViewModel.test.ts │ │ │ │ │ ├── linkDetector.test.ts │ │ │ │ │ ├── mockDebugModel.ts │ │ │ │ │ ├── rawDebugSession.test.ts │ │ │ │ │ ├── repl.test.ts │ │ │ │ │ ├── variablesView.test.ts │ │ │ │ │ ├── watch.test.ts │ │ │ │ │ └── watchExpressionView.test.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractDebugAdapter.test.ts │ │ │ │ │ ├── debugModel.test.ts │ │ │ │ │ └── mockDebug.ts │ │ │ │ └── node/ │ │ │ │ ├── debugger.test.ts │ │ │ │ ├── streamDebugAdapter.test.ts │ │ │ │ └── terminals.test.ts │ │ │ ├── deprecatedExtensionMigrator/ │ │ │ │ └── browser/ │ │ │ │ └── deprecatedExtensionMigrator.contribution.ts │ │ │ ├── dropOrPasteInto/ │ │ │ │ └── browser/ │ │ │ │ ├── commands.ts │ │ │ │ ├── configurationSchema.ts │ │ │ │ └── dropOrPasteInto.contribution.ts │ │ │ ├── editSessions/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── editSessions.contribution.ts │ │ │ │ │ ├── editSessionsFileSystemProvider.ts │ │ │ │ │ ├── editSessionsStorageService.ts │ │ │ │ │ └── editSessionsViews.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── editSessions.ts │ │ │ │ │ ├── editSessionsLogService.ts │ │ │ │ │ ├── editSessionsStorageClient.ts │ │ │ │ │ └── workspaceStateSync.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── editSessions.test.ts │ │ │ ├── emergencyAlert/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── emergencyAlert.contribution.ts │ │ │ ├── emmet/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── actions/ │ │ │ │ │ │ └── expandAbbreviation.ts │ │ │ │ │ ├── emmet.contribution.ts │ │ │ │ │ └── emmetActions.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── emmetAction.test.ts │ │ │ ├── encryption/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── encryption.contribution.ts │ │ │ ├── extensions/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── abstractRuntimeExtensionsEditor.ts │ │ │ │ │ ├── browserRuntimeExtensionsEditor.ts │ │ │ │ │ ├── configBasedRecommendations.ts │ │ │ │ │ ├── exeBasedRecommendations.ts │ │ │ │ │ ├── extensionEditor.ts │ │ │ │ │ ├── extensionEnablementWorkspaceTrustTransitionParticipant.ts │ │ │ │ │ ├── extensionFeaturesTab.ts │ │ │ │ │ ├── extensionRecommendationNotificationService.ts │ │ │ │ │ ├── extensionRecommendations.ts │ │ │ │ │ ├── extensionRecommendationsService.ts │ │ │ │ │ ├── extensions.contribution.ts │ │ │ │ │ ├── extensions.web.contribution.ts │ │ │ │ │ ├── extensionsActions.ts │ │ │ │ │ ├── extensionsActivationProgress.ts │ │ │ │ │ ├── extensionsCompletionItemsProvider.ts │ │ │ │ │ ├── extensionsDependencyChecker.ts │ │ │ │ │ ├── extensionsIcons.ts │ │ │ │ │ ├── extensionsList.ts │ │ │ │ │ ├── extensionsQuickAccess.ts │ │ │ │ │ ├── extensionsViewer.ts │ │ │ │ │ ├── extensionsViewlet.ts │ │ │ │ │ ├── extensionsViews.ts │ │ │ │ │ ├── extensionsWidgets.ts │ │ │ │ │ ├── extensionsWorkbenchService.ts │ │ │ │ │ ├── fileBasedRecommendations.ts │ │ │ │ │ ├── keymapRecommendations.ts │ │ │ │ │ ├── languageRecommendations.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── extension.css │ │ │ │ │ │ ├── extensionActions.css │ │ │ │ │ │ ├── extensionEditor.css │ │ │ │ │ │ ├── extensionsViewlet.css │ │ │ │ │ │ ├── extensionsWidgets.css │ │ │ │ │ │ └── runtimeExtensionsEditor.css │ │ │ │ │ ├── remoteRecommendations.ts │ │ │ │ │ ├── unsupportedExtensionsMigrationContribution.ts │ │ │ │ │ ├── webRecommendations.ts │ │ │ │ │ └── workspaceRecommendations.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── extensionQuery.ts │ │ │ │ │ ├── extensions.ts │ │ │ │ │ ├── extensionsFileTemplate.ts │ │ │ │ │ ├── extensionsInput.ts │ │ │ │ │ ├── extensionsUtils.ts │ │ │ │ │ ├── reportExtensionIssueAction.ts │ │ │ │ │ └── runtimeExtensionsInput.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── debugExtensionHostAction.ts │ │ │ │ │ ├── extensionProfileService.ts │ │ │ │ │ ├── extensions.contribution.ts │ │ │ │ │ ├── extensionsActions.ts │ │ │ │ │ ├── extensionsAutoProfiler.ts │ │ │ │ │ ├── extensionsSlowActions.ts │ │ │ │ │ ├── remoteExtensionsInit.ts │ │ │ │ │ └── runtimeExtensionsEditor.ts │ │ │ │ └── test/ │ │ │ │ ├── common/ │ │ │ │ │ └── extensionQuery.test.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── extension.test.ts │ │ │ │ ├── extensionRecommendationsService.test.ts │ │ │ │ ├── extensionsActions.test.ts │ │ │ │ ├── extensionsViews.test.ts │ │ │ │ └── extensionsWorkbenchService.test.ts │ │ │ ├── externalTerminal/ │ │ │ │ ├── browser/ │ │ │ │ │ └── externalTerminal.contribution.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── externalTerminal.contribution.ts │ │ │ │ └── node/ │ │ │ │ ├── TerminalHelper.scpt │ │ │ │ └── iTermHelper.scpt │ │ │ ├── externalUriOpener/ │ │ │ │ ├── common/ │ │ │ │ │ ├── configuration.ts │ │ │ │ │ ├── contributedOpeners.ts │ │ │ │ │ ├── externalUriOpener.contribution.ts │ │ │ │ │ └── externalUriOpenerService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── externalUriOpenerService.test.ts │ │ │ ├── files/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── editors/ │ │ │ │ │ │ ├── binaryFileEditor.ts │ │ │ │ │ │ ├── fileEditorHandler.ts │ │ │ │ │ │ ├── fileEditorInput.ts │ │ │ │ │ │ ├── textFileEditor.ts │ │ │ │ │ │ ├── textFileEditorTracker.ts │ │ │ │ │ │ └── textFileSaveErrorHandler.ts │ │ │ │ │ ├── explorerFileContrib.ts │ │ │ │ │ ├── explorerService.ts │ │ │ │ │ ├── explorerViewlet.ts │ │ │ │ │ ├── fileActions.contribution.ts │ │ │ │ │ ├── fileActions.ts │ │ │ │ │ ├── fileCommands.ts │ │ │ │ │ ├── fileConstants.ts │ │ │ │ │ ├── fileImportExport.ts │ │ │ │ │ ├── files.contribution.ts │ │ │ │ │ ├── files.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── explorerviewlet.css │ │ │ │ │ ├── views/ │ │ │ │ │ │ ├── emptyView.ts │ │ │ │ │ │ ├── explorerDecorationsProvider.ts │ │ │ │ │ │ ├── explorerView.ts │ │ │ │ │ │ ├── explorerViewer.ts │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── openeditors.css │ │ │ │ │ │ └── openEditorsView.ts │ │ │ │ │ └── workspaceWatcher.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── dirtyFilesIndicator.ts │ │ │ │ │ ├── explorerFileNestingTrie.ts │ │ │ │ │ ├── explorerModel.ts │ │ │ │ │ └── files.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── fileActions.contribution.ts │ │ │ │ │ └── fileCommands.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── editorAutoSave.test.ts │ │ │ │ ├── explorerFileNestingTrie.test.ts │ │ │ │ ├── explorerFindProvider.test.ts │ │ │ │ ├── explorerModel.test.ts │ │ │ │ ├── explorerView.test.ts │ │ │ │ ├── fileActions.test.ts │ │ │ │ ├── fileEditorInput.test.ts │ │ │ │ ├── fileOnDiskProvider.test.ts │ │ │ │ └── textFileEditorTracker.test.ts │ │ │ ├── folding/ │ │ │ │ └── browser/ │ │ │ │ └── folding.contribution.ts │ │ │ ├── format/ │ │ │ │ └── browser/ │ │ │ │ ├── format.contribution.ts │ │ │ │ ├── formatActionsMultiple.ts │ │ │ │ ├── formatActionsNone.ts │ │ │ │ └── formatModified.ts │ │ │ ├── inlayHints/ │ │ │ │ └── browser/ │ │ │ │ └── inlayHintsAccessibilty.ts │ │ │ ├── inlineChat/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── inlineChat.contribution.ts │ │ │ │ │ ├── inlineChatAccessibilityHelp.ts │ │ │ │ │ ├── inlineChatAccessibleView.ts │ │ │ │ │ ├── inlineChatActions.ts │ │ │ │ │ ├── inlineChatController.ts │ │ │ │ │ ├── inlineChatCurrentLine.ts │ │ │ │ │ ├── inlineChatNotebook.ts │ │ │ │ │ ├── inlineChatSession.ts │ │ │ │ │ ├── inlineChatSessionService.ts │ │ │ │ │ ├── inlineChatSessionServiceImpl.ts │ │ │ │ │ ├── inlineChatStrategies.ts │ │ │ │ │ ├── inlineChatWidget.ts │ │ │ │ │ ├── inlineChatZoneWidget.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── inlineChat.css │ │ │ │ │ └── utils.ts │ │ │ │ ├── common/ │ │ │ │ │ └── inlineChat.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── inlineChat.contribution.ts │ │ │ │ │ └── inlineChatActions.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ ├── InlineChatSession_Apply_Code_s_preview_should_be_easier_to_undo_esc__7537.1.snap │ │ │ │ │ └── InlineChatSession_Apply_Code_s_preview_should_be_easier_to_undo_esc__7537.2.snap │ │ │ │ ├── inlineChatController.test.ts │ │ │ │ ├── inlineChatSession.test.ts │ │ │ │ ├── inlineChatStrategies.test.ts │ │ │ │ └── testWorkerService.ts │ │ │ ├── inlineCompletions/ │ │ │ │ └── browser/ │ │ │ │ ├── inlineCompletionLanguageStatusBarContribution.ts │ │ │ │ └── inlineCompletions.contribution.ts │ │ │ ├── interactive/ │ │ │ │ └── browser/ │ │ │ │ ├── interactive.contribution.ts │ │ │ │ ├── interactiveCommon.ts │ │ │ │ ├── interactiveDocumentService.ts │ │ │ │ ├── interactiveEditor.css │ │ │ │ ├── interactiveEditor.ts │ │ │ │ ├── interactiveEditorInput.ts │ │ │ │ ├── interactiveHistoryService.ts │ │ │ │ ├── media/ │ │ │ │ │ └── interactive.css │ │ │ │ └── replInputHintContentWidget.ts │ │ │ ├── issue/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── baseIssueReporterService.ts │ │ │ │ │ ├── issue.contribution.ts │ │ │ │ │ ├── issueFormService.ts │ │ │ │ │ ├── issueQuickAccess.ts │ │ │ │ │ ├── issueReporterModel.ts │ │ │ │ │ ├── issueReporterPage.ts │ │ │ │ │ ├── issueReporterService.ts │ │ │ │ │ ├── issueService.ts │ │ │ │ │ ├── issueTroubleshoot.ts │ │ │ │ │ └── media/ │ │ │ │ │ └── issueReporter.css │ │ │ │ ├── common/ │ │ │ │ │ ├── issue.contribution.ts │ │ │ │ │ ├── issue.ts │ │ │ │ │ └── issueReporterUtil.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── issue.contribution.ts │ │ │ │ │ ├── issueReporterService.ts │ │ │ │ │ ├── issueService.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── issueReporter.css │ │ │ │ │ ├── nativeIssueFormService.ts │ │ │ │ │ ├── process.contribution.ts │ │ │ │ │ ├── processMainService.ts │ │ │ │ │ └── processService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── testReporterModel.test.ts │ │ │ ├── keybindings/ │ │ │ │ └── browser/ │ │ │ │ └── keybindings.contribution.ts │ │ │ ├── languageDetection/ │ │ │ │ └── browser/ │ │ │ │ └── languageDetection.contribution.ts │ │ │ ├── languageStatus/ │ │ │ │ └── browser/ │ │ │ │ ├── languageStatus.contribution.ts │ │ │ │ ├── languageStatus.ts │ │ │ │ └── media/ │ │ │ │ └── languageStatus.css │ │ │ ├── limitIndicator/ │ │ │ │ └── browser/ │ │ │ │ └── limitIndicator.contribution.ts │ │ │ ├── list/ │ │ │ │ └── browser/ │ │ │ │ ├── list.contribution.ts │ │ │ │ ├── listResizeColumnAction.ts │ │ │ │ └── tableColumnResizeQuickPick.ts │ │ │ ├── localHistory/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── localHistory.contribution.ts │ │ │ │ │ ├── localHistory.ts │ │ │ │ │ ├── localHistoryCommands.ts │ │ │ │ │ ├── localHistoryFileSystemProvider.ts │ │ │ │ │ └── localHistoryTimeline.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── localHistory.contribution.ts │ │ │ │ └── localHistoryCommands.ts │ │ │ ├── localization/ │ │ │ │ ├── browser/ │ │ │ │ │ └── localization.contribution.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── localization.contribution.ts │ │ │ │ │ └── localizationsActions.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── localization.contribution.ts │ │ │ │ └── minimalTranslations.ts │ │ │ ├── logs/ │ │ │ │ ├── browser/ │ │ │ │ │ └── logs.contribution.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── defaultLogLevels.ts │ │ │ │ │ ├── logs.contribution.ts │ │ │ │ │ ├── logsActions.ts │ │ │ │ │ └── logsDataCleaner.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── logs.contribution.ts │ │ │ │ └── logsActions.ts │ │ │ ├── markdown/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── markdownDocumentRenderer.ts │ │ │ │ │ ├── markdownSettingRenderer.ts │ │ │ │ │ └── markedGfmHeadingIdPlugin.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── markdownSettingRenderer.test.ts │ │ │ ├── markers/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── markers.contribution.ts │ │ │ │ │ ├── markers.ts │ │ │ │ │ ├── markersFileDecorations.ts │ │ │ │ │ ├── markersFilterOptions.ts │ │ │ │ │ ├── markersModel.ts │ │ │ │ │ ├── markersTable.ts │ │ │ │ │ ├── markersTreeViewer.ts │ │ │ │ │ ├── markersView.ts │ │ │ │ │ ├── markersViewActions.css │ │ │ │ │ ├── markersViewActions.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── markers.css │ │ │ │ │ └── messages.ts │ │ │ │ ├── common/ │ │ │ │ │ └── markers.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── markersModel.test.ts │ │ │ ├── mcp/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── mcp.contribution.ts │ │ │ │ │ ├── mcpCommands.ts │ │ │ │ │ ├── mcpCommandsAddConfiguration.ts │ │ │ │ │ ├── mcpDiscovery.ts │ │ │ │ │ ├── mcpLanguageFeatures.ts │ │ │ │ │ └── mcpUrlHandler.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── discovery/ │ │ │ │ │ │ ├── configMcpDiscovery.ts │ │ │ │ │ │ ├── extensionMcpDiscovery.ts │ │ │ │ │ │ ├── mcpDiscovery.ts │ │ │ │ │ │ ├── nativeMcpDiscoveryAbstract.ts │ │ │ │ │ │ ├── nativeMcpDiscoveryAdapters.ts │ │ │ │ │ │ ├── nativeMcpRemoteDiscovery.ts │ │ │ │ │ │ └── workspaceMcpDiscoveryAdapter.ts │ │ │ │ │ ├── mcpConfigFileUtils.ts │ │ │ │ │ ├── mcpConfigPathsService.ts │ │ │ │ │ ├── mcpConfiguration.ts │ │ │ │ │ ├── mcpContextKeys.ts │ │ │ │ │ ├── mcpRegistry.ts │ │ │ │ │ ├── mcpRegistryInputStorage.ts │ │ │ │ │ ├── mcpRegistryTypes.ts │ │ │ │ │ ├── mcpServer.ts │ │ │ │ │ ├── mcpServerConnection.ts │ │ │ │ │ ├── mcpServerRequestHandler.ts │ │ │ │ │ ├── mcpService.ts │ │ │ │ │ ├── mcpTypes.ts │ │ │ │ │ └── modelContextProtocol.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── mcp.contribution.ts │ │ │ │ │ └── nativeMpcDiscovery.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ ├── mcpRegistry.test.ts │ │ │ │ ├── mcpRegistryInputStorage.test.ts │ │ │ │ ├── mcpRegistryTypes.ts │ │ │ │ ├── mcpServerConnection.test.ts │ │ │ │ └── mcpServerRequestHandler.test.ts │ │ │ ├── mergeEditor/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── commands/ │ │ │ │ │ │ ├── commands.ts │ │ │ │ │ │ └── devCommands.ts │ │ │ │ │ ├── mergeEditor.contribution.ts │ │ │ │ │ ├── mergeEditorAccessibilityHelp.ts │ │ │ │ │ ├── mergeEditorInput.ts │ │ │ │ │ ├── mergeEditorInputModel.ts │ │ │ │ │ ├── mergeEditorSerializer.ts │ │ │ │ │ ├── mergeMarkers/ │ │ │ │ │ │ └── mergeMarkersController.ts │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── diffComputer.ts │ │ │ │ │ │ ├── editing.ts │ │ │ │ │ │ ├── lineRange.ts │ │ │ │ │ │ ├── mapping.ts │ │ │ │ │ │ ├── mergeEditorModel.ts │ │ │ │ │ │ ├── modifiedBaseRange.ts │ │ │ │ │ │ ├── rangeUtils.ts │ │ │ │ │ │ └── textModelDiffs.ts │ │ │ │ │ ├── telemetry.ts │ │ │ │ │ ├── utils.ts │ │ │ │ │ └── view/ │ │ │ │ │ ├── colors.ts │ │ │ │ │ ├── conflictActions.ts │ │ │ │ │ ├── editorGutter.ts │ │ │ │ │ ├── editors/ │ │ │ │ │ │ ├── baseCodeEditorView.ts │ │ │ │ │ │ ├── codeEditorView.ts │ │ │ │ │ │ ├── inputCodeEditorView.ts │ │ │ │ │ │ └── resultCodeEditorView.ts │ │ │ │ │ ├── fixedZoneWidget.ts │ │ │ │ │ ├── lineAlignment.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── mergeEditor.css │ │ │ │ │ ├── mergeEditor.ts │ │ │ │ │ ├── scrollSynchronizer.ts │ │ │ │ │ ├── viewModel.ts │ │ │ │ │ └── viewZones.ts │ │ │ │ ├── common/ │ │ │ │ │ └── mergeEditor.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── devCommands.ts │ │ │ │ │ └── mergeEditor.contribution.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── mapping.test.ts │ │ │ │ └── model.test.ts │ │ │ ├── multiDiffEditor/ │ │ │ │ └── browser/ │ │ │ │ ├── actions.ts │ │ │ │ ├── icons.contribution.ts │ │ │ │ ├── multiDiffEditor.contribution.ts │ │ │ │ ├── multiDiffEditor.ts │ │ │ │ ├── multiDiffEditorInput.ts │ │ │ │ ├── multiDiffSourceResolverService.ts │ │ │ │ └── scmMultiDiffSourceResolver.ts │ │ │ ├── notebook/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── contrib/ │ │ │ │ │ │ ├── cellCommands/ │ │ │ │ │ │ │ └── cellCommands.ts │ │ │ │ │ │ ├── cellDiagnostics/ │ │ │ │ │ │ │ ├── cellDiagnosticEditorContrib.ts │ │ │ │ │ │ │ ├── cellDiagnostics.ts │ │ │ │ │ │ │ ├── cellDiagnosticsActions.ts │ │ │ │ │ │ │ └── diagnosticCellStatusBarContrib.ts │ │ │ │ │ │ ├── cellStatusBar/ │ │ │ │ │ │ │ ├── contributedStatusBarItemController.ts │ │ │ │ │ │ │ ├── executionStatusBarItemController.ts │ │ │ │ │ │ │ ├── notebookVisibleCellObserver.ts │ │ │ │ │ │ │ └── statusBarProviders.ts │ │ │ │ │ │ ├── clipboard/ │ │ │ │ │ │ │ └── notebookClipboard.ts │ │ │ │ │ │ ├── debug/ │ │ │ │ │ │ │ ├── notebookBreakpoints.ts │ │ │ │ │ │ │ ├── notebookCellPausing.ts │ │ │ │ │ │ │ └── notebookDebugDecorations.ts │ │ │ │ │ │ ├── editorHint/ │ │ │ │ │ │ │ └── emptyCellEditorHint.ts │ │ │ │ │ │ ├── editorStatusBar/ │ │ │ │ │ │ │ └── editorStatusBar.ts │ │ │ │ │ │ ├── execute/ │ │ │ │ │ │ │ └── executionEditorProgress.ts │ │ │ │ │ │ ├── find/ │ │ │ │ │ │ │ ├── findFilters.ts │ │ │ │ │ │ │ ├── findMatchDecorationModel.ts │ │ │ │ │ │ │ ├── findModel.ts │ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ │ └── notebookFind.css │ │ │ │ │ │ │ ├── notebookFind.ts │ │ │ │ │ │ │ ├── notebookFindReplaceWidget.css │ │ │ │ │ │ │ ├── notebookFindReplaceWidget.ts │ │ │ │ │ │ │ └── notebookFindWidget.ts │ │ │ │ │ │ ├── format/ │ │ │ │ │ │ │ └── formatting.ts │ │ │ │ │ │ ├── gettingStarted/ │ │ │ │ │ │ │ └── notebookGettingStarted.ts │ │ │ │ │ │ ├── kernelDetection/ │ │ │ │ │ │ │ └── notebookKernelDetection.ts │ │ │ │ │ │ ├── layout/ │ │ │ │ │ │ │ └── layoutActions.ts │ │ │ │ │ │ ├── marker/ │ │ │ │ │ │ │ └── markerProvider.ts │ │ │ │ │ │ ├── multicursor/ │ │ │ │ │ │ │ ├── notebookMulticursor.ts │ │ │ │ │ │ │ └── notebookSelectionHighlight.ts │ │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ │ └── arrow.ts │ │ │ │ │ │ ├── notebookVariables/ │ │ │ │ │ │ │ ├── notebookInlineVariables.ts │ │ │ │ │ │ │ ├── notebookVariableCommands.ts │ │ │ │ │ │ │ ├── notebookVariableContextKeys.ts │ │ │ │ │ │ │ ├── notebookVariables.ts │ │ │ │ │ │ │ ├── notebookVariablesDataSource.ts │ │ │ │ │ │ │ ├── notebookVariablesTree.ts │ │ │ │ │ │ │ └── notebookVariablesView.ts │ │ │ │ │ │ ├── outline/ │ │ │ │ │ │ │ └── notebookOutline.ts │ │ │ │ │ │ ├── profile/ │ │ │ │ │ │ │ └── notebookProfile.ts │ │ │ │ │ │ ├── saveParticipants/ │ │ │ │ │ │ │ └── saveParticipants.ts │ │ │ │ │ │ ├── troubleshoot/ │ │ │ │ │ │ │ └── layout.ts │ │ │ │ │ │ ├── undoRedo/ │ │ │ │ │ │ │ └── notebookUndoRedo.ts │ │ │ │ │ │ └── viewportWarmup/ │ │ │ │ │ │ └── viewportWarmup.ts │ │ │ │ │ ├── controller/ │ │ │ │ │ │ ├── apiActions.ts │ │ │ │ │ │ ├── cellOperations.ts │ │ │ │ │ │ ├── cellOutputActions.ts │ │ │ │ │ │ ├── chat/ │ │ │ │ │ │ │ ├── cellChatActions.ts │ │ │ │ │ │ │ ├── notebook.chat.contribution.ts │ │ │ │ │ │ │ ├── notebookChatContext.ts │ │ │ │ │ │ │ └── notebookChatController.ts │ │ │ │ │ │ ├── coreActions.ts │ │ │ │ │ │ ├── editActions.ts │ │ │ │ │ │ ├── executeActions.ts │ │ │ │ │ │ ├── foldingController.ts │ │ │ │ │ │ ├── insertCellActions.ts │ │ │ │ │ │ ├── layoutActions.ts │ │ │ │ │ │ ├── notebookIndentationActions.ts │ │ │ │ │ │ ├── sectionActions.ts │ │ │ │ │ │ └── variablesActions.ts │ │ │ │ │ ├── diff/ │ │ │ │ │ │ ├── diffCellEditorOptions.ts │ │ │ │ │ │ ├── diffComponents.ts │ │ │ │ │ │ ├── diffElementOutputs.ts │ │ │ │ │ │ ├── diffElementViewModel.ts │ │ │ │ │ │ ├── diffNestedCellViewModel.ts │ │ │ │ │ │ ├── editorHeightCalculator.ts │ │ │ │ │ │ ├── eventDispatcher.ts │ │ │ │ │ │ ├── inlineDiff/ │ │ │ │ │ │ │ ├── notebookCellDiffDecorator.ts │ │ │ │ │ │ │ ├── notebookDeletedCellDecorator.ts │ │ │ │ │ │ │ ├── notebookInlineDiff.ts │ │ │ │ │ │ │ ├── notebookInlineDiffWidget.ts │ │ │ │ │ │ │ ├── notebookInsertedCellDecorator.ts │ │ │ │ │ │ │ ├── notebookModifiedCellDecorator.ts │ │ │ │ │ │ │ ├── notebookOriginalCellModelFactory.ts │ │ │ │ │ │ │ └── notebookOriginalModelRefFactory.ts │ │ │ │ │ │ ├── notebookDiff.css │ │ │ │ │ │ ├── notebookDiffActions.ts │ │ │ │ │ │ ├── notebookDiffEditor.ts │ │ │ │ │ │ ├── notebookDiffEditorBrowser.ts │ │ │ │ │ │ ├── notebookDiffList.ts │ │ │ │ │ │ ├── notebookDiffOverviewRuler.ts │ │ │ │ │ │ ├── notebookDiffViewModel.ts │ │ │ │ │ │ ├── notebookMultiDiffEditor.ts │ │ │ │ │ │ ├── notebookMultiDiffEditorInput.ts │ │ │ │ │ │ └── unchangedEditorRegions.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── notebook.css │ │ │ │ │ │ ├── notebookCellChat.css │ │ │ │ │ │ ├── notebookCellEditorHint.css │ │ │ │ │ │ ├── notebookCellInsertToolbar.css │ │ │ │ │ │ ├── notebookCellOutput.css │ │ │ │ │ │ ├── notebookCellStatusBar.css │ │ │ │ │ │ ├── notebookCellTitleToolbar.css │ │ │ │ │ │ ├── notebookChatEditController.css │ │ │ │ │ │ ├── notebookChatEditorOverlay.css │ │ │ │ │ │ ├── notebookDnd.css │ │ │ │ │ │ ├── notebookEditorStickyScroll.css │ │ │ │ │ │ ├── notebookFocusIndicator.css │ │ │ │ │ │ ├── notebookFolding.css │ │ │ │ │ │ ├── notebookKernelActionViewItem.css │ │ │ │ │ │ ├── notebookOutline.css │ │ │ │ │ │ └── notebookToolbar.css │ │ │ │ │ ├── notebook.contribution.ts │ │ │ │ │ ├── notebookAccessibilityHelp.ts │ │ │ │ │ ├── notebookAccessibilityProvider.ts │ │ │ │ │ ├── notebookAccessibleView.ts │ │ │ │ │ ├── notebookBrowser.ts │ │ │ │ │ ├── notebookEditor.ts │ │ │ │ │ ├── notebookEditorExtensions.ts │ │ │ │ │ ├── notebookEditorWidget.ts │ │ │ │ │ ├── notebookExtensionPoint.ts │ │ │ │ │ ├── notebookIcons.ts │ │ │ │ │ ├── notebookLogger.ts │ │ │ │ │ ├── notebookOptions.ts │ │ │ │ │ ├── notebookViewEvents.ts │ │ │ │ │ ├── replEditorAccessibleView.ts │ │ │ │ │ ├── services/ │ │ │ │ │ │ ├── notebookCellStatusBarServiceImpl.ts │ │ │ │ │ │ ├── notebookEditorService.ts │ │ │ │ │ │ ├── notebookEditorServiceImpl.ts │ │ │ │ │ │ ├── notebookExecutionServiceImpl.ts │ │ │ │ │ │ ├── notebookExecutionStateServiceImpl.ts │ │ │ │ │ │ ├── notebookKernelHistoryServiceImpl.ts │ │ │ │ │ │ ├── notebookKernelServiceImpl.ts │ │ │ │ │ │ ├── notebookKeymapServiceImpl.ts │ │ │ │ │ │ ├── notebookLoggingServiceImpl.ts │ │ │ │ │ │ ├── notebookRendererMessagingServiceImpl.ts │ │ │ │ │ │ ├── notebookServiceImpl.ts │ │ │ │ │ │ └── notebookWorkerServiceImpl.ts │ │ │ │ │ ├── view/ │ │ │ │ │ │ ├── cellPart.ts │ │ │ │ │ │ ├── cellParts/ │ │ │ │ │ │ │ ├── cellActionView.ts │ │ │ │ │ │ │ ├── cellComments.ts │ │ │ │ │ │ │ ├── cellContextKeys.ts │ │ │ │ │ │ │ ├── cellDecorations.ts │ │ │ │ │ │ │ ├── cellDnd.ts │ │ │ │ │ │ │ ├── cellDragRenderer.ts │ │ │ │ │ │ │ ├── cellEditorOptions.ts │ │ │ │ │ │ │ ├── cellExecution.ts │ │ │ │ │ │ │ ├── cellFocus.ts │ │ │ │ │ │ │ ├── cellFocusIndicator.ts │ │ │ │ │ │ │ ├── cellOutput.ts │ │ │ │ │ │ │ ├── cellProgressBar.ts │ │ │ │ │ │ │ ├── cellStatusPart.ts │ │ │ │ │ │ │ ├── cellToolbarStickyScroll.ts │ │ │ │ │ │ │ ├── cellToolbars.ts │ │ │ │ │ │ │ ├── cellWidgets.ts │ │ │ │ │ │ │ ├── chat/ │ │ │ │ │ │ │ │ └── cellChatPart.ts │ │ │ │ │ │ │ ├── codeCell.ts │ │ │ │ │ │ │ ├── codeCellExecutionIcon.ts │ │ │ │ │ │ │ ├── codeCellRunToolbar.ts │ │ │ │ │ │ │ ├── collapsedCellInput.ts │ │ │ │ │ │ │ ├── collapsedCellOutput.ts │ │ │ │ │ │ │ ├── foldedCellHint.ts │ │ │ │ │ │ │ └── markupCell.ts │ │ │ │ │ │ ├── notebookCellAnchor.ts │ │ │ │ │ │ ├── notebookCellEditorPool.ts │ │ │ │ │ │ ├── notebookCellList.ts │ │ │ │ │ │ ├── notebookCellListView.ts │ │ │ │ │ │ ├── notebookRenderingCommon.ts │ │ │ │ │ │ └── renderers/ │ │ │ │ │ │ ├── backLayerWebView.ts │ │ │ │ │ │ ├── cellRenderer.ts │ │ │ │ │ │ ├── webviewMessages.ts │ │ │ │ │ │ ├── webviewPreloads.ts │ │ │ │ │ │ └── webviewThemeMapping.ts │ │ │ │ │ ├── viewModel/ │ │ │ │ │ │ ├── OutlineEntry.ts │ │ │ │ │ │ ├── baseCellViewModel.ts │ │ │ │ │ │ ├── cellEdit.ts │ │ │ │ │ │ ├── cellEditorOptions.ts │ │ │ │ │ │ ├── cellOutputTextHelper.ts │ │ │ │ │ │ ├── cellOutputViewModel.ts │ │ │ │ │ │ ├── cellSelectionCollection.ts │ │ │ │ │ │ ├── codeCellViewModel.ts │ │ │ │ │ │ ├── eventDispatcher.ts │ │ │ │ │ │ ├── foldingModel.ts │ │ │ │ │ │ ├── markupCellViewModel.ts │ │ │ │ │ │ ├── notebookOutlineDataSource.ts │ │ │ │ │ │ ├── notebookOutlineDataSourceFactory.ts │ │ │ │ │ │ ├── notebookOutlineEntryFactory.ts │ │ │ │ │ │ ├── notebookViewModelImpl.ts │ │ │ │ │ │ └── viewContext.ts │ │ │ │ │ └── viewParts/ │ │ │ │ │ ├── notebookCellOverlays.ts │ │ │ │ │ ├── notebookEditorStickyScroll.ts │ │ │ │ │ ├── notebookEditorToolbar.ts │ │ │ │ │ ├── notebookEditorWidgetContextKeys.ts │ │ │ │ │ ├── notebookHorizontalTracker.ts │ │ │ │ │ ├── notebookKernelQuickPickStrategy.ts │ │ │ │ │ ├── notebookKernelView.ts │ │ │ │ │ ├── notebookOverviewRuler.ts │ │ │ │ │ ├── notebookTopCellToolbar.ts │ │ │ │ │ └── notebookViewZones.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── cellEdit.ts │ │ │ │ │ │ ├── notebookCellOutputTextModel.ts │ │ │ │ │ │ ├── notebookCellTextModel.ts │ │ │ │ │ │ ├── notebookMetadataTextModel.ts │ │ │ │ │ │ └── notebookTextModel.ts │ │ │ │ │ ├── notebookCellStatusBarService.ts │ │ │ │ │ ├── notebookCommon.ts │ │ │ │ │ ├── notebookContextKeys.ts │ │ │ │ │ ├── notebookDiff.ts │ │ │ │ │ ├── notebookDiffEditorInput.ts │ │ │ │ │ ├── notebookEditorInput.ts │ │ │ │ │ ├── notebookEditorModel.ts │ │ │ │ │ ├── notebookEditorModelResolverService.ts │ │ │ │ │ ├── notebookEditorModelResolverServiceImpl.ts │ │ │ │ │ ├── notebookExecutionService.ts │ │ │ │ │ ├── notebookExecutionStateService.ts │ │ │ │ │ ├── notebookKernelService.ts │ │ │ │ │ ├── notebookKeymapService.ts │ │ │ │ │ ├── notebookLoggingService.ts │ │ │ │ │ ├── notebookOutputRenderer.ts │ │ │ │ │ ├── notebookPerformance.ts │ │ │ │ │ ├── notebookProvider.ts │ │ │ │ │ ├── notebookRange.ts │ │ │ │ │ ├── notebookRendererMessagingService.ts │ │ │ │ │ ├── notebookService.ts │ │ │ │ │ └── services/ │ │ │ │ │ ├── notebookCellMatching.ts │ │ │ │ │ ├── notebookWebWorker.ts │ │ │ │ │ ├── notebookWebWorkerMain.ts │ │ │ │ │ └── notebookWorkerService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── NotebookEditorWidgetService.test.ts │ │ │ │ ├── __snapshots__/ │ │ │ │ │ ├── NotebookEditorStickyScroll_test0__should_render_empty___scrollTop_at_0.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test1__should_render_0-_1___visible_range_3-_8.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test2__should_render_0____visible_range_6-_9_so_collapsing_next_2_against_following_section.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test3__should_render_0-_2___collapsing_against_equivalent_level_header.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test4__should_render_0____scrolltop_halfway_through_cell_0.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test5__should_render_0-_2___scrolltop_halfway_through_cell_2.0.snap │ │ │ │ │ ├── NotebookEditorStickyScroll_test6__should_render_6-_7___scrolltop_halfway_through_cell_7.0.snap │ │ │ │ │ └── NotebookEditorStickyScroll_test7__should_render_0-_1___collapsing_against_next_section.0.snap │ │ │ │ ├── cellDecorations.test.ts │ │ │ │ ├── cellDnd.test.ts │ │ │ │ ├── cellOperations.test.ts │ │ │ │ ├── cellOutput.test.ts │ │ │ │ ├── contrib/ │ │ │ │ │ ├── contributedStatusBarItemController.test.ts │ │ │ │ │ ├── executionStatusBarItem.test.ts │ │ │ │ │ ├── find.test.ts │ │ │ │ │ ├── layoutActions.test.ts │ │ │ │ │ ├── notebookCellDiagnostics.test.ts │ │ │ │ │ ├── notebookClipboard.test.ts │ │ │ │ │ ├── notebookOutline.test.ts │ │ │ │ │ ├── notebookOutlineViewProviders.test.ts │ │ │ │ │ ├── notebookSymbols.test.ts │ │ │ │ │ ├── notebookUndoRedo.test.ts │ │ │ │ │ └── outputCopyTests.test.ts │ │ │ │ ├── diff/ │ │ │ │ │ ├── editorHeightCalculator.test.ts │ │ │ │ │ ├── notebookDiff.test.ts │ │ │ │ │ └── notebookDiffService.test.ts │ │ │ │ ├── notebookBrowser.test.ts │ │ │ │ ├── notebookCellAnchor.test.ts │ │ │ │ ├── notebookCellList.test.ts │ │ │ │ ├── notebookCommon.test.ts │ │ │ │ ├── notebookEditor.test.ts │ │ │ │ ├── notebookEditorModel.test.ts │ │ │ │ ├── notebookExecutionService.test.ts │ │ │ │ ├── notebookExecutionStateService.test.ts │ │ │ │ ├── notebookFolding.test.ts │ │ │ │ ├── notebookKernelHistory.test.ts │ │ │ │ ├── notebookKernelService.test.ts │ │ │ │ ├── notebookRendererMessagingService.test.ts │ │ │ │ ├── notebookSelection.test.ts │ │ │ │ ├── notebookServiceImpl.test.ts │ │ │ │ ├── notebookStickyScroll.test.ts │ │ │ │ ├── notebookTextModel.test.ts │ │ │ │ ├── notebookVariablesDataSource.test.ts │ │ │ │ ├── notebookViewModel.test.ts │ │ │ │ ├── notebookViewZones.test.ts │ │ │ │ ├── notebookWorkbenchToolbar.test.ts │ │ │ │ └── testNotebookEditor.ts │ │ │ ├── outline/ │ │ │ │ └── browser/ │ │ │ │ ├── outline.contribution.ts │ │ │ │ ├── outline.ts │ │ │ │ ├── outlineActions.ts │ │ │ │ ├── outlinePane.css │ │ │ │ ├── outlinePane.ts │ │ │ │ └── outlineViewState.ts │ │ │ ├── output/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── output.contribution.ts │ │ │ │ │ ├── output.css │ │ │ │ │ ├── outputLinkProvider.ts │ │ │ │ │ ├── outputServices.ts │ │ │ │ │ └── outputView.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── outputChannelModel.ts │ │ │ │ │ ├── outputLinkComputer.ts │ │ │ │ │ └── outputLinkComputerMain.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── outputChannelModel.test.ts │ │ │ │ └── outputLinkProvider.test.ts │ │ │ ├── performance/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── inputLatencyContrib.ts │ │ │ │ │ ├── performance.contribution.ts │ │ │ │ │ ├── performance.web.contribution.ts │ │ │ │ │ ├── perfviewEditor.ts │ │ │ │ │ └── startupTimings.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── performance.contribution.ts │ │ │ │ ├── rendererAutoProfiler.ts │ │ │ │ ├── startupProfiler.ts │ │ │ │ └── startupTimings.ts │ │ │ ├── preferences/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── keybindingWidgets.ts │ │ │ │ │ ├── keybindingsEditor.ts │ │ │ │ │ ├── keybindingsEditorContribution.ts │ │ │ │ │ ├── keyboardLayoutPicker.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── keybindings.css │ │ │ │ │ │ ├── keybindingsEditor.css │ │ │ │ │ │ ├── preferences.css │ │ │ │ │ │ ├── settingsEditor2.css │ │ │ │ │ │ └── settingsWidgets.css │ │ │ │ │ ├── preferences.contribution.ts │ │ │ │ │ ├── preferencesActions.ts │ │ │ │ │ ├── preferencesEditor.ts │ │ │ │ │ ├── preferencesIcons.ts │ │ │ │ │ ├── preferencesRenderers.ts │ │ │ │ │ ├── preferencesSearch.ts │ │ │ │ │ ├── preferencesWidgets.ts │ │ │ │ │ ├── settingsEditor2.ts │ │ │ │ │ ├── settingsEditorSettingIndicators.ts │ │ │ │ │ ├── settingsLayout.ts │ │ │ │ │ ├── settingsSearchMenu.ts │ │ │ │ │ ├── settingsTree.ts │ │ │ │ │ ├── settingsTreeModels.ts │ │ │ │ │ ├── settingsWidgets.ts │ │ │ │ │ └── tocTree.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── preferences.ts │ │ │ │ │ ├── preferencesContribution.ts │ │ │ │ │ ├── settingsEditorColorRegistry.ts │ │ │ │ │ ├── settingsFilesystemProvider.ts │ │ │ │ │ └── smartSnippetInserter.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── keybindingsEditorContribution.test.ts │ │ │ │ │ └── settingsTreeModels.test.ts │ │ │ │ └── common/ │ │ │ │ └── smartSnippetInserter.test.ts │ │ │ ├── quickaccess/ │ │ │ │ └── browser/ │ │ │ │ ├── commandsQuickAccess.ts │ │ │ │ ├── quickAccess.contribution.ts │ │ │ │ └── viewQuickAccess.ts │ │ │ ├── relauncher/ │ │ │ │ └── browser/ │ │ │ │ └── relauncher.contribution.ts │ │ │ ├── remote/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── explorerViewItems.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── remoteViewlet.css │ │ │ │ │ │ └── tunnelView.css │ │ │ │ │ ├── remote.contribution.ts │ │ │ │ │ ├── remote.ts │ │ │ │ │ ├── remoteConnectionHealth.ts │ │ │ │ │ ├── remoteExplorer.ts │ │ │ │ │ ├── remoteIcons.ts │ │ │ │ │ ├── remoteIndicator.ts │ │ │ │ │ ├── remoteStartEntry.contribution.ts │ │ │ │ │ ├── remoteStartEntry.ts │ │ │ │ │ ├── showCandidate.ts │ │ │ │ │ ├── tunnelFactory.ts │ │ │ │ │ ├── tunnelView.ts │ │ │ │ │ └── urlFinder.ts │ │ │ │ ├── common/ │ │ │ │ │ └── remote.contribution.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── remote.contribution.ts │ │ │ ├── remoteTunnel/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── remoteTunnel.contribution.ts │ │ │ ├── replNotebook/ │ │ │ │ └── browser/ │ │ │ │ ├── interactiveEditor.css │ │ │ │ ├── media/ │ │ │ │ │ └── interactive.css │ │ │ │ ├── repl.contribution.ts │ │ │ │ ├── replEditor.ts │ │ │ │ ├── replEditorAccessibilityHelp.ts │ │ │ │ └── replEditorInput.ts │ │ │ ├── sash/ │ │ │ │ └── browser/ │ │ │ │ ├── sash.contribution.ts │ │ │ │ └── sash.ts │ │ │ ├── scm/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── activity.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── dirtydiffDecorator.css │ │ │ │ │ │ └── scm.css │ │ │ │ │ ├── menus.ts │ │ │ │ │ ├── quickDiffDecorator.ts │ │ │ │ │ ├── quickDiffModel.ts │ │ │ │ │ ├── quickDiffWidget.ts │ │ │ │ │ ├── scm.contribution.ts │ │ │ │ │ ├── scmAccessibilityHelp.ts │ │ │ │ │ ├── scmHistory.ts │ │ │ │ │ ├── scmHistoryViewPane.ts │ │ │ │ │ ├── scmRepositoriesViewPane.ts │ │ │ │ │ ├── scmRepositoryRenderer.ts │ │ │ │ │ ├── scmViewPane.ts │ │ │ │ │ ├── scmViewPaneContainer.ts │ │ │ │ │ ├── scmViewService.ts │ │ │ │ │ ├── util.ts │ │ │ │ │ └── workingSet.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── history.ts │ │ │ │ │ ├── quickDiff.ts │ │ │ │ │ ├── quickDiffService.ts │ │ │ │ │ ├── scm.ts │ │ │ │ │ └── scmService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── scmHistory.test.ts │ │ │ ├── scrollLocking/ │ │ │ │ └── browser/ │ │ │ │ ├── scrollLocking.contribution.ts │ │ │ │ └── scrollLocking.ts │ │ │ ├── search/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── AISearch/ │ │ │ │ │ │ ├── aiSearchModel.ts │ │ │ │ │ │ └── aiSearchModelBase.ts │ │ │ │ │ ├── anythingQuickAccess.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── anythingQuickAccess.css │ │ │ │ │ │ └── searchview.css │ │ │ │ │ ├── notebookSearch/ │ │ │ │ │ │ ├── notebookSearchContributions.ts │ │ │ │ │ │ ├── notebookSearchModel.ts │ │ │ │ │ │ ├── notebookSearchModelBase.ts │ │ │ │ │ │ ├── notebookSearchService.ts │ │ │ │ │ │ └── searchNotebookHelpers.ts │ │ │ │ │ ├── patternInputWidget.ts │ │ │ │ │ ├── quickTextSearch/ │ │ │ │ │ │ └── textSearchQuickAccess.ts │ │ │ │ │ ├── replace.ts │ │ │ │ │ ├── replaceContributions.ts │ │ │ │ │ ├── replaceService.ts │ │ │ │ │ ├── search.contribution.ts │ │ │ │ │ ├── searchActionsBase.ts │ │ │ │ │ ├── searchActionsCopy.ts │ │ │ │ │ ├── searchActionsFind.ts │ │ │ │ │ ├── searchActionsNav.ts │ │ │ │ │ ├── searchActionsRemoveReplace.ts │ │ │ │ │ ├── searchActionsSymbol.ts │ │ │ │ │ ├── searchActionsTextQuickAccess.ts │ │ │ │ │ ├── searchActionsTopBar.ts │ │ │ │ │ ├── searchCompare.ts │ │ │ │ │ ├── searchFindInput.ts │ │ │ │ │ ├── searchIcons.ts │ │ │ │ │ ├── searchMessage.ts │ │ │ │ │ ├── searchResultsView.ts │ │ │ │ │ ├── searchTreeModel/ │ │ │ │ │ │ ├── fileMatch.ts │ │ │ │ │ │ ├── folderMatch.ts │ │ │ │ │ │ ├── match.ts │ │ │ │ │ │ ├── rangeDecorations.ts │ │ │ │ │ │ ├── searchModel.ts │ │ │ │ │ │ ├── searchResult.ts │ │ │ │ │ │ ├── searchTreeCommon.ts │ │ │ │ │ │ ├── searchViewModelWorkbenchService.ts │ │ │ │ │ │ └── textSearchHeading.ts │ │ │ │ │ ├── searchView.ts │ │ │ │ │ ├── searchWidget.ts │ │ │ │ │ └── symbolsQuickAccess.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── cacheState.ts │ │ │ │ │ ├── cellSearchModel.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── notebookSearch.ts │ │ │ │ │ ├── search.ts │ │ │ │ │ ├── searchHistoryService.ts │ │ │ │ │ └── searchNotebookHelpers.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── mockSearchTree.ts │ │ │ │ │ ├── searchActions.test.ts │ │ │ │ │ ├── searchModel.test.ts │ │ │ │ │ ├── searchNotebookHelpers.test.ts │ │ │ │ │ ├── searchResult.test.ts │ │ │ │ │ ├── searchTestCommon.ts │ │ │ │ │ └── searchViewlet.test.ts │ │ │ │ └── common/ │ │ │ │ ├── cacheState.test.ts │ │ │ │ └── extractRange.test.ts │ │ │ ├── searchEditor/ │ │ │ │ └── browser/ │ │ │ │ ├── constants.ts │ │ │ │ ├── media/ │ │ │ │ │ └── searchEditor.css │ │ │ │ ├── searchEditor.contribution.ts │ │ │ │ ├── searchEditor.ts │ │ │ │ ├── searchEditorActions.ts │ │ │ │ ├── searchEditorInput.ts │ │ │ │ ├── searchEditorModel.ts │ │ │ │ └── searchEditorSerialization.ts │ │ │ ├── share/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── share.contribution.ts │ │ │ │ │ ├── share.css │ │ │ │ │ └── shareService.ts │ │ │ │ └── common/ │ │ │ │ └── share.ts │ │ │ ├── snippets/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── commands/ │ │ │ │ │ │ ├── abstractSnippetsActions.ts │ │ │ │ │ │ ├── configureSnippets.ts │ │ │ │ │ │ ├── fileTemplateSnippets.ts │ │ │ │ │ │ ├── insertSnippet.ts │ │ │ │ │ │ └── surroundWithSnippet.ts │ │ │ │ │ ├── snippetCodeActionProvider.ts │ │ │ │ │ ├── snippetCompletionProvider.ts │ │ │ │ │ ├── snippetPicker.ts │ │ │ │ │ ├── snippets.contribution.ts │ │ │ │ │ ├── snippets.ts │ │ │ │ │ ├── snippetsFile.ts │ │ │ │ │ ├── snippetsService.ts │ │ │ │ │ └── tabCompletion.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── snippetFile.test.ts │ │ │ │ ├── snippetsRegistry.test.ts │ │ │ │ ├── snippetsRewrite.test.ts │ │ │ │ └── snippetsService.test.ts │ │ │ ├── speech/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── speech.contribution.ts │ │ │ │ │ ├── speechAccessibilitySignal.ts │ │ │ │ │ └── speechService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── speechService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── speechService.test.ts │ │ │ ├── splash/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── partsSplash.ts │ │ │ │ │ ├── splash.contribution.ts │ │ │ │ │ └── splash.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── splash.contribution.ts │ │ │ ├── surveys/ │ │ │ │ └── browser/ │ │ │ │ ├── languageSurveys.contribution.ts │ │ │ │ └── nps.contribution.ts │ │ │ ├── tags/ │ │ │ │ ├── browser/ │ │ │ │ │ └── workspaceTagsService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── javaWorkspaceTags.ts │ │ │ │ │ └── workspaceTags.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── tags.contribution.ts │ │ │ │ │ ├── workspaceTags.ts │ │ │ │ │ └── workspaceTagsService.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ └── workspaceTags.test.ts │ │ │ ├── tasks/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── abstractTaskService.ts │ │ │ │ │ ├── runAutomaticTasks.ts │ │ │ │ │ ├── task.contribution.ts │ │ │ │ │ ├── taskQuickPick.ts │ │ │ │ │ ├── taskService.ts │ │ │ │ │ ├── taskTerminalStatus.ts │ │ │ │ │ ├── tasksQuickAccess.ts │ │ │ │ │ └── terminalTaskSystem.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── jsonSchemaCommon.ts │ │ │ │ │ ├── jsonSchema_v1.ts │ │ │ │ │ ├── jsonSchema_v2.ts │ │ │ │ │ ├── problemCollectors.ts │ │ │ │ │ ├── problemMatcher.ts │ │ │ │ │ ├── taskConfiguration.ts │ │ │ │ │ ├── taskDefinitionRegistry.ts │ │ │ │ │ ├── taskService.ts │ │ │ │ │ ├── taskSystem.ts │ │ │ │ │ ├── taskTemplates.ts │ │ │ │ │ └── tasks.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── taskService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── taskTerminalStatus.test.ts │ │ │ │ └── common/ │ │ │ │ ├── problemMatcher.test.ts │ │ │ │ └── taskConfiguration.test.ts │ │ │ ├── telemetry/ │ │ │ │ └── browser/ │ │ │ │ └── telemetry.contribution.ts │ │ │ ├── terminal/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── baseTerminalBackend.ts │ │ │ │ │ ├── detachedTerminal.ts │ │ │ │ │ ├── environmentVariableInfo.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── terminal.css │ │ │ │ │ │ ├── terminalVoice.css │ │ │ │ │ │ ├── widgets.css │ │ │ │ │ │ └── xterm.css │ │ │ │ │ ├── remotePty.ts │ │ │ │ │ ├── remoteTerminalBackend.ts │ │ │ │ │ ├── terminal.contribution.ts │ │ │ │ │ ├── terminal.ts │ │ │ │ │ ├── terminal.web.contribution.ts │ │ │ │ │ ├── terminalActions.ts │ │ │ │ │ ├── terminalCommands.ts │ │ │ │ │ ├── terminalConfigurationService.ts │ │ │ │ │ ├── terminalContextMenu.ts │ │ │ │ │ ├── terminalEditor.ts │ │ │ │ │ ├── terminalEditorInput.ts │ │ │ │ │ ├── terminalEditorSerializer.ts │ │ │ │ │ ├── terminalEditorService.ts │ │ │ │ │ ├── terminalEscapeSequences.ts │ │ │ │ │ ├── terminalEvents.ts │ │ │ │ │ ├── terminalExtensions.ts │ │ │ │ │ ├── terminalGroup.ts │ │ │ │ │ ├── terminalGroupService.ts │ │ │ │ │ ├── terminalIcon.ts │ │ │ │ │ ├── terminalIconPicker.ts │ │ │ │ │ ├── terminalIcons.ts │ │ │ │ │ ├── terminalInstance.ts │ │ │ │ │ ├── terminalInstanceService.ts │ │ │ │ │ ├── terminalKeybindings.ts │ │ │ │ │ ├── terminalMainContribution.ts │ │ │ │ │ ├── terminalMenus.ts │ │ │ │ │ ├── terminalProcessExtHostProxy.ts │ │ │ │ │ ├── terminalProcessManager.ts │ │ │ │ │ ├── terminalProfileQuickpick.ts │ │ │ │ │ ├── terminalProfileResolverService.ts │ │ │ │ │ ├── terminalProfileService.ts │ │ │ │ │ ├── terminalResizeDebouncer.ts │ │ │ │ │ ├── terminalService.ts │ │ │ │ │ ├── terminalStatusList.ts │ │ │ │ │ ├── terminalTabbedView.ts │ │ │ │ │ ├── terminalTabsList.ts │ │ │ │ │ ├── terminalTelemetry.ts │ │ │ │ │ ├── terminalTestHelpers.ts │ │ │ │ │ ├── terminalTooltip.ts │ │ │ │ │ ├── terminalUri.ts │ │ │ │ │ ├── terminalView.ts │ │ │ │ │ ├── widgets/ │ │ │ │ │ │ ├── terminalHoverWidget.ts │ │ │ │ │ │ ├── widgetManager.ts │ │ │ │ │ │ └── widgets.ts │ │ │ │ │ ├── xterm/ │ │ │ │ │ │ ├── decorationAddon.ts │ │ │ │ │ │ ├── decorationStyles.ts │ │ │ │ │ │ ├── lineDataEventAddon.ts │ │ │ │ │ │ ├── markNavigationAddon.ts │ │ │ │ │ │ ├── xtermAddonImporter.ts │ │ │ │ │ │ └── xtermTerminal.ts │ │ │ │ │ └── xterm-private.d.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── basePty.ts │ │ │ │ │ ├── environmentVariable.contribution.ts │ │ │ │ │ ├── environmentVariable.ts │ │ │ │ │ ├── environmentVariableService.ts │ │ │ │ │ ├── remote/ │ │ │ │ │ │ ├── remoteTerminalChannel.ts │ │ │ │ │ │ └── terminal.ts │ │ │ │ │ ├── scripts/ │ │ │ │ │ │ ├── cgmanifest.json │ │ │ │ │ │ ├── shellIntegration-bash.sh │ │ │ │ │ │ ├── shellIntegration-env.zsh │ │ │ │ │ │ ├── shellIntegration-login.zsh │ │ │ │ │ │ ├── shellIntegration-profile.zsh │ │ │ │ │ │ ├── shellIntegration-rc.zsh │ │ │ │ │ │ ├── shellIntegration.fish │ │ │ │ │ │ └── shellIntegration.ps1 │ │ │ │ │ ├── terminal.ts │ │ │ │ │ ├── terminalColorRegistry.ts │ │ │ │ │ ├── terminalConfiguration.ts │ │ │ │ │ ├── terminalContextKey.ts │ │ │ │ │ ├── terminalEnvironment.ts │ │ │ │ │ ├── terminalExtensionPoints.contribution.ts │ │ │ │ │ ├── terminalExtensionPoints.ts │ │ │ │ │ ├── terminalStorageKeys.ts │ │ │ │ │ └── terminalStrings.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── localPty.ts │ │ │ │ │ ├── localTerminalBackend.ts │ │ │ │ │ ├── terminal.contribution.ts │ │ │ │ │ ├── terminalNativeContribution.ts │ │ │ │ │ ├── terminalProfileResolverService.ts │ │ │ │ │ └── terminalRemote.ts │ │ │ │ ├── terminal.all.ts │ │ │ │ ├── terminalContribChatExports.ts │ │ │ │ ├── terminalContribExports.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── capabilities/ │ │ │ │ │ │ ├── commandDetectionCapability.test.ts │ │ │ │ │ │ ├── partialCommandDetectionCapability.test.ts │ │ │ │ │ │ └── terminalCapabilityStore.test.ts │ │ │ │ │ ├── terminalActions.test.ts │ │ │ │ │ ├── terminalConfigurationService.test.ts │ │ │ │ │ ├── terminalInstance.test.ts │ │ │ │ │ ├── terminalInstanceService.test.ts │ │ │ │ │ ├── terminalProcessManager.test.ts │ │ │ │ │ ├── terminalProfileService.integrationTest.ts │ │ │ │ │ ├── terminalService.test.ts │ │ │ │ │ ├── terminalStatusList.test.ts │ │ │ │ │ ├── terminalUri.test.ts │ │ │ │ │ └── xterm/ │ │ │ │ │ ├── decorationAddon.test.ts │ │ │ │ │ ├── lineDataEventAddon.test.ts │ │ │ │ │ ├── shellIntegrationAddon.test.ts │ │ │ │ │ └── xtermTerminal.test.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── environmentVariableCollection.test.ts │ │ │ │ │ ├── environmentVariableService.test.ts │ │ │ │ │ ├── environmentVariableShared.test.ts │ │ │ │ │ ├── terminalColorRegistry.test.ts │ │ │ │ │ ├── terminalDataBuffering.test.ts │ │ │ │ │ └── terminalEnvironment.test.ts │ │ │ │ └── node/ │ │ │ │ └── terminalProfiles.test.ts │ │ │ ├── terminalContrib/ │ │ │ │ ├── README.md │ │ │ │ ├── accessibility/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── bufferContentTracker.ts │ │ │ │ │ │ ├── terminal.accessibility.contribution.ts │ │ │ │ │ │ ├── terminalAccessibilityHelp.ts │ │ │ │ │ │ ├── terminalAccessibleBufferProvider.ts │ │ │ │ │ │ └── textAreaSyncAddon.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── terminal.accessibility.ts │ │ │ │ │ │ └── terminalAccessibilityConfiguration.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── bufferContentTracker.test.ts │ │ │ │ ├── autoReplies/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── terminal.autoReplies.contribution.ts │ │ │ │ │ └── common/ │ │ │ │ │ └── terminalAutoRepliesConfiguration.ts │ │ │ │ ├── chat/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ ├── terminalChatWidget.css │ │ │ │ │ │ │ └── terminalInitialHint.css │ │ │ │ │ │ ├── terminal.chat.contribution.ts │ │ │ │ │ │ ├── terminal.initialHint.contribution.ts │ │ │ │ │ │ ├── terminalChat.ts │ │ │ │ │ │ ├── terminalChatAccessibilityHelp.ts │ │ │ │ │ │ ├── terminalChatAccessibleView.ts │ │ │ │ │ │ ├── terminalChatActions.ts │ │ │ │ │ │ ├── terminalChatController.ts │ │ │ │ │ │ ├── terminalChatEnabler.ts │ │ │ │ │ │ └── terminalChatWidget.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── terminalInitialHintConfiguration.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── terminalInitialHint.test.ts │ │ │ │ ├── clipboard/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── terminal.clipboard.contribution.ts │ │ │ │ │ │ └── terminalClipboard.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── terminalClipboard.test.ts │ │ │ │ ├── commandGuide/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── terminal.commandGuide.contribution.ts │ │ │ │ │ └── common/ │ │ │ │ │ └── terminalCommandGuideConfiguration.ts │ │ │ │ ├── developer/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── developer.css │ │ │ │ │ │ └── terminal.developer.contribution.ts │ │ │ │ │ └── common/ │ │ │ │ │ └── terminal.developer.ts │ │ │ │ ├── environmentChanges/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── terminal.environmentChanges.contribution.ts │ │ │ │ ├── find/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── terminalFind.css │ │ │ │ │ │ ├── terminal.find.contribution.ts │ │ │ │ │ │ └── terminalFindWidget.ts │ │ │ │ │ └── common/ │ │ │ │ │ └── terminal.find.ts │ │ │ │ ├── history/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── terminal.history.contribution.ts │ │ │ │ │ │ └── terminalRunRecentQuickPick.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── history.ts │ │ │ │ │ │ └── terminal.history.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── common/ │ │ │ │ │ └── history.test.ts │ │ │ │ ├── links/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── links.ts │ │ │ │ │ │ ├── terminal.links.contribution.ts │ │ │ │ │ │ ├── terminalExternalLinkDetector.ts │ │ │ │ │ │ ├── terminalLink.ts │ │ │ │ │ │ ├── terminalLinkDetectorAdapter.ts │ │ │ │ │ │ ├── terminalLinkHelpers.ts │ │ │ │ │ │ ├── terminalLinkManager.ts │ │ │ │ │ │ ├── terminalLinkOpeners.ts │ │ │ │ │ │ ├── terminalLinkParsing.ts │ │ │ │ │ │ ├── terminalLinkProviderService.ts │ │ │ │ │ │ ├── terminalLinkQuickpick.ts │ │ │ │ │ │ ├── terminalLinkResolver.ts │ │ │ │ │ │ ├── terminalLocalLinkDetector.ts │ │ │ │ │ │ ├── terminalMultiLineLinkDetector.ts │ │ │ │ │ │ ├── terminalUriLinkDetector.ts │ │ │ │ │ │ └── terminalWordLinkDetector.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── terminal.links.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── linkTestUtils.ts │ │ │ │ │ ├── terminalLinkHelpers.test.ts │ │ │ │ │ ├── terminalLinkManager.test.ts │ │ │ │ │ ├── terminalLinkOpeners.test.ts │ │ │ │ │ ├── terminalLinkParsing.test.ts │ │ │ │ │ ├── terminalLocalLinkDetector.test.ts │ │ │ │ │ ├── terminalMultiLineLinkDetector.test.ts │ │ │ │ │ ├── terminalUriLinkDetector.test.ts │ │ │ │ │ └── terminalWordLinkDetector.test.ts │ │ │ │ ├── quickAccess/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── terminal.quickAccess.contribution.ts │ │ │ │ │ └── terminalQuickAccess.ts │ │ │ │ ├── quickFix/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── terminalQuickFix.css │ │ │ │ │ │ ├── quickFix.ts │ │ │ │ │ │ ├── quickFixAddon.ts │ │ │ │ │ │ ├── terminal.quickFix.contribution.ts │ │ │ │ │ │ ├── terminalQuickFixBuiltinActions.ts │ │ │ │ │ │ └── terminalQuickFixService.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── quickFixAddon.test.ts │ │ │ │ ├── stickyScroll/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── stickyScroll.css │ │ │ │ │ │ ├── terminal.stickyScroll.contribution.ts │ │ │ │ │ │ ├── terminalStickyScrollColorRegistry.ts │ │ │ │ │ │ ├── terminalStickyScrollContribution.ts │ │ │ │ │ │ └── terminalStickyScrollOverlay.ts │ │ │ │ │ └── common/ │ │ │ │ │ └── terminalStickyScrollConfiguration.ts │ │ │ │ ├── suggest/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── media/ │ │ │ │ │ │ │ └── terminalSymbolIcons.css │ │ │ │ │ │ ├── pwshCompletionProviderAddon.ts │ │ │ │ │ │ ├── terminal.suggest.contribution.ts │ │ │ │ │ │ ├── terminalCompletionItem.ts │ │ │ │ │ │ ├── terminalCompletionModel.ts │ │ │ │ │ │ ├── terminalCompletionService.ts │ │ │ │ │ │ ├── terminalSuggestAddon.ts │ │ │ │ │ │ ├── terminalSuggestTelemetry.ts │ │ │ │ │ │ └── terminalSymbolIcons.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── terminal.suggest.ts │ │ │ │ │ │ └── terminalSuggestConfiguration.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ ├── terminalCompletionModel.test.ts │ │ │ │ │ └── terminalCompletionService.test.ts │ │ │ │ ├── typeAhead/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── terminal.typeAhead.contribution.ts │ │ │ │ │ │ └── terminalTypeAheadAddon.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── terminalTypeAheadConfiguration.ts │ │ │ │ │ └── test/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── terminalTypeAhead.test.ts │ │ │ │ ├── wslRecommendation/ │ │ │ │ │ └── browser/ │ │ │ │ │ └── terminal.wslRecommendation.contribution.ts │ │ │ │ └── zoom/ │ │ │ │ ├── browser/ │ │ │ │ │ └── terminal.zoom.contribution.ts │ │ │ │ └── common/ │ │ │ │ └── terminal.zoom.ts │ │ │ ├── testing/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── codeCoverageDecorations.ts │ │ │ │ │ ├── codeCoverageDisplayUtils.ts │ │ │ │ │ ├── explorerProjections/ │ │ │ │ │ │ ├── display.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── listProjection.ts │ │ │ │ │ │ ├── testItemContextOverlay.ts │ │ │ │ │ │ ├── testingObjectTree.ts │ │ │ │ │ │ ├── testingViewState.ts │ │ │ │ │ │ └── treeProjection.ts │ │ │ │ │ ├── icons.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ ├── testMessageColorizer.css │ │ │ │ │ │ └── testing.css │ │ │ │ │ ├── testCoverageBars.ts │ │ │ │ │ ├── testCoverageView.ts │ │ │ │ │ ├── testExplorerActions.ts │ │ │ │ │ ├── testMessageColorizer.ts │ │ │ │ │ ├── testResultsView/ │ │ │ │ │ │ ├── testResultsOutput.ts │ │ │ │ │ │ ├── testResultsSubject.ts │ │ │ │ │ │ ├── testResultsTree.ts │ │ │ │ │ │ ├── testResultsViewContent.css │ │ │ │ │ │ └── testResultsViewContent.ts │ │ │ │ │ ├── testing.contribution.ts │ │ │ │ │ ├── testingConfigurationUi.ts │ │ │ │ │ ├── testingDecorations.ts │ │ │ │ │ ├── testingExplorerFilter.ts │ │ │ │ │ ├── testingExplorerView.ts │ │ │ │ │ ├── testingOutputPeek.ts │ │ │ │ │ ├── testingProgressUiService.ts │ │ │ │ │ ├── testingViewPaneContainer.ts │ │ │ │ │ └── theme.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── configuration.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── getComputedState.ts │ │ │ │ │ ├── mainThreadTestCollection.ts │ │ │ │ │ ├── observableUtils.ts │ │ │ │ │ ├── observableValue.ts │ │ │ │ │ ├── storedValue.ts │ │ │ │ │ ├── testCoverage.ts │ │ │ │ │ ├── testCoverageService.ts │ │ │ │ │ ├── testExclusions.ts │ │ │ │ │ ├── testExplorerFilterState.ts │ │ │ │ │ ├── testId.ts │ │ │ │ │ ├── testItemCollection.ts │ │ │ │ │ ├── testProfileService.ts │ │ │ │ │ ├── testResult.ts │ │ │ │ │ ├── testResultService.ts │ │ │ │ │ ├── testResultStorage.ts │ │ │ │ │ ├── testService.ts │ │ │ │ │ ├── testServiceImpl.ts │ │ │ │ │ ├── testTypes.ts │ │ │ │ │ ├── testingContentProvider.ts │ │ │ │ │ ├── testingContextKeys.ts │ │ │ │ │ ├── testingContinuousRunService.ts │ │ │ │ │ ├── testingDecorations.ts │ │ │ │ │ ├── testingPeekOpener.ts │ │ │ │ │ ├── testingStates.ts │ │ │ │ │ └── testingUri.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ ├── Code_Coverage_Decorations_CoverageDetailsModel_1.0.snap │ │ │ │ │ │ ├── Code_Coverage_Decorations_CoverageDetailsModel_2.0.snap │ │ │ │ │ │ ├── Code_Coverage_Decorations_CoverageDetailsModel_3.0.snap │ │ │ │ │ │ └── Code_Coverage_Decorations_CoverageDetailsModel_4.0.snap │ │ │ │ │ ├── codeCoverageDecorations.test.ts │ │ │ │ │ ├── explorerProjections/ │ │ │ │ │ │ ├── nameProjection.test.ts │ │ │ │ │ │ └── treeProjection.test.ts │ │ │ │ │ └── testObjectTree.ts │ │ │ │ └── common/ │ │ │ │ ├── testCoverage.test.ts │ │ │ │ ├── testExplorerFilterState.test.ts │ │ │ │ ├── testProfileService.test.ts │ │ │ │ ├── testResultService.test.ts │ │ │ │ ├── testResultStorage.test.ts │ │ │ │ ├── testService.test.ts │ │ │ │ ├── testStubs.ts │ │ │ │ ├── testingContinuousRunService.test.ts │ │ │ │ └── testingUri.test.ts │ │ │ ├── themes/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── themes.contribution.ts │ │ │ │ │ └── themes.test.contribution.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ ├── colorRegistry.releaseTest.ts │ │ │ │ └── colorRegistryExport.test.ts │ │ │ ├── timeline/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── timelinePane.css │ │ │ │ │ ├── timeline.contribution.ts │ │ │ │ │ └── timelinePane.ts │ │ │ │ └── common/ │ │ │ │ ├── timeline.ts │ │ │ │ └── timelineService.ts │ │ │ ├── typeHierarchy/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── typeHierarchy.css │ │ │ │ │ ├── typeHierarchy.contribution.ts │ │ │ │ │ ├── typeHierarchyPeek.ts │ │ │ │ │ └── typeHierarchyTree.ts │ │ │ │ └── common/ │ │ │ │ └── typeHierarchy.ts │ │ │ ├── update/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── releasenoteseditor.css │ │ │ │ │ ├── releaseNotesEditor.ts │ │ │ │ │ ├── update.contribution.ts │ │ │ │ │ └── update.ts │ │ │ │ └── common/ │ │ │ │ └── update.ts │ │ │ ├── url/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── externalUriResolver.ts │ │ │ │ │ ├── trustedDomainService.ts │ │ │ │ │ ├── trustedDomains.ts │ │ │ │ │ ├── trustedDomainsFileSystemProvider.ts │ │ │ │ │ ├── trustedDomainsValidator.ts │ │ │ │ │ └── url.contribution.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── trustedDomains.ts │ │ │ │ │ └── urlGlob.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── mockTrustedDomainService.ts │ │ │ │ └── trustedDomains.test.ts │ │ │ ├── userDataProfile/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── userDataProfilesEditor.css │ │ │ │ │ ├── userDataProfile.contribution.ts │ │ │ │ │ ├── userDataProfile.ts │ │ │ │ │ ├── userDataProfileActions.ts │ │ │ │ │ ├── userDataProfilesEditor.ts │ │ │ │ │ └── userDataProfilesEditorModel.ts │ │ │ │ └── common/ │ │ │ │ └── userDataProfile.ts │ │ │ ├── userDataSync/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── userDataSync.contribution.ts │ │ │ │ │ ├── userDataSync.ts │ │ │ │ │ ├── userDataSyncConflictsView.ts │ │ │ │ │ ├── userDataSyncTrigger.ts │ │ │ │ │ └── userDataSyncViews.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── userDataSync.contribution.ts │ │ │ ├── void/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── _dummyContrib.ts │ │ │ │ │ ├── _markerCheckService.ts │ │ │ │ │ ├── actionIDs.ts │ │ │ │ │ ├── aiRegexService.ts │ │ │ │ │ ├── autocompleteService.ts │ │ │ │ │ ├── chatThreadService.ts │ │ │ │ │ ├── contextGatheringService.ts │ │ │ │ │ ├── convertToLLMMessageService.ts │ │ │ │ │ ├── convertToLLMMessageWorkbenchContrib.ts │ │ │ │ │ ├── editCodeService.ts │ │ │ │ │ ├── editCodeServiceInterface.ts │ │ │ │ │ ├── extensionTransferService.ts │ │ │ │ │ ├── extensionTransferTypes.ts │ │ │ │ │ ├── fileService.ts │ │ │ │ │ ├── helperServices/ │ │ │ │ │ │ └── consistentItemService.ts │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ └── findDiffs.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── void.css │ │ │ │ │ ├── metricsPollService.ts │ │ │ │ │ ├── miscWokrbenchContrib.ts │ │ │ │ │ ├── quickEditActions.ts │ │ │ │ │ ├── react/ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── build.js │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ ├── diff/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── markdown/ │ │ │ │ │ │ │ │ ├── ApplyBlockHoverButtons.tsx │ │ │ │ │ │ │ │ └── ChatMarkdownRender.tsx │ │ │ │ │ │ │ ├── quick-edit-tsx/ │ │ │ │ │ │ │ │ ├── QuickEdit.tsx │ │ │ │ │ │ │ │ ├── QuickEditChat.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── sidebar-tsx/ │ │ │ │ │ │ │ │ ├── ErrorBoundary.tsx │ │ │ │ │ │ │ │ ├── ErrorDisplay.tsx │ │ │ │ │ │ │ │ ├── Sidebar.tsx │ │ │ │ │ │ │ │ ├── SidebarChat.tsx │ │ │ │ │ │ │ │ ├── SidebarThreadSelector.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── styles.css │ │ │ │ │ │ │ ├── util/ │ │ │ │ │ │ │ │ ├── helpers.tsx │ │ │ │ │ │ │ │ ├── inputs.tsx │ │ │ │ │ │ │ │ ├── mountFnGenerator.tsx │ │ │ │ │ │ │ │ ├── services.tsx │ │ │ │ │ │ │ │ └── useScrollbarStyles.tsx │ │ │ │ │ │ │ ├── void-editor-widgets-tsx/ │ │ │ │ │ │ │ │ ├── VoidCommandBar.tsx │ │ │ │ │ │ │ │ ├── VoidSelectionHelper.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── void-onboarding/ │ │ │ │ │ │ │ │ ├── VoidOnboarding.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── void-settings-tsx/ │ │ │ │ │ │ │ │ ├── ModelDropdown.tsx │ │ │ │ │ │ │ │ ├── Settings.tsx │ │ │ │ │ │ │ │ ├── WarningBox.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ └── void-tooltip/ │ │ │ │ │ │ │ ├── VoidTooltip.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── tailwind.config.js │ │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ │ └── tsup.config.js │ │ │ │ │ ├── sidebarActions.ts │ │ │ │ │ ├── sidebarPane.ts │ │ │ │ │ ├── terminalToolService.ts │ │ │ │ │ ├── toolsService.ts │ │ │ │ │ ├── tooltipService.ts │ │ │ │ │ ├── void.contribution.ts │ │ │ │ │ ├── voidCommandBarService.ts │ │ │ │ │ ├── voidOnboardingService.ts │ │ │ │ │ ├── voidSCMService.ts │ │ │ │ │ ├── voidSelectionHelperWidget.ts │ │ │ │ │ ├── voidSettingsPane.ts │ │ │ │ │ └── voidUpdateActions.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── chatThreadServiceTypes.ts │ │ │ │ │ ├── directoryStrService.ts │ │ │ │ │ ├── directoryStrTypes.ts │ │ │ │ │ ├── editCodeServiceTypes.ts │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ ├── colors.ts │ │ │ │ │ │ ├── extractCodeFromResult.ts │ │ │ │ │ │ ├── languageHelpers.ts │ │ │ │ │ │ ├── systemInfo.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── mcpService.ts │ │ │ │ │ ├── mcpServiceTypes.ts │ │ │ │ │ ├── metricsService.ts │ │ │ │ │ ├── modelCapabilities.ts │ │ │ │ │ ├── prompt/ │ │ │ │ │ │ └── prompts.ts │ │ │ │ │ ├── refreshModelService.ts │ │ │ │ │ ├── sendLLMMessageService.ts │ │ │ │ │ ├── sendLLMMessageTypes.ts │ │ │ │ │ ├── storageKeys.ts │ │ │ │ │ ├── toolsServiceTypes.ts │ │ │ │ │ ├── voidModelService.ts │ │ │ │ │ ├── voidSCMTypes.ts │ │ │ │ │ ├── voidSettingsService.ts │ │ │ │ │ ├── voidSettingsTypes.ts │ │ │ │ │ ├── voidUpdateService.ts │ │ │ │ │ └── voidUpdateServiceTypes.ts │ │ │ │ └── electron-main/ │ │ │ │ ├── llmMessage/ │ │ │ │ │ ├── extractGrammar.ts │ │ │ │ │ ├── sendLLMMessage.impl.ts │ │ │ │ │ └── sendLLMMessage.ts │ │ │ │ ├── mcpChannel.ts │ │ │ │ ├── metricsMainService.ts │ │ │ │ ├── sendLLMMessageChannel.ts │ │ │ │ ├── voidSCMMainService.ts │ │ │ │ └── voidUpdateMainService.ts │ │ │ ├── webview/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── overlayWebview.ts │ │ │ │ │ ├── pre/ │ │ │ │ │ │ ├── fake.html │ │ │ │ │ │ ├── index-no-csp.html │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── service-worker.js │ │ │ │ │ ├── resourceLoading.ts │ │ │ │ │ ├── themeing.ts │ │ │ │ │ ├── webview.contribution.ts │ │ │ │ │ ├── webview.ts │ │ │ │ │ ├── webview.web.contribution.ts │ │ │ │ │ ├── webviewElement.ts │ │ │ │ │ ├── webviewFindWidget.ts │ │ │ │ │ ├── webviewMessages.d.ts │ │ │ │ │ ├── webviewService.ts │ │ │ │ │ └── webviewWindowDragMonitor.ts │ │ │ │ ├── common/ │ │ │ │ │ └── webview.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── webview.contribution.ts │ │ │ │ ├── webviewCommands.ts │ │ │ │ ├── webviewElement.ts │ │ │ │ ├── webviewService.ts │ │ │ │ └── windowIgnoreMenuShortcutsManager.ts │ │ │ ├── webviewPanel/ │ │ │ │ └── browser/ │ │ │ │ ├── webviewCommands.ts │ │ │ │ ├── webviewEditor.ts │ │ │ │ ├── webviewEditorInput.ts │ │ │ │ ├── webviewEditorInputSerializer.ts │ │ │ │ ├── webviewIconManager.ts │ │ │ │ ├── webviewPanel.contribution.ts │ │ │ │ └── webviewWorkbenchService.ts │ │ │ ├── webviewView/ │ │ │ │ └── browser/ │ │ │ │ ├── webviewView.contribution.ts │ │ │ │ ├── webviewViewPane.ts │ │ │ │ └── webviewViewService.ts │ │ │ ├── welcomeBanner/ │ │ │ │ └── browser/ │ │ │ │ └── welcomeBanner.contribution.ts │ │ │ ├── welcomeDialog/ │ │ │ │ └── browser/ │ │ │ │ ├── media/ │ │ │ │ │ └── welcomeWidget.css │ │ │ │ ├── welcomeDialog.contribution.ts │ │ │ │ └── welcomeWidget.ts │ │ │ ├── welcomeGettingStarted/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── gettingStarted.contribution.ts │ │ │ │ │ ├── gettingStarted.ts │ │ │ │ │ ├── gettingStartedAccessibleView.ts │ │ │ │ │ ├── gettingStartedColors.ts │ │ │ │ │ ├── gettingStartedDetailsRenderer.ts │ │ │ │ │ ├── gettingStartedExtensionPoint.ts │ │ │ │ │ ├── gettingStartedIcons.ts │ │ │ │ │ ├── gettingStartedInput.ts │ │ │ │ │ ├── gettingStartedList.ts │ │ │ │ │ ├── gettingStartedService.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── gettingStarted.css │ │ │ │ │ └── startupPage.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── gettingStartedContent.ts │ │ │ │ │ └── media/ │ │ │ │ │ ├── empty.ts │ │ │ │ │ ├── notebookProfile.ts │ │ │ │ │ └── theme_picker.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── gettingStartedMarkdownRenderer.test.ts │ │ │ ├── welcomeViews/ │ │ │ │ └── common/ │ │ │ │ ├── newFile.contribution.ts │ │ │ │ ├── viewsWelcome.contribution.ts │ │ │ │ ├── viewsWelcomeContribution.ts │ │ │ │ └── viewsWelcomeExtensionPoint.ts │ │ │ ├── welcomeWalkthrough/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ ├── editorWalkThrough.ts │ │ │ │ │ │ └── vs_code_editor_walkthrough.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── walkThroughPart.css │ │ │ │ │ ├── walkThrough.contribution.ts │ │ │ │ │ ├── walkThroughActions.ts │ │ │ │ │ ├── walkThroughInput.ts │ │ │ │ │ └── walkThroughPart.ts │ │ │ │ └── common/ │ │ │ │ ├── walkThroughContentProvider.ts │ │ │ │ └── walkThroughUtils.ts │ │ │ ├── workspace/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── workspaceTrustEditor.css │ │ │ │ │ ├── workspace.contribution.ts │ │ │ │ │ └── workspaceTrustEditor.ts │ │ │ │ └── common/ │ │ │ │ └── workspace.ts │ │ │ └── workspaces/ │ │ │ └── browser/ │ │ │ └── workspaces.contribution.ts │ │ ├── electron-sandbox/ │ │ │ ├── actions/ │ │ │ │ ├── developerActions.ts │ │ │ │ ├── installActions.ts │ │ │ │ ├── media/ │ │ │ │ │ └── actions.css │ │ │ │ └── windowActions.ts │ │ │ ├── desktop.contribution.ts │ │ │ ├── desktop.main.ts │ │ │ ├── media/ │ │ │ │ └── window.css │ │ │ ├── parts/ │ │ │ │ ├── dialogs/ │ │ │ │ │ ├── dialog.contribution.ts │ │ │ │ │ └── dialogHandler.ts │ │ │ │ └── titlebar/ │ │ │ │ ├── menubarControl.ts │ │ │ │ └── titlebarPart.ts │ │ │ └── window.ts │ │ ├── services/ │ │ │ ├── accessibility/ │ │ │ │ ├── common/ │ │ │ │ │ └── accessibleViewInformationService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── accessibilityService.ts │ │ │ ├── accounts/ │ │ │ │ └── common/ │ │ │ │ └── defaultAccount.ts │ │ │ ├── actions/ │ │ │ │ └── common/ │ │ │ │ └── menusExtensionPoint.ts │ │ │ ├── activity/ │ │ │ │ ├── browser/ │ │ │ │ │ └── activityService.ts │ │ │ │ └── common/ │ │ │ │ └── activity.ts │ │ │ ├── aiEmbeddingVector/ │ │ │ │ └── common/ │ │ │ │ └── aiEmbeddingVectorService.ts │ │ │ ├── aiRelatedInformation/ │ │ │ │ ├── common/ │ │ │ │ │ ├── aiRelatedInformation.ts │ │ │ │ │ └── aiRelatedInformationService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── aiRelatedInformationService.test.ts │ │ │ ├── assignment/ │ │ │ │ ├── common/ │ │ │ │ │ └── assignmentService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── nullAssignmentService.ts │ │ │ ├── authentication/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── authenticationAccessService.ts │ │ │ │ │ ├── authenticationExtensionsService.ts │ │ │ │ │ ├── authenticationService.ts │ │ │ │ │ └── authenticationUsageService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── authentication.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── authenticationService.test.ts │ │ │ ├── auxiliaryWindow/ │ │ │ │ ├── browser/ │ │ │ │ │ └── auxiliaryWindowService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── auxiliaryWindowService.ts │ │ │ ├── banner/ │ │ │ │ └── browser/ │ │ │ │ └── bannerService.ts │ │ │ ├── checksum/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── checksumService.ts │ │ │ ├── clipboard/ │ │ │ │ ├── browser/ │ │ │ │ │ └── clipboardService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── clipboardService.ts │ │ │ ├── commands/ │ │ │ │ ├── common/ │ │ │ │ │ └── commandService.ts │ │ │ │ └── test/ │ │ │ │ └── common/ │ │ │ │ └── commandService.test.ts │ │ │ ├── configuration/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── configuration.ts │ │ │ │ │ └── configurationService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── configuration.ts │ │ │ │ │ ├── configurationCache.ts │ │ │ │ │ ├── configurationEditing.ts │ │ │ │ │ ├── configurationModels.ts │ │ │ │ │ ├── jsonEditing.ts │ │ │ │ │ └── jsonEditingService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── configuration.test.ts │ │ │ │ │ ├── configurationEditing.test.ts │ │ │ │ │ └── configurationService.test.ts │ │ │ │ └── common/ │ │ │ │ ├── configurationModels.test.ts │ │ │ │ └── testServices.ts │ │ │ ├── configurationResolver/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── baseConfigurationResolverService.ts │ │ │ │ │ └── configurationResolverService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── configurationResolver.ts │ │ │ │ │ ├── configurationResolverExpression.ts │ │ │ │ │ ├── configurationResolverSchema.ts │ │ │ │ │ ├── configurationResolverUtils.ts │ │ │ │ │ └── variableResolver.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── configurationResolverService.ts │ │ │ │ └── test/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── configurationResolverService.test.ts │ │ │ ├── contextmenu/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── contextmenuService.ts │ │ │ ├── decorations/ │ │ │ │ ├── browser/ │ │ │ │ │ └── decorationsService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── decorations.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── decorationsService.test.ts │ │ │ ├── dialogs/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── abstractFileDialogService.ts │ │ │ │ │ ├── fileDialogService.ts │ │ │ │ │ └── simpleFileDialog.ts │ │ │ │ ├── common/ │ │ │ │ │ └── dialogService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── fileDialogService.ts │ │ │ │ └── test/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── fileDialogService.test.ts │ │ │ ├── driver/ │ │ │ │ ├── browser/ │ │ │ │ │ └── driver.ts │ │ │ │ ├── common/ │ │ │ │ │ └── driver.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── driver.ts │ │ │ ├── editor/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── codeEditorService.ts │ │ │ │ │ ├── editorPaneService.ts │ │ │ │ │ ├── editorResolverService.ts │ │ │ │ │ └── editorService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── customEditorLabelService.ts │ │ │ │ │ ├── editorGroupColumn.ts │ │ │ │ │ ├── editorGroupFinder.ts │ │ │ │ │ ├── editorGroupsService.ts │ │ │ │ │ ├── editorPaneService.ts │ │ │ │ │ ├── editorResolverService.ts │ │ │ │ │ └── editorService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── customEditorLabelService.test.ts │ │ │ │ ├── editorGroupsService.test.ts │ │ │ │ ├── editorResolverService.test.ts │ │ │ │ ├── editorService.test.ts │ │ │ │ └── editorsObserver.test.ts │ │ │ ├── encryption/ │ │ │ │ ├── browser/ │ │ │ │ │ └── encryptionService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── encryptionService.ts │ │ │ ├── environment/ │ │ │ │ ├── browser/ │ │ │ │ │ └── environmentService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── environmentService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── environmentService.ts │ │ │ │ └── shellEnvironmentService.ts │ │ │ ├── extensionManagement/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── builtinExtensionsScannerService.ts │ │ │ │ │ ├── extensionBisect.ts │ │ │ │ │ ├── extensionEnablementService.ts │ │ │ │ │ ├── extensionGalleryManifestService.ts │ │ │ │ │ ├── extensionsProfileScannerService.ts │ │ │ │ │ └── webExtensionsScannerService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── extensionFeatures.ts │ │ │ │ │ ├── extensionFeaturesManagemetService.ts │ │ │ │ │ ├── extensionGalleryService.ts │ │ │ │ │ ├── extensionManagement.ts │ │ │ │ │ ├── extensionManagementChannelClient.ts │ │ │ │ │ ├── extensionManagementServerService.ts │ │ │ │ │ ├── extensionManagementService.ts │ │ │ │ │ ├── extensionsIcons.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── extensionManagement.css │ │ │ │ │ ├── remoteExtensionManagementService.ts │ │ │ │ │ └── webExtensionManagementService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── extensionGalleryManifestService.ts │ │ │ │ │ ├── extensionManagementServerService.ts │ │ │ │ │ ├── extensionManagementService.ts │ │ │ │ │ ├── extensionTipsService.ts │ │ │ │ │ ├── nativeExtensionManagementService.ts │ │ │ │ │ └── remoteExtensionManagementService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── extensionEnablementService.test.ts │ │ │ ├── extensionRecommendations/ │ │ │ │ └── common/ │ │ │ │ ├── extensionIgnoredRecommendationsService.ts │ │ │ │ ├── extensionRecommendations.ts │ │ │ │ └── workspaceExtensionsConfig.ts │ │ │ ├── extensions/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── extensionService.ts │ │ │ │ │ ├── extensionUrlHandler.ts │ │ │ │ │ ├── extensionsScannerService.ts │ │ │ │ │ ├── webWorkerExtensionHost.ts │ │ │ │ │ └── webWorkerFileSystemProvider.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractExtensionService.ts │ │ │ │ │ ├── extHostCustomers.ts │ │ │ │ │ ├── extensionDescriptionRegistry.ts │ │ │ │ │ ├── extensionDevOptions.ts │ │ │ │ │ ├── extensionHostEnv.ts │ │ │ │ │ ├── extensionHostKind.ts │ │ │ │ │ ├── extensionHostManager.ts │ │ │ │ │ ├── extensionHostManagers.ts │ │ │ │ │ ├── extensionHostProtocol.ts │ │ │ │ │ ├── extensionHostProxy.ts │ │ │ │ │ ├── extensionManifestPropertiesService.ts │ │ │ │ │ ├── extensionRunningLocation.ts │ │ │ │ │ ├── extensionRunningLocationTracker.ts │ │ │ │ │ ├── extensionStorageMigration.ts │ │ │ │ │ ├── extensions.ts │ │ │ │ │ ├── extensionsProposedApi.ts │ │ │ │ │ ├── extensionsRegistry.ts │ │ │ │ │ ├── extensionsUtil.ts │ │ │ │ │ ├── lazyCreateExtensionHostManager.ts │ │ │ │ │ ├── lazyPromise.ts │ │ │ │ │ ├── polyfillNestedWorker.protocol.ts │ │ │ │ │ ├── proxyIdentifier.ts │ │ │ │ │ ├── remoteConsoleUtil.ts │ │ │ │ │ ├── remoteExtensionHost.ts │ │ │ │ │ ├── rpcProtocol.ts │ │ │ │ │ └── workspaceContains.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── cachedExtensionScanner.ts │ │ │ │ │ ├── extensionHostProfiler.ts │ │ │ │ │ ├── extensionHostStarter.ts │ │ │ │ │ ├── extensionsScannerService.ts │ │ │ │ │ ├── localProcessExtensionHost.ts │ │ │ │ │ └── nativeExtensionService.ts │ │ │ │ ├── test/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── extensionService.test.ts │ │ │ │ │ │ └── extensionStorageMigration.test.ts │ │ │ │ │ └── common/ │ │ │ │ │ ├── extensionDescriptionRegistry.test.ts │ │ │ │ │ ├── extensionManifestPropertiesService.test.ts │ │ │ │ │ └── rpcProtocol.test.ts │ │ │ │ └── worker/ │ │ │ │ ├── polyfillNestedWorker.ts │ │ │ │ └── webWorkerExtensionHostIframe.html │ │ │ ├── files/ │ │ │ │ ├── browser/ │ │ │ │ │ └── elevatedFileService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── elevatedFileService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── diskFileSystemProvider.ts │ │ │ │ ├── elevatedFileService.ts │ │ │ │ └── watcherClient.ts │ │ │ ├── filesConfiguration/ │ │ │ │ └── common/ │ │ │ │ └── filesConfigurationService.ts │ │ │ ├── history/ │ │ │ │ ├── browser/ │ │ │ │ │ └── historyService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── history.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── historyService.test.ts │ │ │ ├── host/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserHostService.ts │ │ │ │ │ └── host.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── nativeHostService.ts │ │ │ ├── integrity/ │ │ │ │ ├── browser/ │ │ │ │ │ └── integrityService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── integrity.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── integrityService.ts │ │ │ ├── keybinding/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── keybindingService.ts │ │ │ │ │ ├── keyboardLayoutService.ts │ │ │ │ │ ├── keyboardLayouts/ │ │ │ │ │ │ ├── _.contribution.ts │ │ │ │ │ │ ├── cz.win.ts │ │ │ │ │ │ ├── de-swiss.win.ts │ │ │ │ │ │ ├── de.darwin.ts │ │ │ │ │ │ ├── de.linux.ts │ │ │ │ │ │ ├── de.win.ts │ │ │ │ │ │ ├── dk.win.ts │ │ │ │ │ │ ├── dvorak.darwin.ts │ │ │ │ │ │ ├── en-belgian.win.ts │ │ │ │ │ │ ├── en-ext.darwin.ts │ │ │ │ │ │ ├── en-in.win.ts │ │ │ │ │ │ ├── en-intl.darwin.ts │ │ │ │ │ │ ├── en-intl.win.ts │ │ │ │ │ │ ├── en-uk.darwin.ts │ │ │ │ │ │ ├── en-uk.win.ts │ │ │ │ │ │ ├── en.darwin.ts │ │ │ │ │ │ ├── en.linux.ts │ │ │ │ │ │ ├── en.win.ts │ │ │ │ │ │ ├── es-latin.win.ts │ │ │ │ │ │ ├── es.darwin.ts │ │ │ │ │ │ ├── es.linux.ts │ │ │ │ │ │ ├── es.win.ts │ │ │ │ │ │ ├── fr.darwin.ts │ │ │ │ │ │ ├── fr.linux.ts │ │ │ │ │ │ ├── fr.win.ts │ │ │ │ │ │ ├── hu.win.ts │ │ │ │ │ │ ├── it.darwin.ts │ │ │ │ │ │ ├── it.win.ts │ │ │ │ │ │ ├── jp-roman.darwin.ts │ │ │ │ │ │ ├── jp.darwin.ts │ │ │ │ │ │ ├── ko.darwin.ts │ │ │ │ │ │ ├── layout.contribution.darwin.ts │ │ │ │ │ │ ├── layout.contribution.linux.ts │ │ │ │ │ │ ├── layout.contribution.win.ts │ │ │ │ │ │ ├── no.win.ts │ │ │ │ │ │ ├── pl.darwin.ts │ │ │ │ │ │ ├── pl.win.ts │ │ │ │ │ │ ├── pt-br.win.ts │ │ │ │ │ │ ├── pt.darwin.ts │ │ │ │ │ │ ├── pt.win.ts │ │ │ │ │ │ ├── ru.darwin.ts │ │ │ │ │ │ ├── ru.linux.ts │ │ │ │ │ │ ├── ru.win.ts │ │ │ │ │ │ ├── sv.darwin.ts │ │ │ │ │ │ ├── sv.win.ts │ │ │ │ │ │ ├── thai.win.ts │ │ │ │ │ │ ├── tr.win.ts │ │ │ │ │ │ └── zh-hans.darwin.ts │ │ │ │ │ ├── navigatorKeyboard.ts │ │ │ │ │ └── unboundCommands.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── fallbackKeyboardMapper.ts │ │ │ │ │ ├── keybindingEditing.ts │ │ │ │ │ ├── keybindingIO.ts │ │ │ │ │ ├── keymapInfo.ts │ │ │ │ │ ├── macLinuxKeyboardMapper.ts │ │ │ │ │ └── windowsKeyboardMapper.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── nativeKeyboardLayout.ts │ │ │ │ │ └── nativeKeyboardLayoutService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserKeyboardMapper.test.ts │ │ │ │ │ ├── keybindingEditing.test.ts │ │ │ │ │ └── keybindingIO.test.ts │ │ │ │ └── node/ │ │ │ │ ├── fallbackKeyboardMapper.test.ts │ │ │ │ ├── keyboardMapperTestUtils.ts │ │ │ │ ├── linux_de_ch.js │ │ │ │ ├── linux_de_ch.txt │ │ │ │ ├── linux_en_uk.js │ │ │ │ ├── linux_en_uk.txt │ │ │ │ ├── linux_en_us.js │ │ │ │ ├── linux_en_us.txt │ │ │ │ ├── linux_ru.js │ │ │ │ ├── linux_ru.txt │ │ │ │ ├── macLinuxKeyboardMapper.test.ts │ │ │ │ ├── mac_de_ch.js │ │ │ │ ├── mac_de_ch.txt │ │ │ │ ├── mac_en_us.js │ │ │ │ ├── mac_en_us.txt │ │ │ │ ├── mac_zh_hant.js │ │ │ │ ├── mac_zh_hant.txt │ │ │ │ ├── mac_zh_hant2.js │ │ │ │ ├── mac_zh_hant2.txt │ │ │ │ ├── win_de_ch.js │ │ │ │ ├── win_de_ch.txt │ │ │ │ ├── win_en_us.js │ │ │ │ ├── win_en_us.txt │ │ │ │ ├── win_por_ptb.js │ │ │ │ ├── win_por_ptb.txt │ │ │ │ ├── win_ru.js │ │ │ │ ├── win_ru.txt │ │ │ │ └── windowsKeyboardMapper.test.ts │ │ │ ├── label/ │ │ │ │ ├── common/ │ │ │ │ │ └── labelService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── label.test.ts │ │ │ │ └── common/ │ │ │ │ └── mockLabelService.ts │ │ │ ├── language/ │ │ │ │ └── common/ │ │ │ │ └── languageService.ts │ │ │ ├── languageDetection/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── languageDetectionWebWorker.ts │ │ │ │ │ ├── languageDetectionWebWorkerMain.ts │ │ │ │ │ ├── languageDetectionWorker.protocol.ts │ │ │ │ │ └── languageDetectionWorkerServiceImpl.ts │ │ │ │ └── common/ │ │ │ │ └── languageDetectionWorkerService.ts │ │ │ ├── languageStatus/ │ │ │ │ └── common/ │ │ │ │ └── languageStatusService.ts │ │ │ ├── layout/ │ │ │ │ └── browser/ │ │ │ │ └── layoutService.ts │ │ │ ├── lifecycle/ │ │ │ │ ├── browser/ │ │ │ │ │ └── lifecycleService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── lifecycle.ts │ │ │ │ │ └── lifecycleService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── lifecycleService.ts │ │ │ │ └── test/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── lifecycleService.test.ts │ │ │ ├── localization/ │ │ │ │ ├── browser/ │ │ │ │ │ └── localeService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── locale.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── languagePackService.ts │ │ │ │ └── localeService.ts │ │ │ ├── log/ │ │ │ │ ├── common/ │ │ │ │ │ └── logConstants.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── logService.ts │ │ │ ├── menubar/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── menubarService.ts │ │ │ ├── model/ │ │ │ │ └── common/ │ │ │ │ └── modelService.ts │ │ │ ├── notebook/ │ │ │ │ └── common/ │ │ │ │ └── notebookDocumentService.ts │ │ │ ├── notification/ │ │ │ │ └── common/ │ │ │ │ └── notificationService.ts │ │ │ ├── outline/ │ │ │ │ └── browser/ │ │ │ │ ├── outline.ts │ │ │ │ └── outlineService.ts │ │ │ ├── output/ │ │ │ │ └── common/ │ │ │ │ ├── delayedLogChannel.ts │ │ │ │ └── output.ts │ │ │ ├── panecomposite/ │ │ │ │ └── browser/ │ │ │ │ └── panecomposite.ts │ │ │ ├── path/ │ │ │ │ ├── browser/ │ │ │ │ │ └── pathService.ts │ │ │ │ ├── common/ │ │ │ │ │ └── pathService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── pathService.ts │ │ │ ├── policies/ │ │ │ │ └── common/ │ │ │ │ ├── accountPolicyService.ts │ │ │ │ └── multiplexPolicyService.ts │ │ │ ├── preferences/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── keybindingsEditorInput.ts │ │ │ │ │ ├── keybindingsEditorModel.ts │ │ │ │ │ └── preferencesService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── preferences.ts │ │ │ │ │ ├── preferencesEditorInput.ts │ │ │ │ │ ├── preferencesModels.ts │ │ │ │ │ └── preferencesValidation.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── keybindingsEditorModel.test.ts │ │ │ │ │ └── preferencesService.test.ts │ │ │ │ └── common/ │ │ │ │ └── preferencesValidation.test.ts │ │ │ ├── progress/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── progressService.css │ │ │ │ │ ├── progressIndicator.ts │ │ │ │ │ └── progressService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── progressIndicator.test.ts │ │ │ ├── quickinput/ │ │ │ │ └── browser/ │ │ │ │ └── quickInputService.ts │ │ │ ├── remote/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserRemoteResourceHandler.ts │ │ │ │ │ └── remoteAgentService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractRemoteAgentService.ts │ │ │ │ │ ├── remoteAgentEnvironmentChannel.ts │ │ │ │ │ ├── remoteAgentService.ts │ │ │ │ │ ├── remoteExplorerService.ts │ │ │ │ │ ├── remoteExtensionsScanner.ts │ │ │ │ │ ├── remoteFileSystemProviderClient.ts │ │ │ │ │ └── tunnelModel.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── remoteAgentService.ts │ │ │ ├── request/ │ │ │ │ ├── browser/ │ │ │ │ │ └── requestService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── requestService.ts │ │ │ ├── search/ │ │ │ │ ├── browser/ │ │ │ │ │ └── searchService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── fileSearchManager.ts │ │ │ │ │ ├── folderQuerySearchTree.ts │ │ │ │ │ ├── getFileResults.ts │ │ │ │ │ ├── ignoreFile.ts │ │ │ │ │ ├── localFileSearchWorkerTypes.ts │ │ │ │ │ ├── queryBuilder.ts │ │ │ │ │ ├── replace.ts │ │ │ │ │ ├── search.ts │ │ │ │ │ ├── searchExtConversionTypes.ts │ │ │ │ │ ├── searchExtTypes.ts │ │ │ │ │ ├── searchExtTypesInternal.ts │ │ │ │ │ ├── searchHelpers.ts │ │ │ │ │ ├── searchService.ts │ │ │ │ │ └── textSearchManager.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── searchService.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── fileSearch.ts │ │ │ │ │ ├── rawSearchService.ts │ │ │ │ │ ├── ripgrepFileSearch.ts │ │ │ │ │ ├── ripgrepSearchProvider.ts │ │ │ │ │ ├── ripgrepSearchUtils.ts │ │ │ │ │ ├── ripgrepTextSearchEngine.ts │ │ │ │ │ ├── textSearchAdapter.ts │ │ │ │ │ └── textSearchManager.ts │ │ │ │ ├── test/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── queryBuilder.test.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── folderQuerySearchTree.test.ts │ │ │ │ │ │ ├── ignoreFile.test.ts │ │ │ │ │ │ ├── queryBuilder.test.ts │ │ │ │ │ │ ├── replace.test.ts │ │ │ │ │ │ ├── search.test.ts │ │ │ │ │ │ └── searchHelpers.test.ts │ │ │ │ │ └── node/ │ │ │ │ │ ├── fileSearch.integrationTest.ts │ │ │ │ │ ├── fixtures/ │ │ │ │ │ │ ├── binary.wuff │ │ │ │ │ │ ├── examples/ │ │ │ │ │ │ │ ├── NullPoinderException.js │ │ │ │ │ │ │ ├── company.js │ │ │ │ │ │ │ ├── employee.js │ │ │ │ │ │ │ ├── small.js │ │ │ │ │ │ │ └── subfolder/ │ │ │ │ │ │ │ ├── anotherfolder/ │ │ │ │ │ │ │ │ └── anotherfile.txt │ │ │ │ │ │ │ └── subfile.txt │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── more/ │ │ │ │ │ │ │ └── file.txt │ │ │ │ │ │ ├── site.css │ │ │ │ │ │ ├── site.less │ │ │ │ │ │ ├── some_utf16be.css │ │ │ │ │ │ ├── some_utf16le.css │ │ │ │ │ │ └── üm laut汉语/ │ │ │ │ │ │ └── 汉语.txt │ │ │ │ │ ├── fixtures2/ │ │ │ │ │ │ └── 36438/ │ │ │ │ │ │ ├── modules/ │ │ │ │ │ │ │ └── do-not-find.txt │ │ │ │ │ │ └── more/ │ │ │ │ │ │ └── modules/ │ │ │ │ │ │ └── find.txt │ │ │ │ │ ├── rawSearchService.integrationTest.ts │ │ │ │ │ ├── ripgrepFileSearch.test.ts │ │ │ │ │ ├── ripgrepTextSearchEngineUtils.test.ts │ │ │ │ │ ├── search.integrationTest.ts │ │ │ │ │ ├── textSearch.integrationTest.ts │ │ │ │ │ └── textSearchManager.test.ts │ │ │ │ └── worker/ │ │ │ │ ├── localFileSearch.ts │ │ │ │ └── localFileSearchMain.ts │ │ │ ├── secrets/ │ │ │ │ ├── browser/ │ │ │ │ │ └── secretStorageService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── secretStorageService.ts │ │ │ ├── sharedProcess/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── sharedProcessService.ts │ │ │ ├── statusbar/ │ │ │ │ └── browser/ │ │ │ │ └── statusbar.ts │ │ │ ├── storage/ │ │ │ │ ├── browser/ │ │ │ │ │ └── storageService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── storageService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── storageService.test.ts │ │ │ ├── suggest/ │ │ │ │ └── browser/ │ │ │ │ ├── media/ │ │ │ │ │ └── suggest.css │ │ │ │ ├── simpleCompletionItem.ts │ │ │ │ ├── simpleCompletionModel.ts │ │ │ │ ├── simpleSuggestWidget.ts │ │ │ │ ├── simpleSuggestWidgetDetails.ts │ │ │ │ └── simpleSuggestWidgetRenderer.ts │ │ │ ├── telemetry/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── telemetryService.ts │ │ │ │ │ └── workbenchCommonProperties.ts │ │ │ │ ├── common/ │ │ │ │ │ └── workbenchCommonProperties.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── telemetryService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── commonProperties.test.ts │ │ │ │ └── node/ │ │ │ │ └── commonProperties.test.ts │ │ │ ├── terminal/ │ │ │ │ └── common/ │ │ │ │ └── embedderTerminalService.ts │ │ │ ├── textMate/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── arrayOperation.ts │ │ │ │ │ ├── backgroundTokenization/ │ │ │ │ │ │ ├── textMateWorkerTokenizerController.ts │ │ │ │ │ │ ├── threadedBackgroundTokenizerFactory.ts │ │ │ │ │ │ └── worker/ │ │ │ │ │ │ ├── textMateTokenizationWorker.worker.ts │ │ │ │ │ │ ├── textMateTokenizationWorker.workerMain.ts │ │ │ │ │ │ ├── textMateWorkerHost.ts │ │ │ │ │ │ └── textMateWorkerTokenizer.ts │ │ │ │ │ ├── textMateTokenizationFeature.contribution.ts │ │ │ │ │ ├── textMateTokenizationFeature.ts │ │ │ │ │ ├── textMateTokenizationFeatureImpl.ts │ │ │ │ │ └── tokenizationSupport/ │ │ │ │ │ ├── textMateTokenizationSupport.ts │ │ │ │ │ └── tokenizationSupportWithLineLimit.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── TMGrammarFactory.ts │ │ │ │ │ ├── TMGrammars.ts │ │ │ │ │ ├── TMHelper.ts │ │ │ │ │ ├── TMScopeRegistry.ts │ │ │ │ │ └── cgmanifest.json │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── arrayOperation.test.ts │ │ │ ├── textfile/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserTextFileService.ts │ │ │ │ │ └── textFileService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── encoding.ts │ │ │ │ │ ├── textEditorService.ts │ │ │ │ │ ├── textFileEditorModel.ts │ │ │ │ │ ├── textFileEditorModelManager.ts │ │ │ │ │ ├── textFileSaveParticipant.ts │ │ │ │ │ └── textfiles.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ └── nativeTextFileService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserTextFileService.io.test.ts │ │ │ │ │ ├── textEditorService.test.ts │ │ │ │ │ ├── textFileEditorModel.integrationTest.ts │ │ │ │ │ ├── textFileEditorModel.test.ts │ │ │ │ │ ├── textFileEditorModelManager.test.ts │ │ │ │ │ └── textFileService.test.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── fixtures/ │ │ │ │ │ │ └── files.ts │ │ │ │ │ └── textFileService.io.test.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── nativeTextFileService.io.test.ts │ │ │ │ │ └── nativeTextFileService.test.ts │ │ │ │ └── node/ │ │ │ │ └── encoding/ │ │ │ │ ├── encoding.integrationTest.ts │ │ │ │ ├── encoding.test.ts │ │ │ │ └── fixtures/ │ │ │ │ ├── empty.txt │ │ │ │ ├── issue_102202.txt │ │ │ │ ├── some.cp1252.txt │ │ │ │ ├── some.css.qwoff │ │ │ │ ├── some.png.txt │ │ │ │ ├── some.qwoff.txt │ │ │ │ ├── some.shiftjis.1.txt │ │ │ │ ├── some.shiftjis.txt │ │ │ │ ├── some_ansi.css │ │ │ │ ├── some_file.css │ │ │ │ ├── some_gbk.txt │ │ │ │ ├── some_utf16be.css │ │ │ │ ├── some_utf16le.css │ │ │ │ ├── some_utf8.css │ │ │ │ ├── utf16_be_nobom.txt │ │ │ │ └── utf16_le_nobom.txt │ │ │ ├── textmodelResolver/ │ │ │ │ ├── common/ │ │ │ │ │ └── textModelResolverService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ └── textModelResolverService.test.ts │ │ │ ├── textresourceProperties/ │ │ │ │ └── common/ │ │ │ │ └── textResourcePropertiesService.ts │ │ │ ├── themes/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── browserHostColorSchemeService.ts │ │ │ │ │ ├── fileIconThemeData.ts │ │ │ │ │ ├── productIconThemeData.ts │ │ │ │ │ └── workbenchThemeService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── colorExtensionPoint.ts │ │ │ │ │ ├── colorThemeData.ts │ │ │ │ │ ├── colorThemeSchema.ts │ │ │ │ │ ├── fileIconThemeSchema.ts │ │ │ │ │ ├── hostColorSchemeService.ts │ │ │ │ │ ├── iconExtensionPoint.ts │ │ │ │ │ ├── plistParser.ts │ │ │ │ │ ├── productIconThemeSchema.ts │ │ │ │ │ ├── textMateScopeMatcher.ts │ │ │ │ │ ├── themeCompatibility.ts │ │ │ │ │ ├── themeConfiguration.ts │ │ │ │ │ ├── themeExtensionPoints.ts │ │ │ │ │ ├── tokenClassificationExtensionPoint.ts │ │ │ │ │ └── workbenchThemeService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── nativeHostColorSchemeService.ts │ │ │ │ │ └── themes.contribution.ts │ │ │ │ └── test/ │ │ │ │ └── node/ │ │ │ │ ├── color-theme.json │ │ │ │ └── tokenStyleResolving.test.ts │ │ │ ├── timer/ │ │ │ │ ├── browser/ │ │ │ │ │ └── timerService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── timerService.ts │ │ │ ├── title/ │ │ │ │ ├── browser/ │ │ │ │ │ └── titleService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── titleService.ts │ │ │ ├── treeSitter/ │ │ │ │ └── browser/ │ │ │ │ ├── treeSitterCodeEditors.ts │ │ │ │ ├── treeSitterTokenizationFeature.contribution.ts │ │ │ │ └── treeSitterTokenizationFeature.ts │ │ │ ├── tunnel/ │ │ │ │ ├── browser/ │ │ │ │ │ └── tunnelService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── tunnelService.ts │ │ │ ├── untitled/ │ │ │ │ ├── common/ │ │ │ │ │ ├── untitledTextEditorHandler.ts │ │ │ │ │ ├── untitledTextEditorInput.ts │ │ │ │ │ ├── untitledTextEditorModel.ts │ │ │ │ │ └── untitledTextEditorService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── untitledTextEditor.integrationTest.ts │ │ │ │ └── untitledTextEditor.test.ts │ │ │ ├── update/ │ │ │ │ ├── browser/ │ │ │ │ │ └── updateService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── updateService.ts │ │ │ ├── url/ │ │ │ │ ├── browser/ │ │ │ │ │ └── urlService.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ └── urlService.ts │ │ │ ├── userActivity/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── domActivityTracker.ts │ │ │ │ │ └── userActivityBrowser.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── userActivityRegistry.ts │ │ │ │ │ └── userActivityService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ └── domActivityTracker.test.ts │ │ │ │ └── common/ │ │ │ │ └── userActivityService.test.ts │ │ │ ├── userData/ │ │ │ │ └── browser/ │ │ │ │ └── userDataInit.ts │ │ │ ├── userDataProfile/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── extensionsResource.ts │ │ │ │ │ ├── globalStateResource.ts │ │ │ │ │ ├── iconSelectBox.ts │ │ │ │ │ ├── keybindingsResource.ts │ │ │ │ │ ├── media/ │ │ │ │ │ │ └── userDataProfileView.css │ │ │ │ │ ├── settingsResource.ts │ │ │ │ │ ├── snippetsResource.ts │ │ │ │ │ ├── tasksResource.ts │ │ │ │ │ ├── userDataProfileImportExportService.ts │ │ │ │ │ ├── userDataProfileInit.ts │ │ │ │ │ ├── userDataProfileManagement.ts │ │ │ │ │ └── userDataProfileStorageService.ts │ │ │ │ └── common/ │ │ │ │ ├── remoteUserDataProfiles.ts │ │ │ │ ├── userDataProfile.ts │ │ │ │ ├── userDataProfileIcons.ts │ │ │ │ └── userDataProfileService.ts │ │ │ ├── userDataSync/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── userDataSyncEnablementService.ts │ │ │ │ │ ├── userDataSyncInit.ts │ │ │ │ │ ├── userDataSyncWorkbenchService.ts │ │ │ │ │ └── webUserDataSyncEnablementService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── userDataSync.ts │ │ │ │ │ └── userDataSyncUtil.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── userDataAutoSyncService.ts │ │ │ │ └── userDataSyncService.ts │ │ │ ├── utilityProcess/ │ │ │ │ └── electron-sandbox/ │ │ │ │ └── utilityProcessWorkerWorkbenchService.ts │ │ │ ├── views/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── viewDescriptorService.ts │ │ │ │ │ └── viewsService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── viewContainerModel.ts │ │ │ │ │ └── viewsService.ts │ │ │ │ └── test/ │ │ │ │ └── browser/ │ │ │ │ ├── viewContainerModel.test.ts │ │ │ │ └── viewDescriptorService.test.ts │ │ │ ├── workingCopy/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── workingCopyBackupService.ts │ │ │ │ │ ├── workingCopyBackupTracker.ts │ │ │ │ │ └── workingCopyHistoryService.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── abstractFileWorkingCopyManager.ts │ │ │ │ │ ├── fileWorkingCopy.ts │ │ │ │ │ ├── fileWorkingCopyManager.ts │ │ │ │ │ ├── resourceWorkingCopy.ts │ │ │ │ │ ├── storedFileWorkingCopy.ts │ │ │ │ │ ├── storedFileWorkingCopyManager.ts │ │ │ │ │ ├── storedFileWorkingCopySaveParticipant.ts │ │ │ │ │ ├── untitledFileWorkingCopy.ts │ │ │ │ │ ├── untitledFileWorkingCopyManager.ts │ │ │ │ │ ├── workingCopy.ts │ │ │ │ │ ├── workingCopyBackup.ts │ │ │ │ │ ├── workingCopyBackupService.ts │ │ │ │ │ ├── workingCopyBackupTracker.ts │ │ │ │ │ ├── workingCopyEditorService.ts │ │ │ │ │ ├── workingCopyFileOperationParticipant.ts │ │ │ │ │ ├── workingCopyFileService.ts │ │ │ │ │ ├── workingCopyHistory.ts │ │ │ │ │ ├── workingCopyHistoryService.ts │ │ │ │ │ ├── workingCopyHistoryTracker.ts │ │ │ │ │ └── workingCopyService.ts │ │ │ │ ├── electron-sandbox/ │ │ │ │ │ ├── workingCopyBackupService.ts │ │ │ │ │ ├── workingCopyBackupTracker.ts │ │ │ │ │ └── workingCopyHistoryService.ts │ │ │ │ └── test/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── fileWorkingCopyManager.test.ts │ │ │ │ │ ├── resourceWorkingCopy.test.ts │ │ │ │ │ ├── storedFileWorkingCopy.test.ts │ │ │ │ │ ├── storedFileWorkingCopyManager.test.ts │ │ │ │ │ ├── untitledFileWorkingCopy.test.ts │ │ │ │ │ ├── untitledFileWorkingCopyManager.test.ts │ │ │ │ │ ├── untitledScratchpadWorkingCopy.test.ts │ │ │ │ │ ├── workingCopyBackupTracker.test.ts │ │ │ │ │ ├── workingCopyEditorService.test.ts │ │ │ │ │ └── workingCopyFileService.test.ts │ │ │ │ ├── common/ │ │ │ │ │ └── workingCopyService.test.ts │ │ │ │ └── electron-sandbox/ │ │ │ │ ├── workingCopyBackupService.test.ts │ │ │ │ ├── workingCopyBackupTracker.test.ts │ │ │ │ ├── workingCopyHistoryService.test.ts │ │ │ │ └── workingCopyHistoryTracker.test.ts │ │ │ └── workspaces/ │ │ │ ├── browser/ │ │ │ │ ├── abstractWorkspaceEditingService.ts │ │ │ │ ├── workspaceEditingService.ts │ │ │ │ ├── workspaceTrustEditorInput.ts │ │ │ │ ├── workspaces.ts │ │ │ │ └── workspacesService.ts │ │ │ ├── common/ │ │ │ │ ├── canonicalUriService.ts │ │ │ │ ├── editSessionIdentityService.ts │ │ │ │ ├── workspaceEditing.ts │ │ │ │ ├── workspaceIdentityService.ts │ │ │ │ ├── workspaceTrust.ts │ │ │ │ └── workspaceUtils.ts │ │ │ ├── electron-sandbox/ │ │ │ │ ├── workspaceEditingService.ts │ │ │ │ └── workspacesService.ts │ │ │ └── test/ │ │ │ ├── browser/ │ │ │ │ └── workspaces.test.ts │ │ │ └── common/ │ │ │ └── workspaceTrust.test.ts │ │ ├── test/ │ │ │ ├── browser/ │ │ │ │ ├── codeeditor.test.ts │ │ │ │ ├── contributions.test.ts │ │ │ │ ├── part.test.ts │ │ │ │ ├── parts/ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ ├── breadcrumbModel.test.ts │ │ │ │ │ │ ├── diffEditorInput.test.ts │ │ │ │ │ │ ├── editor.test.ts │ │ │ │ │ │ ├── editorCommandsContext.test.ts │ │ │ │ │ │ ├── editorDiffModel.test.ts │ │ │ │ │ │ ├── editorGroupModel.test.ts │ │ │ │ │ │ ├── editorInput.test.ts │ │ │ │ │ │ ├── editorModel.test.ts │ │ │ │ │ │ ├── editorPane.test.ts │ │ │ │ │ │ ├── filteredEditorGroupModel.test.ts │ │ │ │ │ │ ├── resourceEditorInput.test.ts │ │ │ │ │ │ ├── sideBySideEditorInput.test.ts │ │ │ │ │ │ ├── textEditorPane.test.ts │ │ │ │ │ │ └── textResourceEditorInput.test.ts │ │ │ │ │ └── statusbar/ │ │ │ │ │ └── statusbarModel.test.ts │ │ │ │ ├── quickAccess.test.ts │ │ │ │ ├── treeview.test.ts │ │ │ │ ├── viewlet.test.ts │ │ │ │ ├── webview.test.ts │ │ │ │ ├── window.test.ts │ │ │ │ └── workbenchTestServices.ts │ │ │ ├── common/ │ │ │ │ ├── memento.test.ts │ │ │ │ ├── notifications.test.ts │ │ │ │ ├── resources.test.ts │ │ │ │ ├── utils.ts │ │ │ │ └── workbenchTestServices.ts │ │ │ ├── electron-main/ │ │ │ │ └── treeSitterTokenizationFeature.test.ts │ │ │ └── electron-sandbox/ │ │ │ ├── resolveExternal.test.ts │ │ │ └── workbenchTestServices.ts │ │ ├── workbench.common.main.ts │ │ ├── workbench.desktop.main.ts │ │ ├── workbench.web.main.internal.ts │ │ └── workbench.web.main.ts │ └── vscode-dts/ │ ├── README.md │ ├── vscode.d.ts │ ├── vscode.proposed.activeComment.d.ts │ ├── vscode.proposed.aiRelatedInformation.d.ts │ ├── vscode.proposed.aiTextSearchProvider.d.ts │ ├── vscode.proposed.authLearnMore.d.ts │ ├── vscode.proposed.authSession.d.ts │ ├── vscode.proposed.canonicalUriProvider.d.ts │ ├── vscode.proposed.chatEditing.d.ts │ ├── vscode.proposed.chatParticipantAdditions.d.ts │ ├── vscode.proposed.chatParticipantPrivate.d.ts │ ├── vscode.proposed.chatProvider.d.ts │ ├── vscode.proposed.chatReferenceBinaryData.d.ts │ ├── vscode.proposed.chatReferenceDiagnostic.d.ts │ ├── vscode.proposed.chatStatusItem.d.ts │ ├── vscode.proposed.chatTab.d.ts │ ├── vscode.proposed.codeActionAI.d.ts │ ├── vscode.proposed.codeActionRanges.d.ts │ ├── vscode.proposed.codiconDecoration.d.ts │ ├── vscode.proposed.commentReactor.d.ts │ ├── vscode.proposed.commentReveal.d.ts │ ├── vscode.proposed.commentThreadApplicability.d.ts │ ├── vscode.proposed.commentingRangeHint.d.ts │ ├── vscode.proposed.commentsDraftState.d.ts │ ├── vscode.proposed.contribAccessibilityHelpContent.d.ts │ ├── vscode.proposed.contribCommentEditorActionsMenu.d.ts │ ├── vscode.proposed.contribCommentPeekContext.d.ts │ ├── vscode.proposed.contribCommentThreadAdditionalMenu.d.ts │ ├── vscode.proposed.contribCommentsViewThreadMenus.d.ts │ ├── vscode.proposed.contribDebugCreateConfiguration.d.ts │ ├── vscode.proposed.contribDiffEditorGutterToolBarMenus.d.ts │ ├── vscode.proposed.contribEditSessions.d.ts │ ├── vscode.proposed.contribEditorContentMenu.d.ts │ ├── vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts │ ├── vscode.proposed.contribMenuBarHome.d.ts │ ├── vscode.proposed.contribMergeEditorMenus.d.ts │ ├── vscode.proposed.contribMultiDiffEditorMenus.d.ts │ ├── vscode.proposed.contribNotebookStaticPreloads.d.ts │ ├── vscode.proposed.contribRemoteHelp.d.ts │ ├── vscode.proposed.contribShareMenu.d.ts │ ├── vscode.proposed.contribSourceControlHistoryItemMenu.d.ts │ ├── vscode.proposed.contribSourceControlHistoryTitleMenu.d.ts │ ├── vscode.proposed.contribSourceControlInputBoxMenu.d.ts │ ├── vscode.proposed.contribSourceControlTitleMenu.d.ts │ ├── vscode.proposed.contribStatusBarItems.d.ts │ ├── vscode.proposed.contribViewContainerTitle.d.ts │ ├── vscode.proposed.contribViewsRemote.d.ts │ ├── vscode.proposed.contribViewsWelcome.d.ts │ ├── vscode.proposed.customEditorMove.d.ts │ ├── vscode.proposed.debugVisualization.d.ts │ ├── vscode.proposed.defaultChatParticipant.d.ts │ ├── vscode.proposed.diffCommand.d.ts │ ├── vscode.proposed.diffContentOptions.d.ts │ ├── vscode.proposed.documentFiltersExclusive.d.ts │ ├── vscode.proposed.editSessionIdentityProvider.d.ts │ ├── vscode.proposed.editorHoverVerbosityLevel.d.ts │ ├── vscode.proposed.editorInsets.d.ts │ ├── vscode.proposed.embeddings.d.ts │ ├── vscode.proposed.extensionRuntime.d.ts │ ├── vscode.proposed.extensionsAny.d.ts │ ├── vscode.proposed.externalUriOpener.d.ts │ ├── vscode.proposed.fileSearchProvider.d.ts │ ├── vscode.proposed.fileSearchProvider2.d.ts │ ├── vscode.proposed.findFiles2.d.ts │ ├── vscode.proposed.findTextInFiles.d.ts │ ├── vscode.proposed.findTextInFiles2.d.ts │ ├── vscode.proposed.fsChunks.d.ts │ ├── vscode.proposed.idToken.d.ts │ ├── vscode.proposed.inlineCompletionsAdditions.d.ts │ ├── vscode.proposed.inlineEdit.d.ts │ ├── vscode.proposed.interactive.d.ts │ ├── vscode.proposed.interactiveWindow.d.ts │ ├── vscode.proposed.ipc.d.ts │ ├── vscode.proposed.languageModelCapabilities.d.ts │ ├── vscode.proposed.languageModelDataPart.d.ts │ ├── vscode.proposed.languageModelSystem.d.ts │ ├── vscode.proposed.languageModelToolsForAgent.d.ts │ ├── vscode.proposed.languageStatusText.d.ts │ ├── vscode.proposed.mappedEditsProvider.d.ts │ ├── vscode.proposed.mcpConfigurationProvider.d.ts │ ├── vscode.proposed.multiDocumentHighlightProvider.d.ts │ ├── vscode.proposed.nativeWindowHandle.d.ts │ ├── vscode.proposed.newSymbolNamesProvider.d.ts │ ├── vscode.proposed.notebookCellExecution.d.ts │ ├── vscode.proposed.notebookCellExecutionState.d.ts │ ├── vscode.proposed.notebookControllerAffinityHidden.d.ts │ ├── vscode.proposed.notebookDeprecated.d.ts │ ├── vscode.proposed.notebookExecution.d.ts │ ├── vscode.proposed.notebookKernelSource.d.ts │ ├── vscode.proposed.notebookLiveShare.d.ts │ ├── vscode.proposed.notebookMessaging.d.ts │ ├── vscode.proposed.notebookMime.d.ts │ ├── vscode.proposed.notebookReplDocument.d.ts │ ├── vscode.proposed.notebookVariableProvider.d.ts │ ├── vscode.proposed.portsAttributes.d.ts │ ├── vscode.proposed.profileContentHandlers.d.ts │ ├── vscode.proposed.quickDiffProvider.d.ts │ ├── vscode.proposed.quickInputButtonLocation.d.ts │ ├── vscode.proposed.quickPickItemTooltip.d.ts │ ├── vscode.proposed.quickPickSortByLabel.d.ts │ ├── vscode.proposed.resolvers.d.ts │ ├── vscode.proposed.scmActionButton.d.ts │ ├── vscode.proposed.scmHistoryProvider.d.ts │ ├── vscode.proposed.scmMultiDiffEditor.d.ts │ ├── vscode.proposed.scmSelectedProvider.d.ts │ ├── vscode.proposed.scmTextDocument.d.ts │ ├── vscode.proposed.scmValidation.d.ts │ ├── vscode.proposed.shareProvider.d.ts │ ├── vscode.proposed.speech.d.ts │ ├── vscode.proposed.statusBarItemTooltip.d.ts │ ├── vscode.proposed.tabInputMultiDiff.d.ts │ ├── vscode.proposed.tabInputTextMerge.d.ts │ ├── vscode.proposed.taskPresentationGroup.d.ts │ ├── vscode.proposed.taskProblemMatcherStatus.d.ts │ ├── vscode.proposed.telemetry.d.ts │ ├── vscode.proposed.terminalCompletionProvider.d.ts │ ├── vscode.proposed.terminalDataWriteEvent.d.ts │ ├── vscode.proposed.terminalDimensions.d.ts │ ├── vscode.proposed.terminalExecuteCommandEvent.d.ts │ ├── vscode.proposed.terminalQuickFixProvider.d.ts │ ├── vscode.proposed.terminalSelection.d.ts │ ├── vscode.proposed.terminalShellEnv.d.ts │ ├── vscode.proposed.testObserver.d.ts │ ├── vscode.proposed.testRelatedCode.d.ts │ ├── vscode.proposed.textDocumentEncoding.d.ts │ ├── vscode.proposed.textEditorDiffInformation.d.ts │ ├── vscode.proposed.textSearchComplete2.d.ts │ ├── vscode.proposed.textSearchProvider.d.ts │ ├── vscode.proposed.textSearchProvider2.d.ts │ ├── vscode.proposed.timeline.d.ts │ ├── vscode.proposed.tokenInformation.d.ts │ ├── vscode.proposed.treeViewActiveItem.d.ts │ ├── vscode.proposed.treeViewMarkdownMessage.d.ts │ ├── vscode.proposed.treeViewReveal.d.ts │ ├── vscode.proposed.tunnelFactory.d.ts │ ├── vscode.proposed.tunnels.d.ts │ ├── vscode.proposed.valueSelectionInQuickPick.d.ts │ └── vscode.proposed.workspaceTrust.d.ts ├── test/ │ ├── .mocharc.json │ ├── README.md │ ├── automation/ │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── activityBar.ts │ │ │ ├── application.ts │ │ │ ├── code.ts │ │ │ ├── debug.ts │ │ │ ├── editor.ts │ │ │ ├── editors.ts │ │ │ ├── electron.ts │ │ │ ├── explorer.ts │ │ │ ├── extensions.ts │ │ │ ├── index.ts │ │ │ ├── keybindings.ts │ │ │ ├── localization.ts │ │ │ ├── logger.ts │ │ │ ├── notebook.ts │ │ │ ├── peek.ts │ │ │ ├── playwrightBrowser.ts │ │ │ ├── playwrightDriver.ts │ │ │ ├── playwrightElectron.ts │ │ │ ├── problems.ts │ │ │ ├── processes.ts │ │ │ ├── profiler.ts │ │ │ ├── quickaccess.ts │ │ │ ├── quickinput.ts │ │ │ ├── scm.ts │ │ │ ├── search.ts │ │ │ ├── settings.ts │ │ │ ├── statusbar.ts │ │ │ ├── task.ts │ │ │ ├── terminal.ts │ │ │ ├── viewlet.ts │ │ │ └── workbench.ts │ │ ├── tools/ │ │ │ ├── copy-driver-definition.js │ │ │ └── copy-package-version.js │ │ └── tsconfig.json │ ├── cgmanifest.json │ ├── integration/ │ │ ├── browser/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── index.ts │ │ │ └── tsconfig.json │ │ └── electron/ │ │ ├── testrunner.d.ts │ │ └── testrunner.js │ ├── leaks/ │ │ ├── index.html │ │ ├── package.json │ │ └── server.js │ ├── monaco/ │ │ ├── .gitignore │ │ ├── .mocharc.json │ │ ├── .npmrc │ │ ├── README.md │ │ ├── core.js │ │ ├── dist/ │ │ │ └── core.html │ │ ├── esm-check/ │ │ │ ├── esm-check.js │ │ │ ├── index.html │ │ │ └── index.js │ │ ├── monaco.test.ts │ │ ├── package.json │ │ ├── runner.js │ │ ├── tsconfig.json │ │ └── webpack.config.js │ ├── package.json │ ├── smoke/ │ │ ├── .gitignore │ │ ├── Audit.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── areas/ │ │ │ │ ├── extensions/ │ │ │ │ │ └── extensions.test.ts │ │ │ │ ├── languages/ │ │ │ │ │ └── languages.test.ts │ │ │ │ ├── multiroot/ │ │ │ │ │ └── multiroot.test.ts │ │ │ │ ├── notebook/ │ │ │ │ │ └── notebook.test.ts │ │ │ │ ├── preferences/ │ │ │ │ │ └── preferences.test.ts │ │ │ │ ├── search/ │ │ │ │ │ └── search.test.ts │ │ │ │ ├── statusbar/ │ │ │ │ │ └── statusbar.test.ts │ │ │ │ ├── task/ │ │ │ │ │ ├── task-quick-pick.test.ts │ │ │ │ │ └── task.test.ts │ │ │ │ ├── terminal/ │ │ │ │ │ ├── terminal-editors.test.ts │ │ │ │ │ ├── terminal-helpers.ts │ │ │ │ │ ├── terminal-input.test.ts │ │ │ │ │ ├── terminal-persistence.test.ts │ │ │ │ │ ├── terminal-profiles.test.ts │ │ │ │ │ ├── terminal-shellIntegration.test.ts │ │ │ │ │ ├── terminal-splitCwd.test.ts │ │ │ │ │ ├── terminal-stickyScroll.test.ts │ │ │ │ │ ├── terminal-tabs.test.ts │ │ │ │ │ └── terminal.test.ts │ │ │ │ └── workbench/ │ │ │ │ ├── data-loss.test.ts │ │ │ │ ├── launch.test.ts │ │ │ │ └── localization.test.ts │ │ │ ├── main.ts │ │ │ └── utils.ts │ │ ├── test/ │ │ │ └── index.js │ │ └── tsconfig.json │ └── unit/ │ ├── README.md │ ├── analyzeSnapshot.js │ ├── assert.js │ ├── browser/ │ │ ├── index.js │ │ └── renderer.html │ ├── coverage.js │ ├── electron/ │ │ ├── index.js │ │ ├── preload.js │ │ ├── renderer.html │ │ └── renderer.js │ ├── fullJsonStreamReporter.js │ ├── node/ │ │ ├── index.js │ │ └── package.json │ └── reporter.js └── tsfmt.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .config/1espt/PipelineAutobaseliningConfig.yml ================================================ ## DO NOT MODIFY THIS FILE MANUALLY. This is part of auto-baselining from 1ES Pipeline Templates. Go to [https://aka.ms/1espt-autobaselining] for more details. pipelines: 111: retail: source: credscan: lastModifiedDate: 2024-09-10 eslint: lastModifiedDate: 2024-09-10 psscriptanalyzer: lastModifiedDate: 2024-09-10 armory: lastModifiedDate: 2024-09-10 binary: credscan: lastModifiedDate: 2025-02-04 binskim: lastModifiedDate: 2025-02-04 spotbugs: lastModifiedDate: 2025-02-04 ================================================ FILE: .config/guardian/.gdnbaselines ================================================ { "properties": { "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/baselines" }, "version": "1.0.0", "baselines": { "default": { "name": "default", "createdDate": "2025-01-28 06:29:05Z", "lastUpdatedDate": "2025-01-28 06:29:05Z" } }, "results": { "ea3b2bf4f5b3d0bd8a6ad35cc61e49f2a1596660fd66d17d740e4806e7ed7dcc": { "signature": "ea3b2bf4f5b3d0bd8a6ad35cc61e49f2a1596660fd66d17d740e4806e7ed7dcc", "alternativeSignatures": [ "ff528c0b5a010ae7b5e9178b004a8b816a429a28ba98ce8336466b490a09dcef" ], "target": ".build/win32-arm64/system-setup/VSCodeSetup-arm64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-01-30 19:19:49Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "12babbc85192ed1c8d927693da788537c1eef199bbecbe226f940a2d0e97637c": { "signature": "12babbc85192ed1c8d927693da788537c1eef199bbecbe226f940a2d0e97637c", "alternativeSignatures": [ "35b0519e201e56fb87fc6fb085e6fb1df5b89715142bb9086a5b2006e0fd4ced" ], "target": ".build/win32-arm64/system-setup/VSCodeSetup-arm64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-01-30 19:19:49Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "49163bd1dc9d965d3baced1694dc8c43305b8bf96e884f478d8e4bd124454ba0": { "signature": "49163bd1dc9d965d3baced1694dc8c43305b8bf96e884f478d8e4bd124454ba0", "alternativeSignatures": [ "aa80bcf44aa8ddd20fb9802e9032c1257048b973896a944ded70bb195f060b2a" ], "target": ".build/win32-arm64/user-setup/VSCodeUserSetup-arm64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-01-30 19:21:17Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "c405af02e021c3a473d4e45ec4daa658db1527ea7430c6be968d182e7b50fbd1": { "signature": "c405af02e021c3a473d4e45ec4daa658db1527ea7430c6be968d182e7b50fbd1", "alternativeSignatures": [ "619d2a1a77f55b4181493b8cfdf09be5261e539115752af2e4938f5ac04af132" ], "target": ".build/win32-arm64/user-setup/VSCodeUserSetup-arm64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-01-30 19:21:17Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "71b8515b2eb51cfd5eace11cedb15189d51ce9e479095a5938334416088cbc03": { "signature": "71b8515b2eb51cfd5eace11cedb15189d51ce9e479095a5938334416088cbc03", "alternativeSignatures": [ "b34279fc5fec828b8dcd9ca873804e85d7d9cd78554ec109d2dd493351a7a244" ], "target": ".build/win32-x64/system-setup/VSCodeSetup-x64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-01-30 19:51:51Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "9238de77a5320039def14694d1b6f501cc2288f13c9c688d2e0501fc5a56ee61": { "signature": "9238de77a5320039def14694d1b6f501cc2288f13c9c688d2e0501fc5a56ee61", "alternativeSignatures": [ "1d17616a549e9f36d814c4e802d651b1af453ce0a23d4478eef39be81adcc16b" ], "target": ".build/win32-x64/system-setup/VSCodeSetup-x64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-01-30 19:51:51Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "bad8b698b48c1da9ece953903581c66bf98bc829ae1a6adcd3b5c2056a6fcd01": { "signature": "bad8b698b48c1da9ece953903581c66bf98bc829ae1a6adcd3b5c2056a6fcd01", "alternativeSignatures": [ "057376d31b97e8ce3ecf6a180a553b932d7e5be6e2b07a08027d5dfabe35e82c" ], "target": ".build/win32-x64/user-setup/VSCodeUserSetup-x64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-01-30 19:53:13Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "cc7c248b0fd4c105e9a393ae232bf0d314ec50e65357a5e7e7d68f6f10c77077": { "signature": "cc7c248b0fd4c105e9a393ae232bf0d314ec50e65357a5e7e7d68f6f10c77077", "alternativeSignatures": [ "f3867098aff3368682df9926e85a35ec05cf905f27d0c157430021c3169f899d" ], "target": ".build/win32-x64/user-setup/VSCodeUserSetup-x64-1.97.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-01-30 19:53:13Z", "expirationDate": "2025-07-19 21:12:48Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-01-30 21:12:48Z" }, "8c53250a171412b84dedcbb22cdab9ec365d9b52d74b09c070097fff45372de0": { "signature": "8c53250a171412b84dedcbb22cdab9ec365d9b52d74b09c070097fff45372de0", "alternativeSignatures": [ "314267784b0ea867006e00b809a93498fae3264e42d1a3a7745ab13180a5b6ef" ], "target": ".build/win32-arm64/system-setup/VSCodeSetup-arm64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-02-04 06:16:33Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "a6a58d971da858f4af219672cef73ffd0aacc47f1e2c12b8b44a428e1330d3de": { "signature": "a6a58d971da858f4af219672cef73ffd0aacc47f1e2c12b8b44a428e1330d3de", "alternativeSignatures": [ "4e40f2f1683f0bf2245f35d0ebbcf2f446274d84b1db09d8e76ddfdcad5d4479" ], "target": ".build/win32-arm64/system-setup/VSCodeSetup-arm64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-02-04 06:16:33Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "90e0f060e01e4a55620f609ac3241b62e8f54a059e9f4d292e93a4305fd3c39e": { "signature": "90e0f060e01e4a55620f609ac3241b62e8f54a059e9f4d292e93a4305fd3c39e", "alternativeSignatures": [ "377fe43ff8404d07f4a6ca763175004f360397ded6cf5d55b655646ada90e39c" ], "target": ".build/win32-arm64/user-setup/VSCodeUserSetup-arm64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-02-04 06:17:54Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "f36c3dc19566098a923877d16d6ebfcbd971f8fcd8210afb8f5558fb5ba1f203": { "signature": "f36c3dc19566098a923877d16d6ebfcbd971f8fcd8210afb8f5558fb5ba1f203", "alternativeSignatures": [ "1af1f475c1617701e3d7a8fd465916bcc60c3125b8807af5d47d49137d9d468c" ], "target": ".build/win32-arm64/user-setup/VSCodeUserSetup-arm64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-02-04 06:17:54Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "71193d108c53bb802f5c491276365bcff0645fb380be57288f3fbd6896166d3a": { "signature": "71193d108c53bb802f5c491276365bcff0645fb380be57288f3fbd6896166d3a", "alternativeSignatures": [ "420cae2e6e34b93d7b74fc1ffddfdf23b57650ae989d838bb2d67f28e4e1db0e" ], "target": ".build/win32-x64/system-setup/VSCodeSetup-x64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-02-04 07:11:19Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "444c302f49bdedcafe772322a09727b2279e3265d99deb2e307defeae3ef200b": { "signature": "444c302f49bdedcafe772322a09727b2279e3265d99deb2e307defeae3ef200b", "alternativeSignatures": [ "4ff6ccbdb0745d43d3b61f82fb2f4d8a64fe9787525df81a6d7b825e79282085" ], "target": ".build/win32-x64/system-setup/VSCodeSetup-x64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-02-04 07:11:19Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "4670c7c096a69ca428429ffa1f5250aac9f2e07beac0ffe587ffb37bdb1da4d4": { "signature": "4670c7c096a69ca428429ffa1f5250aac9f2e07beac0ffe587ffb37bdb1da4d4", "alternativeSignatures": [ "7cead96cb508ab6e37e27bcc0f8b7ed8d0761b77f4793958c46c5ff3892ab1b6" ], "target": ".build/win32-x64/user-setup/VSCodeUserSetup-x64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2009", "createdDate": "2025-02-04 07:13:22Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" }, "a359b4a5ed2378a73f3bba93e3fb1c595db7423c3082635d12d101bbeb0a51b8": { "signature": "a359b4a5ed2378a73f3bba93e3fb1c595db7423c3082635d12d101bbeb0a51b8", "alternativeSignatures": [ "125b52a21ef619a95e695085deb9492280bcf2c1decdd5e87e6416af5982d02d" ], "target": ".build/win32-x64/user-setup/VSCodeUserSetup-x64-1.98.0-insider.exe", "memberOf": [ "default" ], "tool": "binskim", "ruleId": "BA2018", "createdDate": "2025-02-04 07:13:22Z", "expirationDate": "2025-07-24 07:25:17Z", "justification": "This error is baselined with an expiration date of 180 days from 2025-02-04 07:25:17Z" } } } ================================================ FILE: .config/guardian/.gdnsuppress ================================================ { "hydrated": false, "properties": { "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/suppressions" }, "version": "1.0.0", "suppressionSets": { "default": { "name": "default", "createdDate": "2025-03-17 11:52:32Z", "lastUpdatedDate": "2025-03-17 11:52:32Z" } }, "results": { "216e2ac9cb596796224b47799f656570a01fa0d9b5f935608b47d15ab613c8e8": { "signature": "216e2ac9cb596796224b47799f656570a01fa0d9b5f935608b47d15ab613c8e8", "alternativeSignatures": [ "07746898f43afab7cc50931b33154c2d9e1a35f82a649dbe8aecf785b3d5a813" ], "memberOf": [ "default" ], "createdDate": "2025-03-17 11:52:32Z" }, "77797a3e44634bb2994bd13ccc95ff4575bba474585dbd2cf3068a1c16bc0624": { "signature": "77797a3e44634bb2994bd13ccc95ff4575bba474585dbd2cf3068a1c16bc0624", "alternativeSignatures": [ "4a6cb67bd4b401e9669c13a2162660aaefc0a94a4122e5b50c198414db545672" ], "memberOf": [ "default" ], "createdDate": "2025-03-17 11:52:32Z" }, "30418bcc5269eaeb2832a2404465784431d4e72a2af332320c2b1db4768902ad": { "signature": "30418bcc5269eaeb2832a2404465784431d4e72a2af332320c2b1db4768902ad", "alternativeSignatures": [ "b7b9eb974d7d3a4ae14df8695ca5a62592c8c9d20b7eda70a6535d50cbda3e7f" ], "memberOf": [ "default" ], "createdDate": "2025-03-17 11:52:32Z" } } } ================================================ FILE: .configurations/configuration.dsc.yaml ================================================ # yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2 # Reference: https://github.com/microsoft/vscode/wiki/How-to-Contribute properties: resources: - resource: Microsoft.WinGet.DSC/WinGetPackage directives: description: Install Git allowPrerelease: true settings: id: Git.Git source: winget - resource: Microsoft.WinGet.DSC/WinGetPackage id: npm directives: description: Install NodeJS version 20 allowPrerelease: true settings: id: OpenJS.NodeJS.LTS version: "20.14.0" source: winget - resource: Microsoft.WinGet.DSC/WinGetPackage directives: description: Install Python 3.10 allowPrerelease: true settings: id: Python.Python.3.10 source: winget - resource: Microsoft.WinGet.DSC/WinGetPackage id: vsPackage directives: description: Install Visual Studio 2022 (any edition is OK) allowPrerelease: true settings: id: Microsoft.VisualStudio.2022.BuildTools source: winget - resource: Microsoft.VisualStudio.DSC/VSComponents dependsOn: - vsPackage directives: description: Install required VS workloads allowPrerelease: true settings: productId: Microsoft.VisualStudio.Product.BuildTools channelId: VisualStudio.17.Release includeRecommended: true components: - Microsoft.VisualStudio.Workload.VCTools - resource: NpmDsc/NpmInstall dependsOn: - npm directives: description: Install dependencies allowPrerelease: true settings: PackageDirectory: '${WinGetConfigRoot}\..\' configurationVersion: 0.2.0 ================================================ FILE: .devcontainer/Dockerfile ================================================ FROM mcr.microsoft.com/devcontainers/typescript-node:20-bookworm ADD install-vscode.sh /root/ RUN /root/install-vscode.sh RUN git config --system codespaces-theme.hide-status 1 USER node RUN npm install -g node-gyp RUN NPM_CACHE="$(npm config get cache)" && rm -rf "$NPM_CACHE" && ln -s /vscode-dev/npm-cache "$NPM_CACHE" RUN echo 'export DISPLAY="${DISPLAY:-:1}"' | tee -a ~/.bashrc >> ~/.zshrc USER root CMD chown node:node /vscode-dev && sudo -u node mkdir -p /vscode-dev/npm-cache && sleep inf ================================================ FILE: .devcontainer/README.md ================================================ # Code - OSS Development Container [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) This repository includes configuration for a development container for working with Code - OSS in a local container or using [GitHub Codespaces](https://github.com/features/codespaces). > **Tip:** The default VNC password is `vscode`. The VNC server runs on port `5901` and a web client is available on port `6080`. ## Quick start - local If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. 1. Install Docker Desktop or Docker for Linux on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.) 2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**. > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. 3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension. ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**. > **Tip:** While you can use your local source tree instead, operations like `npm i` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend using the WSL filesystem on Windows or the "clone repository in container" approach on Windows and macOS instead since it uses "named volume" rather than the local filesystem. 5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter. 6. After the container is running: 1. If you have the `DISPLAY` or `WAYLAND_DISPLAY` environment variables set locally (or in WSL on Windows), desktop apps in the container will be shown in local windows. 2. If these are not set, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** ## Quick start - GitHub Codespaces 1. From the [microsoft/vscode GitHub repository](https://github.com/microsoft/vscode), click on the **Code** dropdown, select **Open with Codespaces**, and then click on **New codespace**. If prompted, select the **Standard** machine size (which is also the default). > **Note:** You will not see these options within GitHub if you are not in the Codespaces beta. 2. After the codespace is up and running in your browser, press Ctrl/Cmd + Shift + P or F1 and select **Ports: Focus on Ports View**. 3. You should see **VNC web client (6080)** under in the list of ports. Select the line and click on the globe icon to open it in a browser tab. > **Tip:** If you do not see the port, Ctrl/Cmd + Shift + P or F1, select **Forward a Port** and enter port `6080`. 4. In the new tab, you should see noVNC. Click **Connect** and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** ### Using VS Code with GitHub Codespaces You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it. 1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. 2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings: - `microsoft/vscode` for the repository. - Select any branch (e.g. **main**) - you can select a different one later. - Choose **Standard** (4-core, 8GB) as the size. 3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop. 4. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** ## Try it This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. > **Note:** You can also set the resolution from the command line by typing `set-resolution`. To start working with Code - OSS, follow these steps: 1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands: ```bash npm i bash scripts/code.sh ``` 2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password. 3. You should now see Code - OSS! Next, let's try debugging. 1. Shut down Code - OSS by clicking the box in the upper right corner of the Code - OSS window through your browser or VNC viewer. 2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5). > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `./scripts/code.sh` first will set up Electron which will usually solve timeout issues. 3. After a bit, Code - OSS will appear with the debugger attached! Enjoy! ### Notes The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`. [def]: https://www.realvnc.com/en/connect/download/viewer/ ================================================ FILE: .devcontainer/devcontainer-lock.json ================================================ { "features": { "ghcr.io/devcontainers/features/desktop-lite:1": { "version": "1.0.8", "resolved": "ghcr.io/devcontainers/features/desktop-lite@sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7", "integrity": "sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7" }, "ghcr.io/devcontainers/features/rust:1": { "version": "1.1.3", "resolved": "ghcr.io/devcontainers/features/rust@sha256:aba6f47303b197976902bf544c786b5efecc03c238ff593583e5e74dfa9c7ccb", "integrity": "sha256:aba6f47303b197976902bf544c786b5efecc03c238ff593583e5e74dfa9c7ccb" } } } ================================================ FILE: .devcontainer/devcontainer.json ================================================ { "name": "Code - OSS", "build": { "dockerfile": "Dockerfile" }, "features": { "ghcr.io/devcontainers/features/desktop-lite:1": {}, "ghcr.io/devcontainers/features/rust:1": {} }, "containerEnv": { "DISPLAY": "" // Allow the Dev Containers extension to set DISPLAY, post-create.sh will add it back in ~/.bashrc and ~/.zshrc if not set. }, "overrideCommand": false, "privileged": true, "mounts": [ { "source": "vscode-dev", "target": "/vscode-dev", "type": "volume" } ], "postCreateCommand": "./.devcontainer/post-create.sh", "customizations": { "vscode": { "settings": { "resmon.show.battery": false, "resmon.show.cpufreq": false }, "extensions": [ "dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", "GitHub.vscode-pull-request-github", "ms-vscode.vscode-github-issue-notebooks", "ms-vscode.vscode-selfhost-test-provider", "mutantdino.resourcemonitor" ] } }, "forwardPorts": [6080, 5901], "portsAttributes": { "6080": { "label": "VNC web client (noVNC)", "onAutoForward": "silent" }, "5901": { "label": "VNC TCP port", "onAutoForward": "silent" } }, "hostRequirements": { "memory": "9gb" } } ================================================ FILE: .devcontainer/install-vscode.sh ================================================ #!/bin/sh apt update apt install -y wget gpg wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list' rm -f packages.microsoft.gpg apt update apt install -y code-insiders libsecret-1-dev libxkbfile-dev libkrb5-dev ================================================ FILE: .devcontainer/post-create.sh ================================================ #!/bin/sh npm i npm run electron ================================================ FILE: .editorconfig ================================================ # EditorConfig is awesome: https://EditorConfig.org # top-most EditorConfig file root = true # Tab indentation [*] indent_style = tab trim_trailing_whitespace = true # The indent size used in the `package.json` file cannot be changed # https://github.com/npm/npm/pull/3180#issuecomment-16336516 [{*.yml,*.yaml,package.json}] indent_style = space indent_size = 2 ================================================ FILE: .eslint-ignore ================================================ **/build/*/**/*.js **/dist/**/*.js **/extensions/**/*.d.ts **/extensions/**/build/** **/extensions/**/colorize-fixtures/** **/extensions/css-language-features/server/test/pathCompletionFixtures/** **/extensions/html-language-features/server/lib/jquery.d.ts **/extensions/html-language-features/server/src/test/pathCompletionFixtures/** **/extensions/ipynb/notebook-out/** **/extensions/markdown-language-features/media/** **/extensions/markdown-language-features/notebook-out/** **/extensions/markdown-math/notebook-out/** **/extensions/notebook-renderers/renderer-out/index.js **/extensions/simple-browser/media/index.js **/extensions/terminal-suggest/src/completions/upstream/** **/extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts **/extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts **/extensions/terminal-suggest/third_party/** **/extensions/typescript-language-features/test-workspace/** **/extensions/typescript-language-features/extension.webpack.config.js **/extensions/typescript-language-features/extension-browser.webpack.config.js **/extensions/typescript-language-features/package-manager/node-maintainer/** **/extensions/vscode-api-tests/testWorkspace/** **/extensions/vscode-api-tests/testWorkspace2/** **/fixtures/** **/node_modules/** **/out-*/**/*.js **/out-editor-*/** **/out/**/*.js **/src/**/dompurify.js **/src/**/marked.js **/src/**/semver.js **/src/typings/**/*.d.ts **/src/vs/*/**/*.d.ts **/src/vs/base/test/common/filters.perf.data.js **/src/vs/loader.js **/test/unit/assert.js **/test/automation/out/** **/typings/** **/.build/** !.vscode ================================================ FILE: .eslint-plugin-local/code-amd-node-module.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { join } from 'path'; export = new class ApiProviderNaming implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { amdX: 'Use `import type` for import declarations, use `amdX#importAMDNodeModule` for import expressions' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const modules = new Set(); try { const { dependencies, optionalDependencies } = require(join(__dirname, '../package.json')); const all = Object.keys(dependencies).concat(Object.keys(optionalDependencies)); for (const key of all) { modules.add(key); } } catch (e) { console.error(e); throw e; } const checkImport = (node: any) => { if (node.type !== 'Literal' || typeof node.value !== 'string') { return; } if (node.parent.importKind === 'type') { return; } if (!modules.has(node.value)) { return; } context.report({ node, messageId: 'amdX' }); }; return { ['ImportExpression Literal']: checkImport, ['ImportDeclaration Literal']: checkImport }; } }; ================================================ FILE: .eslint-plugin-local/code-declare-service-brand.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class DeclareServiceBrand implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { fixable: 'code', schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['PropertyDefinition[key.name="_serviceBrand"][value]']: (node: any) => { return context.report({ node, message: `The '_serviceBrand'-property should not have a value`, fix: (fixer) => { return fixer.replaceText(node, 'declare _serviceBrand: undefined;'); } }); } }; } }; ================================================ FILE: .eslint-plugin-local/code-ensure-no-disposables-leak-in-test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { Node } from 'estree'; export = new class EnsureNoDisposablesAreLeakedInTestSuite implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { type: 'problem', messages: { ensure: 'Suites should include a call to `ensureNoDisposablesAreLeakedInTestSuite()` to ensure no disposables are leaked in tests.' }, fixable: 'code', schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const config = <{ exclude: string[] }>context.options[0]; const needle = context.getFilename().replace(/\\/g, '/'); if (config.exclude.some((e) => needle.endsWith(e))) { return {}; } return { [`Program > ExpressionStatement > CallExpression[callee.name='suite']`]: (node: Node) => { const src = context.getSourceCode().getText(node); if (!src.includes('ensureNoDisposablesAreLeakedInTestSuite(')) { context.report({ node, messageId: 'ensure', fix: (fixer) => { const updatedSrc = src.replace(/(suite\(.*\n)/, '$1\n\tensureNoDisposablesAreLeakedInTestSuite();\n'); return fixer.replaceText(node, updatedSrc); } }); } }, }; } }; ================================================ FILE: .eslint-plugin-local/code-import-patterns.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; import * as path from 'path'; import minimatch from 'minimatch'; import { createImportRuleListener } from './utils'; const REPO_ROOT = path.normalize(path.join(__dirname, '../')); interface ConditionalPattern { when?: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test'; pattern: string; } interface RawImportPatternsConfig { target: string; layer?: 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-utility' | 'electron-main'; test?: boolean; restrictions: string | (string | ConditionalPattern)[]; } interface LayerAllowRule { when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test'; allow: string[]; } type RawOption = RawImportPatternsConfig | LayerAllowRule; function isLayerAllowRule(option: RawOption): option is LayerAllowRule { return !!((option).when && (option).allow); } interface ImportPatternsConfig { target: string; restrictions: string[]; } export = new class implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { badImport: 'Imports violates \'{{restrictions}}\' restrictions. See https://github.com/microsoft/vscode/wiki/Source-Code-Organization', badFilename: 'Missing definition in `code-import-patterns` for this file. Define rules at https://github.com/microsoft/vscode/blob/main/eslint.config.js', badAbsolute: 'Imports have to be relative to support ESM', badExtension: 'Imports have to end with `.js` or `.css` to support ESM', }, docs: { url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const options = context.options; const configs = this._processOptions(options); const relativeFilename = getRelativeFilename(context); for (const config of configs) { if (minimatch(relativeFilename, config.target)) { return createImportRuleListener((node, value) => this._checkImport(context, config, node, value)); } } context.report({ loc: { line: 1, column: 0 }, messageId: 'badFilename' }); return {}; } private _optionsCache = new WeakMap(); private _processOptions(options: RawOption[]): ImportPatternsConfig[] { if (this._optionsCache.has(options)) { return this._optionsCache.get(options)!; } type Layer = 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-utility' | 'electron-main'; interface ILayerRule { layer: Layer; deps: string; isBrowser?: boolean; isNode?: boolean; isElectron?: boolean; } function orSegment(variants: Layer[]): string { return (variants.length === 1 ? variants[0] : `{${variants.join(',')}}`); } const layerRules: ILayerRule[] = [ { layer: 'common', deps: orSegment(['common']) }, { layer: 'worker', deps: orSegment(['common', 'worker']) }, { layer: 'browser', deps: orSegment(['common', 'browser']), isBrowser: true }, { layer: 'electron-sandbox', deps: orSegment(['common', 'browser', 'electron-sandbox']), isBrowser: true }, { layer: 'node', deps: orSegment(['common', 'node']), isNode: true }, { layer: 'electron-utility', deps: orSegment(['common', 'node', 'electron-utility']), isNode: true, isElectron: true }, { layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-utility', 'electron-main']), isNode: true, isElectron: true }, ]; let browserAllow: string[] = []; let nodeAllow: string[] = []; let electronAllow: string[] = []; let testAllow: string[] = []; for (const option of options) { if (isLayerAllowRule(option)) { if (option.when === 'hasBrowser') { browserAllow = option.allow.slice(0); } else if (option.when === 'hasNode') { nodeAllow = option.allow.slice(0); } else if (option.when === 'hasElectron') { electronAllow = option.allow.slice(0); } else if (option.when === 'test') { testAllow = option.allow.slice(0); } } } function findLayer(layer: Layer): ILayerRule | null { for (const layerRule of layerRules) { if (layerRule.layer === layer) { return layerRule; } } return null; } function generateConfig(layerRule: ILayerRule, target: string, rawRestrictions: (string | ConditionalPattern)[]): [ImportPatternsConfig, ImportPatternsConfig] { const restrictions: string[] = []; const testRestrictions: string[] = [...testAllow]; if (layerRule.isBrowser) { restrictions.push(...browserAllow); } if (layerRule.isNode) { restrictions.push(...nodeAllow); } if (layerRule.isElectron) { restrictions.push(...electronAllow); } for (const rawRestriction of rawRestrictions) { let importPattern: string; let when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test' | undefined = undefined; if (typeof rawRestriction === 'string') { importPattern = rawRestriction; } else { importPattern = rawRestriction.pattern; when = rawRestriction.when; } if (typeof when === 'undefined' || (when === 'hasBrowser' && layerRule.isBrowser) || (when === 'hasNode' && layerRule.isNode) || (when === 'hasElectron' && layerRule.isElectron) ) { restrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`)); testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`)); } else if (when === 'test') { testRestrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`)); testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`)); } } testRestrictions.push(...restrictions); return [ { target: target.replace(/\/\~$/, `/${layerRule.layer}/**`), restrictions: restrictions }, { target: target.replace(/\/\~$/, `/test/${layerRule.layer}/**`), restrictions: testRestrictions } ]; } const configs: ImportPatternsConfig[] = []; for (const option of options) { if (isLayerAllowRule(option)) { continue; } const target = option.target; const targetIsVS = /^src\/vs\//.test(target); const restrictions = (typeof option.restrictions === 'string' ? [option.restrictions] : option.restrictions).slice(0); if (targetIsVS) { // Always add "vs/nls" and "vs/amdX" restrictions.push('vs/nls.js'); restrictions.push('vs/amdX.js'); // TODO@jrieken remove after ESM is real } if (targetIsVS && option.layer) { // single layer => simple substitution for /~ const layerRule = findLayer(option.layer); if (layerRule) { const [config, testConfig] = generateConfig(layerRule, target, restrictions); if (option.test) { configs.push(testConfig); } else { configs.push(config); } } } else if (targetIsVS && /\/\~$/.test(target)) { // generate all layers for (const layerRule of layerRules) { const [config, testConfig] = generateConfig(layerRule, target, restrictions); configs.push(config); configs.push(testConfig); } } else { configs.push({ target, restrictions: restrictions.filter(r => typeof r === 'string') }); } } this._optionsCache.set(options, configs); return configs; } private _checkImport(context: eslint.Rule.RuleContext, config: ImportPatternsConfig, node: TSESTree.Node, importPath: string) { const targetIsVS = /^src\/vs\//.test(getRelativeFilename(context)); if (targetIsVS) { // ESM: check for import ending with ".js" or ".css" if (importPath[0] === '.' && !importPath.endsWith('.js') && !importPath.endsWith('.css')) { context.report({ loc: node.loc, messageId: 'badExtension', }); } // check for import being relative if (importPath.startsWith('vs/')) { context.report({ loc: node.loc, messageId: 'badAbsolute', }); } } // resolve relative paths if (importPath[0] === '.') { const relativeFilename = getRelativeFilename(context); importPath = path.posix.join(path.posix.dirname(relativeFilename), importPath); if (/^src\/vs\//.test(importPath)) { // resolve using base url importPath = importPath.substring('src/'.length); } } const restrictions = config.restrictions; let matched = false; for (const pattern of restrictions) { if (minimatch(importPath, pattern)) { matched = true; break; } } if (!matched) { // None of the restrictions matched context.report({ loc: node.loc, messageId: 'badImport', data: { restrictions: restrictions.join(' or ') } }); } } }; /** * Returns the filename relative to the project root and using `/` as separators */ function getRelativeFilename(context: eslint.Rule.RuleContext): string { const filename = path.normalize(context.getFilename()); return filename.substring(REPO_ROOT.length).replace(/\\/g, '/'); } ================================================ FILE: .eslint-plugin-local/code-layering.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { join, dirname } from 'path'; import { createImportRuleListener } from './utils'; type Config = { allowed: Set; disallowed: Set; }; export = new class implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { layerbreaker: 'Bad layering. You are not allowed to access {{from}} from here, allowed layers are: [{{allowed}}]' }, docs: { url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization' }, schema: [ { type: 'object', additionalProperties: { type: 'array', items: { type: 'string' } } } ] }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const fileDirname = dirname(context.getFilename()); const parts = fileDirname.split(/\\|\//); const ruleArgs = >context.options[0]; let config: Config | undefined; for (let i = parts.length - 1; i >= 0; i--) { if (ruleArgs[parts[i]]) { config = { allowed: new Set(ruleArgs[parts[i]]).add(parts[i]), disallowed: new Set() }; Object.keys(ruleArgs).forEach(key => { if (!config!.allowed.has(key)) { config!.disallowed.add(key); } }); break; } } if (!config) { // nothing return {}; } return createImportRuleListener((node, path) => { if (path[0] === '.') { path = join(dirname(context.getFilename()), path); } const parts = dirname(path).split(/\\|\//); for (let i = parts.length - 1; i >= 0; i--) { const part = parts[i]; if (config!.allowed.has(part)) { // GOOD - same layer break; } if (config!.disallowed.has(part)) { // BAD - wrong layer context.report({ loc: node.loc, messageId: 'layerbreaker', data: { from: part, allowed: [...config!.allowed.keys()].join(', ') } }); break; } } }); } }; ================================================ FILE: .eslint-plugin-local/code-limited-top-functions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { dirname, relative } from 'path'; import minimatch from 'minimatch'; export = new class implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { layerbreaker: 'You are only allowed to define limited top level functions.' }, schema: { type: 'array', items: { type: 'object', additionalProperties: { type: 'array', items: { type: 'string' } } } } }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { let fileRelativePath = relative(dirname(__dirname), context.getFilename()); if (!fileRelativePath.endsWith('/')) { fileRelativePath += '/'; } const ruleArgs = >context.options[0]; const matchingKey = Object.keys(ruleArgs).find(key => fileRelativePath.startsWith(key) || minimatch(fileRelativePath, key)); if (!matchingKey) { // nothing return {}; } const restrictedFunctions = ruleArgs[matchingKey]; return { FunctionDeclaration: (node: any) => { const isTopLevel = node.parent.type === 'Program'; const functionName = node.id.name; if (isTopLevel && !restrictedFunctions.includes(node.id.name)) { context.report({ node, message: `Top-level function '${functionName}' is restricted in this file. Allowed functions are: ${restrictedFunctions.join(', ')}.` }); } }, ExportNamedDeclaration(node: any) { if (node.declaration && node.declaration.type === 'FunctionDeclaration') { const functionName = node.declaration.id.name; const isTopLevel = node.parent.type === 'Program'; if (isTopLevel && !restrictedFunctions.includes(node.declaration.id.name)) { context.report({ node, message: `Top-level function '${functionName}' is restricted in this file. Allowed functions are: ${restrictedFunctions.join(', ')}.` }); } } } }; } }; ================================================ FILE: .eslint-plugin-local/code-must-use-result.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; const VALID_USES = new Set([ TSESTree.AST_NODE_TYPES.AwaitExpression, TSESTree.AST_NODE_TYPES.VariableDeclarator, ]); export = new class MustUseResults implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { schema: false }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const config = <{ message: string; functions: string[] }[]>context.options[0]; const listener: eslint.Rule.RuleListener = {}; for (const { message, functions } of config) { for (const fn of functions) { const query = `CallExpression[callee.property.name='${fn}'], CallExpression[callee.name='${fn}']`; listener[query] = (node: any) => { const cast: TSESTree.CallExpression = node; if (!VALID_USES.has(cast.parent?.type)) { context.report({ node, message }); } }; } } return listener; } }; ================================================ FILE: .eslint-plugin-local/code-must-use-super-dispose.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class NoAsyncSuite implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { function doesCallSuperDispose(node: any) { if (!node.override) { return; } const body = context.getSourceCode().getText(node); if (body.includes('super.dispose')) { return; } context.report({ node, message: 'dispose() should call super.dispose()' }); } return { ['MethodDefinition[override][key.name="dispose"]']: doesCallSuperDispose, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-dangerous-type-assertions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export = new class NoDangerousTypeAssertions implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { // Disable in tests for now if (context.getFilename().includes('.test')) { return {}; } return { // Disallow type assertions on object literals: { ... } or {} as T ['TSTypeAssertion > ObjectExpression, TSAsExpression > ObjectExpression']: (node: any) => { const objectNode = node as TSESTree.Node; const parent = objectNode.parent as TSESTree.TSTypeAssertion | TSESTree.TSAsExpression; if ( // Allow `as const` assertions (parent.typeAnnotation.type === 'TSTypeReference' && parent.typeAnnotation.typeName.type === 'Identifier' && parent.typeAnnotation.typeName.name === 'const') // For also now still allow `any` casts || (parent.typeAnnotation.type === 'TSAnyKeyword') ) { return; } context.report({ node, message: `Don't use type assertions for creating objects as this can hide type errors.` }); }, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-global-document-listener.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class NoGlobalDocumentListener implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { CallExpression(node: any) { if ( ( node.callee.name === 'addDisposableListener' || node.callee.property?.name === 'addDisposableListener' ) && node.arguments.length > 0 && node.arguments[0].type === 'Identifier' && node.arguments[0].name === 'document' ) { context.report({ node, message: 'Use .document to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.', }); } }, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-native-private.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class ApiProviderNaming implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { slow: 'Native private fields are much slower and should only be used when needed. Ignore this warning if you know what you are doing, use compile-time private otherwise. See https://github.com/microsoft/vscode/issues/185991#issuecomment-1614468158 for details', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['PropertyDefinition PrivateIdentifier']: (node: any) => { context.report({ node, messageId: 'slow' }); }, ['MethodDefinition PrivateIdentifier']: (node: any) => { context.report({ node, messageId: 'slow' }); } }; } }; ================================================ FILE: .eslint-plugin-local/code-no-nls-in-standalone-editor.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { join } from 'path'; import { createImportRuleListener } from './utils'; export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { noNls: 'Not allowed to import vs/nls in standalone editor modules. Use standaloneStrings.ts' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const fileName = context.getFilename(); if ( /vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(fileName) || /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(fileName) || /vs(\/|\\)editor(\/|\\)editor.api/.test(fileName) || /vs(\/|\\)editor(\/|\\)editor.main/.test(fileName) || /vs(\/|\\)editor(\/|\\)editor.worker.start/.test(fileName) ) { return createImportRuleListener((node, path) => { // resolve relative paths if (path[0] === '.') { path = join(context.getFilename(), path); } if ( /vs(\/|\\)nls/.test(path) ) { context.report({ loc: node.loc, messageId: 'noNls' }); } }); } return {}; } }; ================================================ FILE: .eslint-plugin-local/code-no-potentially-unsafe-disposables.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; /** * Checks for potentially unsafe usage of `DisposableStore` / `MutableDisposable`. * * These have been the source of leaks in the past. */ export = new class implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { function checkVariableDeclaration(inNode: any) { context.report({ node: inNode, message: `Use const for 'DisposableStore' to avoid leaks by accidental reassignment.` }); } function checkProperty(inNode: any) { context.report({ node: inNode, message: `Use readonly for DisposableStore/MutableDisposable to avoid leaks through accidental reassignment.` }); } return { 'VariableDeclaration[kind!="const"] NewExpression[callee.name="DisposableStore"]': checkVariableDeclaration, 'PropertyDefinition[readonly!=true][typeAnnotation.typeAnnotation.typeName.name=/DisposableStore|MutableDisposable/]': checkProperty, 'PropertyDefinition[readonly!=true] NewExpression[callee.name=/DisposableStore|MutableDisposable/]': checkProperty, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-runtime-import.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TSESTree } from '@typescript-eslint/typescript-estree'; import * as eslint from 'eslint'; import { dirname, join, relative } from 'path'; import minimatch from 'minimatch'; import { createImportRuleListener } from './utils'; export = new class implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { layerbreaker: 'You are only allowed to import {{import}} from here using `import type ...`.' }, schema: { type: 'array', items: { type: 'object', additionalProperties: { type: 'array', items: { type: 'string' } } } } }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { let fileRelativePath = relative(dirname(__dirname), context.getFilename()); if (!fileRelativePath.endsWith('/')) { fileRelativePath += '/'; } const ruleArgs = >context.options[0]; const matchingKey = Object.keys(ruleArgs).find(key => fileRelativePath.startsWith(key) || minimatch(fileRelativePath, key)); if (!matchingKey) { // nothing return {}; } const restrictedImports = ruleArgs[matchingKey]; return createImportRuleListener((node, path) => { if (path[0] === '.') { path = join(dirname(context.getFilename()), path); } if (( restrictedImports.includes(path) || restrictedImports.some(restriction => minimatch(path, restriction)) ) && !( (node.parent?.type === TSESTree.AST_NODE_TYPES.ImportDeclaration && node.parent.importKind === 'type') || (node.parent && 'exportKind' in node.parent && node.parent.exportKind === 'type'))) { // the export could be multiple types context.report({ loc: node.parent!.loc, messageId: 'layerbreaker', data: { import: path } }); } }); } }; ================================================ FILE: .eslint-plugin-local/code-no-standalone-editor.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { join } from 'path'; import { createImportRuleListener } from './utils'; export = new class NoNlsInStandaloneEditorRule implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { badImport: 'Not allowed to import standalone editor modules.' }, docs: { url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { if (/vs(\/|\\)editor/.test(context.getFilename())) { // the vs/editor folder is allowed to use the standalone editor return {}; } return createImportRuleListener((node, path) => { // resolve relative paths if (path[0] === '.') { path = join(context.getFilename(), path); } if ( /vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path) || /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path) || /vs(\/|\\)editor(\/|\\)editor.api/.test(path) || /vs(\/|\\)editor(\/|\\)editor.main/.test(path) || /vs(\/|\\)editor(\/|\\)editor.worker.start/.test(path) ) { context.report({ loc: node.loc, messageId: 'badImport' }); } }); } }; ================================================ FILE: .eslint-plugin-local/code-no-static-self-ref.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; /** * WORKAROUND for https://github.com/evanw/esbuild/issues/3823 */ export = new class implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { function checkProperty(inNode: any) { const classDeclaration = context.sourceCode.getAncestors(inNode).find(node => node.type === 'ClassDeclaration'); const propertyDefinition = inNode; if (!classDeclaration || !classDeclaration.id?.name) { return; } if (!propertyDefinition.value) { return; } const classCtor = classDeclaration.body.body.find(node => node.type === 'MethodDefinition' && node.kind === 'constructor'); if (!classCtor) { return; } const name = classDeclaration.id.name; const valueText = context.sourceCode.getText(propertyDefinition.value); if (valueText.includes(name + '.')) { if (classCtor.value?.type === 'FunctionExpression' && !classCtor.value.params.find((param: any) => param.type === 'TSParameterProperty' && param.decorators?.length > 0)) { return; } context.report({ loc: propertyDefinition.value.loc, message: `Static properties in decorated classes should not reference the class they are defined in. Use 'this' instead. This is a workaround for https://github.com/evanw/esbuild/issues/3823.` }); } } return { 'PropertyDefinition[static=true]': checkProperty, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-test-async-suite.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TSESTree } from '@typescript-eslint/utils'; import * as eslint from 'eslint'; function isCallExpression(node: TSESTree.Node): node is TSESTree.CallExpression { return node.type === 'CallExpression'; } function isFunctionExpression(node: TSESTree.Node): node is TSESTree.FunctionExpression { return node.type.includes('FunctionExpression'); } export = new class NoAsyncSuite implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { function hasAsyncSuite(node: any) { if (isCallExpression(node) && node.arguments.length >= 2 && isFunctionExpression(node.arguments[1]) && node.arguments[1].async) { return context.report({ node: node as any, message: 'suite factory function should never be async' }); } } return { ['CallExpression[callee.name=/suite$/][arguments]']: hasAsyncSuite, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-test-only.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class NoTestOnly implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['MemberExpression[object.name=/^(test|suite)$/][property.name="only"]']: (node: any) => { return context.report({ node, message: 'only is a dev-time tool and CANNOT be pushed' }); } }; } }; ================================================ FILE: .eslint-plugin-local/code-no-unexternalized-strings.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils'; function isStringLiteral(node: TSESTree.Node | null | undefined): node is TSESTree.StringLiteral { return !!node && node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string'; } function isDoubleQuoted(node: TSESTree.StringLiteral): boolean { return node.raw[0] === '"' && node.raw[node.raw.length - 1] === '"'; } export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { private static _rNlsKeys = /^[_a-zA-Z0-9][ .\-_a-zA-Z0-9]*$/; readonly meta: eslint.Rule.RuleMetaData = { messages: { doubleQuoted: 'Only use double-quoted strings for externalized strings.', badKey: 'The key \'{{key}}\' doesn\'t conform to a valid localize identifier.', duplicateKey: 'Duplicate key \'{{key}}\' with different message value.', badMessage: 'Message argument to \'{{message}}\' must be a string literal.' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const externalizedStringLiterals = new Map(); const doubleQuotedStringLiterals = new Set(); function collectDoubleQuotedStrings(node: TSESTree.Literal) { if (isStringLiteral(node) && isDoubleQuoted(node)) { doubleQuotedStringLiterals.add(node); } } function visitLocalizeCall(node: TSESTree.CallExpression) { // localize(key, message) const [keyNode, messageNode] = (node).arguments; // (1) // extract key so that it can be checked later let key: string | undefined; if (isStringLiteral(keyNode)) { doubleQuotedStringLiterals.delete(keyNode); key = keyNode.value; } else if (keyNode.type === AST_NODE_TYPES.ObjectExpression) { for (const property of keyNode.properties) { if (property.type === AST_NODE_TYPES.Property && !property.computed) { if (property.key.type === AST_NODE_TYPES.Identifier && property.key.name === 'key') { if (isStringLiteral(property.value)) { doubleQuotedStringLiterals.delete(property.value); key = property.value.value; break; } } } } } if (typeof key === 'string') { let array = externalizedStringLiterals.get(key); if (!array) { array = []; externalizedStringLiterals.set(key, array); } array.push({ call: node, message: messageNode }); } // (2) // remove message-argument from doubleQuoted list and make // sure it is a string-literal doubleQuotedStringLiterals.delete(messageNode); if (!isStringLiteral(messageNode)) { context.report({ loc: messageNode.loc, messageId: 'badMessage', data: { message: context.getSourceCode().getText(node) } }); } } function visitL10NCall(node: TSESTree.CallExpression) { // localize(key, message) const [messageNode] = (node).arguments; // remove message-argument from doubleQuoted list and make // sure it is a string-literal if (isStringLiteral(messageNode)) { doubleQuotedStringLiterals.delete(messageNode); } else if (messageNode.type === AST_NODE_TYPES.ObjectExpression) { for (const prop of messageNode.properties) { if (prop.type === AST_NODE_TYPES.Property) { if (prop.key.type === AST_NODE_TYPES.Identifier && prop.key.name === 'message') { doubleQuotedStringLiterals.delete(prop.value); break; } } } } } function reportBadStringsAndBadKeys() { // (1) // report all strings that are in double quotes for (const node of doubleQuotedStringLiterals) { context.report({ loc: node.loc, messageId: 'doubleQuoted' }); } for (const [key, values] of externalizedStringLiterals) { // (2) // report all invalid NLS keys if (!key.match(NoUnexternalizedStrings._rNlsKeys)) { for (const value of values) { context.report({ loc: value.call.loc, messageId: 'badKey', data: { key } }); } } // (2) // report all invalid duplicates (same key, different message) if (values.length > 1) { for (let i = 1; i < values.length; i++) { if (context.getSourceCode().getText(values[i - 1].message) !== context.getSourceCode().getText(values[i].message)) { context.report({ loc: values[i].call.loc, messageId: 'duplicateKey', data: { key } }); } } } } } return { ['Literal']: (node: any) => collectDoubleQuotedStrings(node), ['ExpressionStatement[directive] Literal:exit']: (node: any) => doubleQuotedStringLiterals.delete(node), // localize(...) ['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize"]:exit']: (node: any) => visitLocalizeCall(node), // localize2(...) ['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize2"]:exit']: (node: any) => visitLocalizeCall(node), // vscode.l10n.t(...) ['CallExpression[callee.type="MemberExpression"][callee.object.property.name="l10n"][callee.property.name="t"]:exit']: (node: any) => visitL10NCall(node), // l10n.t(...) ['CallExpression[callee.object.name="l10n"][callee.property.name="t"]:exit']: (node: any) => visitL10NCall(node), ['CallExpression[callee.name="localize"][arguments.length>=2]:exit']: (node: any) => visitLocalizeCall(node), ['CallExpression[callee.name="localize2"][arguments.length>=2]:exit']: (node: any) => visitLocalizeCall(node), ['Program:exit']: reportBadStringsAndBadKeys, }; } }; ================================================ FILE: .eslint-plugin-local/code-no-unused-expressions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // FORKED FROM https://github.com/eslint/eslint/blob/b23ad0d789a909baf8d7c41a35bc53df932eaf30/lib/rules/no-unused-expressions.js // and added support for `OptionalCallExpression`, see https://github.com/facebook/create-react-app/issues/8107 and https://github.com/eslint/eslint/issues/12642 /** * @fileoverview Flag expressions in statement position that do not side effect * @author Michael Ficarra */ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; import * as ESTree from 'estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: 'suggestion', docs: { description: 'disallow unused expressions', category: 'Best Practices', recommended: false, url: 'https://eslint.org/docs/rules/no-unused-expressions' }, schema: [ { type: 'object', properties: { allowShortCircuit: { type: 'boolean', default: false }, allowTernary: { type: 'boolean', default: false }, allowTaggedTemplates: { type: 'boolean', default: false } }, additionalProperties: false } ] }, create(context: eslint.Rule.RuleContext) { const config = context.options[0] || {}, allowShortCircuit = config.allowShortCircuit || false, allowTernary = config.allowTernary || false, allowTaggedTemplates = config.allowTaggedTemplates || false; /** * @param node any node * @returns whether the given node structurally represents a directive */ function looksLikeDirective(node: TSESTree.Node): boolean { return node.type === 'ExpressionStatement' && node.expression.type === 'Literal' && typeof node.expression.value === 'string'; } /** * @param predicate ([a] -> Boolean) the function used to make the determination * @param list the input list * @returns the leading sequence of members in the given list that pass the given predicate */ function takeWhile(predicate: (item: T) => boolean, list: T[]): T[] { for (let i = 0; i < list.length; ++i) { if (!predicate(list[i])) { return list.slice(0, i); } } return list.slice(); } /** * @param node a Program or BlockStatement node * @returns the leading sequence of directive nodes in the given node's body */ function directives(node: TSESTree.Program | TSESTree.BlockStatement): TSESTree.Node[] { return takeWhile(looksLikeDirective, node.body); } /** * @param node any node * @param ancestors the given node's ancestors * @returns whether the given node is considered a directive in its current position */ function isDirective(node: TSESTree.Node, ancestors: TSESTree.Node[]): boolean { const parent = ancestors[ancestors.length - 1], grandparent = ancestors[ancestors.length - 2]; return (parent.type === 'Program' || parent.type === 'BlockStatement' && (/Function/u.test(grandparent.type))) && directives(parent).indexOf(node) >= 0; } /** * Determines whether or not a given node is a valid expression. Recurses on short circuit eval and ternary nodes if enabled by flags. * @param node any node * @returns whether the given node is a valid expression */ function isValidExpression(node: TSESTree.Node): boolean { if (allowTernary) { // Recursive check for ternary and logical expressions if (node.type === 'ConditionalExpression') { return isValidExpression(node.consequent) && isValidExpression(node.alternate); } } if (allowShortCircuit) { if (node.type === 'LogicalExpression') { return isValidExpression(node.right); } } if (allowTaggedTemplates && node.type === 'TaggedTemplateExpression') { return true; } if (node.type === 'ExpressionStatement') { return isValidExpression(node.expression); } return /^(?:Assignment|OptionalCall|Call|New|Update|Yield|Await|Chain)Expression$/u.test(node.type) || (node.type === 'UnaryExpression' && ['delete', 'void'].indexOf(node.operator) >= 0); } return { ExpressionStatement(node: TSESTree.ExpressionStatement) { if (!isValidExpression(node.expression) && !isDirective(node, context.sourceCode.getAncestors(node))) { context.report({ node: node, message: `Expected an assignment or function call and instead saw an expression. ${node.expression}` }); } } }; } }; ================================================ FILE: .eslint-plugin-local/code-parameter-properties-must-have-explicit-accessibility.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; /** * Enforces that all parameter properties have an explicit access modifier (public, protected, private). * * This catches a common bug where a service is accidentally made public by simply writing: `readonly prop: Foo` */ export = new class implements eslint.Rule.RuleModule { create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { function check(inNode: any) { const node: TSESTree.TSParameterProperty = inNode; // For now, only apply to injected services const firstDecorator = node.decorators?.at(0); if ( firstDecorator?.expression.type !== 'Identifier' || !firstDecorator.expression.name.endsWith('Service') ) { return; } if (!node.accessibility) { context.report({ node: inNode, message: 'Parameter properties must have an explicit access modifier.' }); } } return { ['TSParameterProperty']: check, }; } }; ================================================ FILE: .eslint-plugin-local/code-translation-remind.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; import { readFileSync } from 'fs'; import { createImportRuleListener } from './utils'; export = new class TranslationRemind implements eslint.Rule.RuleModule { private static NLS_MODULE = 'vs/nls'; readonly meta: eslint.Rule.RuleMetaData = { messages: { missing: 'Please add \'{{resource}}\' to ./build/lib/i18n.resources.json file to use translations here.' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return createImportRuleListener((node, path) => this._checkImport(context, node, path)); } private _checkImport(context: eslint.Rule.RuleContext, node: TSESTree.Node, path: string) { if (path !== TranslationRemind.NLS_MODULE) { return; } const currentFile = context.getFilename(); const matchService = currentFile.match(/vs\/workbench\/services\/\w+/); const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/); if (!matchService && !matchPart) { return; } const resource = matchService ? matchService[0] : matchPart![0]; let resourceDefined = false; let json; try { json = readFileSync('./build/lib/i18n.resources.json', 'utf8'); } catch (e) { console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.'); return; } const workbenchResources = JSON.parse(json).workbench; workbenchResources.forEach((existingResource: any) => { if (existingResource.name === resource) { resourceDefined = true; return; } }); if (!resourceDefined) { context.report({ loc: node.loc, messageId: 'missing', data: { resource } }); } } }; ================================================ FILE: .eslint-plugin-local/index.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const glob = require('glob'); const path = require('path'); require('ts-node').register({ experimentalResolver: true, transpileOnly: true }); // Re-export all .ts files as rules const rules = {}; glob.sync(`${__dirname}/*.ts`).forEach((file) => { rules[path.basename(file, '.ts')] = require(file); }); exports.rules = rules; ================================================ FILE: .eslint-plugin-local/package.json ================================================ { "type": "commonjs" } ================================================ FILE: .eslint-plugin-local/tsconfig.json ================================================ { "compilerOptions": { "target": "es2020", "lib": [ "ES2020" ], "module": "commonjs", "esModuleInterop": true, "alwaysStrict": true, "allowJs": true, "strict": true, "exactOptionalPropertyTypes": false, "useUnknownInCatchVariables": false, "noUnusedLocals": true, "noUnusedParameters": true, "newLine": "lf", "noEmit": true }, "include": [ "**/*.ts", "**/*.js" ], "exclude": [ "node_modules/**" ] } ================================================ FILE: .eslint-plugin-local/utils.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export function createImportRuleListener(validateImport: (node: TSESTree.Literal, value: string) => any): eslint.Rule.RuleListener { function _checkImport(node: TSESTree.Node | null) { if (node && node.type === 'Literal' && typeof node.value === 'string') { validateImport(node, node.value); } } return { // import ??? from 'module' ImportDeclaration: (node: any) => { _checkImport((node).source); }, // import('module').then(...) OR await import('module') ['CallExpression[callee.type="Import"][arguments.length=1] > Literal']: (node: any) => { _checkImport(node); }, // import foo = ... ['TSImportEqualsDeclaration > TSExternalModuleReference > Literal']: (node: any) => { _checkImport(node); }, // export ?? from 'module' ExportAllDeclaration: (node: any) => { _checkImport((node).source); }, // export {foo} from 'module' ExportNamedDeclaration: (node: any) => { _checkImport((node).source); }, }; } ================================================ FILE: .eslint-plugin-local/vscode-dts-cancellation.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; export = new class ApiProviderNaming implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { noToken: 'Function lacks a cancellation token, preferable as last argument', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature[key.name=/^(provide|resolve).+/]']: (node: any) => { let found = false; for (const param of (node).params) { if (param.type === AST_NODE_TYPES.Identifier) { found = found || param.name === 'token'; } } if (!found) { context.report({ node, messageId: 'noToken' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-create-func.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils'; export = new class ApiLiteralOrTypes implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#creating-objects' }, messages: { sync: '`createXYZ`-functions are constructor-replacements and therefore must return sync', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSDeclareFunction Identifier[name=/create.*/]']: (node: any) => { const decl = (node).parent; if (decl.returnType?.typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference) { return; } if (decl.returnType.typeAnnotation.typeName.type !== AST_NODE_TYPES.Identifier) { return; } const ident = decl.returnType.typeAnnotation.typeName.name; if (ident === 'Promise' || ident === 'Thenable') { context.report({ node, messageId: 'sync' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-event-naming.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils'; export = new class ApiEventNaming implements eslint.Rule.RuleModule { private static _nameRegExp = /on(Did|Will)([A-Z][a-z]+)([A-Z][a-z]+)?/; readonly meta: eslint.Rule.RuleMetaData = { docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#event-naming' }, messages: { naming: 'Event names must follow this patten: `on[Did|Will]`', verb: 'Unknown verb \'{{verb}}\' - is this really a verb? Iff so, then add this verb to the configuration', subject: 'Unknown subject \'{{subject}}\' - This subject has not been used before but it should refer to something in the API', unknown: 'UNKNOWN event declaration, lint-rule needs tweaking' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const config = <{ allowed: string[]; verbs: string[] }>context.options[0]; const allowed = new Set(config.allowed); const verbs = new Set(config.verbs); return { ['TSTypeAnnotation TSTypeReference Identifier[name="Event"]']: (node: any) => { const def = (node).parent?.parent?.parent; const ident = this.getIdent(def); if (!ident) { // event on unknown structure... return context.report({ node, message: 'unknown' }); } if (allowed.has(ident.name)) { // configured exception return; } const match = ApiEventNaming._nameRegExp.exec(ident.name); if (!match) { context.report({ node: ident, messageId: 'naming' }); return; } // check that is spelled out (configured) as verb if (!verbs.has(match[2].toLowerCase())) { context.report({ node: ident, messageId: 'verb', data: { verb: match[2] } }); } // check that a subject (if present) has occurred if (match[3]) { const regex = new RegExp(match[3], 'ig'); const parts = context.getSourceCode().getText().split(regex); if (parts.length < 3) { context.report({ node: ident, messageId: 'subject', data: { subject: match[3] } }); } } } }; } private getIdent(def: TSESTree.Node | undefined): TSESTree.Identifier | undefined { if (!def) { return; } if (def.type === AST_NODE_TYPES.Identifier) { return def; } else if ((def.type === AST_NODE_TYPES.TSPropertySignature || def.type === AST_NODE_TYPES.PropertyDefinition) && def.key.type === AST_NODE_TYPES.Identifier) { return def.key; } return this.getIdent(def.parent); } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-interface-naming.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export = new class ApiInterfaceNaming implements eslint.Rule.RuleModule { private static _nameRegExp = /^I[A-Z]/; readonly meta: eslint.Rule.RuleMetaData = { messages: { naming: 'Interfaces must not be prefixed with uppercase `I`', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSInterfaceDeclaration Identifier']: (node: any) => { const name = (node).name; if (ApiInterfaceNaming._nameRegExp.test(name)) { context.report({ node, messageId: 'naming' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-literal-or-types.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export = new class ApiLiteralOrTypes implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#enums' }, messages: { useEnum: 'Use enums, not literal-or-types', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSTypeAnnotation TSUnionType']: (node: any) => { if ((node).types.every(value => value.type === 'TSLiteralType')) { context.report({ node: node, messageId: 'useEnum' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-provider-naming.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export = new class ApiProviderNaming implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { naming: 'A provider should only have functions like provideXYZ or resolveXYZ', }, schema: false, }; private static _providerFunctionNames = /^(provide|resolve|prepare).+/; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const config = <{ allowed: string[] }>context.options[0]; const allowed = new Set(config.allowed); return { ['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature']: (node: any) => { const interfaceName = ((node).parent?.parent).id.name; if (allowed.has(interfaceName)) { // allowed return; } const methodName = ((node).key).name; if (!ApiProviderNaming._providerFunctionNames.test(methodName)) { context.report({ node, messageId: 'naming' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-string-type-literals.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/utils'; export = new class ApiTypeDiscrimination implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines' }, messages: { noTypeDiscrimination: 'Do not use type discrimination properties' }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSPropertySignature[optional=false] TSTypeAnnotation TSLiteralType Literal']: (node: any) => { const raw = String((node).raw); if (/^('|").*\1$/.test(raw)) { context.report({ node: node, messageId: 'noTypeDiscrimination' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-use-export.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TSESTree } from '@typescript-eslint/utils'; import * as eslint from 'eslint'; export = new class VscodeDtsUseExport implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { useExport: `Public api types must use 'export'`, }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSModuleDeclaration :matches(TSInterfaceDeclaration, ClassDeclaration, VariableDeclaration, TSEnumDeclaration, TSTypeAliasDeclaration)']: (node: any) => { const parent = (node).parent; if (parent && parent.type !== TSESTree.AST_NODE_TYPES.ExportNamedDeclaration) { context.report({ node, messageId: 'useExport' }); } } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-use-thenable.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class ApiEventNaming implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { usage: 'Use the Thenable-type instead of the Promise type', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { ['TSTypeAnnotation TSTypeReference Identifier[name="Promise"]']: (node: any) => { context.report({ node, messageId: 'usage', }); } }; } }; ================================================ FILE: .eslint-plugin-local/vscode-dts-vscode-in-comments.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; import type * as estree from 'estree'; export = new class ApiVsCodeInComments implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { comment: `Don't use the term 'vs code' in comments` }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { const sourceCode = context.getSourceCode(); return { ['Program']: (_node: any) => { for (const comment of sourceCode.getAllComments()) { if (comment.type !== 'Block') { continue; } if (!comment.range) { continue; } const startIndex = comment.range[0] + '/*'.length; const re = /vs code/ig; let match: RegExpExecArray | null; while ((match = re.exec(comment.value))) { // Allow using 'VS Code' in quotes if (comment.value[match.index - 1] === `'` && comment.value[match.index + match[0].length] === `'`) { continue; } // Types for eslint seem incorrect const start = sourceCode.getLocFromIndex(startIndex + match.index) as any as estree.Position; const end = sourceCode.getLocFromIndex(startIndex + match.index + match[0].length) as any as estree.Position; context.report({ messageId: 'comment', loc: { start, end } }); } } } }; } }; ================================================ FILE: .git-blame-ignore-revs ================================================ # https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt # https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view # mjbvz: Fix spacing 13f4f052582bcec3d6c6c6a70d995c9dee2cac13 # mjbvz: Add script to run build with noImplicitOverride ae1452eea678f5266ef513f22dacebb90955d6c9 # alexdima: Revert "bump version" 537ba0ef1791c090bb18bc68d727816c0451c117 # alexdima: bump version 387a0dcb82df729e316ca2518a9ed81a75482b18 # joaomoreno: add ghooks dev dependency 0dfc06e0f9de5925de792cdf9f0e6597bb25908f # joaomoreno: line endings 12ab70d329a13dd5b18d892cd40edd7138259bc3 # mjbvz: organize imports 494cbbd02d67e87727ec885f98d19551aa33aad1 a3cb14be7f2cceadb17adf843675b1a59537dbbd ee1655a82ebdfd38bf8792088a6602c69f7bbd94 # jrieken: new eslint-rule 4a130c40ed876644ed8af2943809d08221375408 # bpasero: ESM migration 6b924c51528e663dda5091a1493229a361676aca ================================================ FILE: .gitattributes ================================================ * text=auto LICENSE.txt eol=crlf ThirdPartyNotices.txt eol=crlf *.bat eol=crlf *.cmd eol=crlf *.ps1 eol=lf *.sh eol=lf *.rtf -text **/*.json linguist-language=jsonc ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false ================================================ FILE: .github/ISSUE_TEMPLATE/issue_template.md ================================================ --- name: Issue about: Submit an Issue to Void title: For VSCode-related issues (eg builds), please start the title with `[App]`. Otherwise, start it with `[Bug]` or `[Feature]`. --- 1. Press `Cmd+Shift+P` in Void, and type `Help: About`. Please paste the information here. Also let us know any other relevant details, like the model and provider you're using if applicable. 2. Describe the issue/feature here! ================================================ FILE: .github/scripts/issue_triage.py ================================================ #!/usr/bin/env python from __future__ import annotations import os, sys, json, datetime, pathlib, textwrap, requests from openai import OpenAI REPO = "voideditor/void" CACHE_FILE = pathlib.Path(".github/triage_cache.json") STAMP_FILE = pathlib.Path(".github/last_triage.txt") THEMES_MD = textwrap.dedent("""\ 1. 🔗 LLM Integration & Provider Support 2. 🖥 App Build & Platform Compatibility 3. 🎯 Prompt, Token, and Cost Management 4. 🧩 Editor UX & Interaction Design 5. 🤖 Agent & Automation Features 6. ⚙️ System Config & Environment Setup 7. 🗃 Meta: Feature Comparison, Structure, and Naming """).strip() client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) headers = {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"} # ───────── helpers ──────────────────────────────────────────────────────── def utc_iso_now() -> str: return datetime.datetime.utcnow().replace(microsecond=0, tzinfo=datetime.timezone.utc).isoformat() def read_stamp() -> str: return STAMP_FILE.read_text().strip() if STAMP_FILE.exists() else "1970-01-01T00:00:00Z" def save_stamp(): STAMP_FILE.parent.mkdir(parents=True, exist_ok=True) STAMP_FILE.write_text(utc_iso_now()) def load_cache() -> dict[int, str]: return json.loads(CACHE_FILE.read_text()) if CACHE_FILE.exists() else {} def save_cache(d: dict[int, str]): CACHE_FILE.parent.mkdir(parents=True, exist_ok=True) CACHE_FILE.write_text(json.dumps(d, indent=2)) def fetch_open_issues(since_iso: str | None = None) -> list[dict]: issues, page = [], 1 while True: url = ( f"https://api.github.com/repos/{REPO}/issues" f"?state=open&per_page=100&page={page}" + (f"&since={since_iso}" if since_iso else "") ) chunk = requests.get(url, headers=headers).json() if not chunk or (isinstance(chunk, dict) and chunk.get("message")): break issues.extend(i for i in chunk if "pull_request" not in i) page += 1 return issues # ───────── main ─────────────────────────────────────────────────────────── last_stamp = read_stamp() changed = fetch_open_issues(since_iso=last_stamp) # Fallback if **nothing** changed AND we have *no* existing output if not changed: cache_exists = CACHE_FILE.exists() wiki_exists = pathlib.Path("wiki/Issue-Categories.md").exists() if not cache_exists or not wiki_exists: # first run or someone wiped the wiki → build from scratch print("⏩ First run or empty wiki — fetching ALL open issues.", file=sys.stderr) changed = fetch_open_issues() # full list else: print(f"✅ No issues updated since {last_stamp}. Nothing to classify.", file=sys.stderr) save_stamp() sys.exit(0) # ---------------------------------------------------------------- prompt issue_lines = "\n".join(f"- {i['title']} ({i['html_url']})" for i in changed) prompt = textwrap.dedent(f"""\ You are an AI assistant helping triage GitHub issues into exactly 7 predefined themes. Each issue must go into exactly one of the themes below: {THEMES_MD} Format your output in Markdown like: ## 🎯 Prompt, Token, and Cost Management - [#123](https://github.com/org/repo/issues/123) – Title here Classify these issues: {issue_lines} """) resp = client.chat.completions.create( model="gpt-4.1", messages=[{"role": "user", "content": prompt}], temperature=0.2, ) md = resp.choices[0].message.content # ---------------------------------------------------------------- parse GPT new_map: dict[int, str] = {} current = None for ln in md.splitlines(): if ln.startswith("##"): current = ln.lstrip("# ").strip() elif ln.lstrip().startswith("- [#"): try: num = int(ln.split("[#")[1].split("]")[0]) new_map[num] = current except Exception: pass # ignore malformed lines cache = load_cache() cache.update(new_map) save_cache(cache) save_stamp() # ---------------------------------------------------------------- rebuild wiki order = [ "🔗 LLM Integration & Provider Support", "🖥 App Build & Platform Compatibility", "🎯 Prompt, Token, and Cost Management", "🧩 Editor UX & Interaction Design", "🤖 Agent & Automation Features", "⚙️ System Config & Environment Setup", "🗃 Meta: Feature Comparison, Structure, and Naming", ] sections: dict[str, list[int]] = {t: [] for t in order} # ── fetch ALL current open issues once (PRs filtered out) ──────────────── title_map: dict[int, tuple[str, str]] = {} open_now: set[int] = set() page = 1 while True: batch = fetch_open_issues(since_iso=None) if page == 1 else [] if not batch: break for it in batch: num = it["number"] title_map[num] = (it["title"], it["html_url"]) open_now.add(num) page += 1 # 🧹 drop any cached IDs that are no longer open issues (e.g., became a PR or were closed) for stale in set(cache) - open_now: del cache[stale] save_cache(cache) # persist cleaned cache # build sections from cleaned cache for num, theme in cache.items(): if theme in sections: # extra safety sections[theme].append(num) # ---------------------------------------------------------------- print roadmap for theme in order: issues = sections[theme] if issues: print(f"## {theme}") for n in sorted(issues): title, url = title_map.get(n, ("(missing)", f"https://github.com/{REPO}/issues/{n}")) print(f"- [#{n}]({url}) – {title}") print() ================================================ FILE: .github/workflows/triage.yml ================================================ name: Issue Triage to Wiki on: workflow_dispatch: schedule: - cron: '0 */6 * * *' # every 6 hrs (UTC) jobs: roadmap: runs-on: ubuntu-latest steps: # 1️⃣ Check out code (so the script and cache files are present) - name: Checkout code uses: actions/checkout@v3 with: fetch-depth: 1 # shallow clone # 2️⃣ Set up Python - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' # 3️⃣ Install dependencies - name: Install Python dependencies run: | pip install openai requests # 4️⃣ Clone your fork’s Wiki - name: Clone your fork's Wiki run: | git clone https://x-access-token:${{ secrets.WIKI_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki # 5️⃣ (Optional) Show repo tree for debugging - name: Show repo tree (debug) run: | echo "PWD: $(pwd)" ls -al ls -al .github/scripts || true ls -al void/.github/scripts || true # 6️⃣ Generate roadmap and push only if it changed - name: Generate roadmap directly into wiki run: | python .github/scripts/issue_triage.py > wiki/_new.md if ! cmp -s wiki/_new.md wiki/Issue-Categories.md ; then mv wiki/_new.md wiki/Issue-Categories.md cd wiki git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add Issue-Categories.md git commit -m "Auto-update Issue-Categories.md from GPT triage" git push else echo "No content change – skipping wiki update" fi env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} GITHUB_TOKEN: ${{ secrets.WIKI_TOKEN }} ================================================ FILE: .gitignore ================================================ .DS_Store .cache npm-debug.log Thumbs.db node_modules/ .build/ .vscode/extensions/**/out/ extensions/**/dist/ /out*/ /extensions/**/out/ build/node_modules coverage/ test_data/ test-results/ test-results.xml vscode.lsif vscode.db /.profile-oss /cli/target /cli/openssl product.overrides.json *.snap.actual .vscode-test # Void added these: .tmp/ .tmp2/ .tool-versions src/vs/workbench/contrib/void/browser/react/out/** src/vs/workbench/contrib/void/browser/react/src2/** ================================================ FILE: .idx/dev.nix ================================================ # Created for Void # To learn more about how to use Nix to configure your environment # see: https://developers.google.com/idx/guides/customize-idx-env {pkgs}: { # Which nixpkgs channel to use. channel = "stable-23.11"; # or "unstable" # Use https://search.nixos.org/packages to find packages packages = [ pkgs.nodejs_20 pkgs.yarn pkgs.nodePackages.pnpm pkgs.bun pkgs.gh ]; # Sets environment variables in the workspace env = {}; idx = { # Search for the extensions you want on https://open-vsx.org/ and use "publisher.id" extensions = [ # "vscodevim.vim" ]; workspace = { # Runs when a workspace is first created with this `dev.nix` file onCreate = { npm-install = "npm ci --no-audit --prefer-offline --no-progress --timing"; # Open editors for the following files by default, if they exist: default.openFiles = [ # Cover all the variations of language, src-dir, router (app/pages) "pages/index.tsx" "pages/index.jsx" "src/pages/index.tsx" "src/pages/index.jsx" "app/page.tsx" "app/page.jsx" "src/app/page.tsx" "src/app/page.jsx" ]; }; # To run something each time the workspace is (re)started, use the `onStart` hook }; # Enable previews and customize configuration previews = { enable = true; previews = { web = { command = ["npm" "run" "dev" "--" "--port" "$PORT" "--hostname" "0.0.0.0"]; manager = "web"; }; }; }; }; } ================================================ FILE: .lsifrc.json ================================================ { "project": "src/tsconfig.json", "source": "./package.json", "package": "package.json", "out": "vscode.lsif" } ================================================ FILE: .mailmap ================================================ Daniel Imms Daniel Imms Raymond Zhao Tyler Leonhardt Tyler Leonhardt João Moreno João Moreno ================================================ FILE: .mention-bot ================================================ { "maxReviewers": 2, "requiredOrgs": ["Microsoft"], "skipAlreadyAssignedPR": true, "skipAlreadyMentionedPR": true, "skipCollaboratorPR": true } ================================================ FILE: .npmrc ================================================ disturl="https://electronjs.org/headers" target="34.3.2" ms_build_id="11161073" runtime="electron" build_from_source="true" legacy-peer-deps="true" timeout=180000 ================================================ FILE: .nvmrc ================================================ 20.18.2 ================================================ FILE: .voidrules ================================================ This is a fork of the VSCode repo called Void. Most code we care about lives in src/vs/workbench/contrib/void. You may often need to explore the full repo to find relevant parts of code. Look for services and built-in functions that you might need to use to solve the problem. In typescript, do NOT cast to types if not neccessary. NEVER lazily cast to 'any'. Find the correct type to apply and use it. Do not add or remove semicolons to any of my files. Just go with convention and make the least number of changes. Never modify files outside src/vs/workbench/contrib/void without consulting with the user first. All types that map from a value A to B should be called bOfA. For example, if you create a hashmap that goes from toolId to toolName, it should be called toolNameOfToolId, etc. Do not run anything to validate your changes; tell the user what to do instead. ================================================ FILE: .vscode/cglicenses.schema.json ================================================ { "type": "array", "items": { "oneOf": [ { "type": "object", "required": [ "name", "prependLicenseText" ], "properties": { "name": { "type": "string", "description": "The name of the dependency" }, "fullLicenseText": { "type": "array", "description": "The complete license text of the dependency", "items": { "type": "string" } }, "prependLicenseText": { "type": "array", "description": "A piece of text to prepend to the auto-detected license text of the dependency", "items": { "type": "string" } } } }, { "type": "object", "required": [ "name", "fullLicenseText" ], "properties": { "name": { "type": "string", "description": "The name of the dependency" }, "fullLicenseText": { "type": "array", "description": "The complete license text of the dependency", "items": { "type": "string" } }, "prependLicenseText": { "type": "array", "description": "A piece of text to prepend to the auto-detected license text of the dependency", "items": { "type": "string" } } } }, { "type": "object", "required": [ "name", "fullLicenseTextUri" ], "properties": { "name": { "type": "string", "description": "The name of the dependency" }, "fullLicenseTextUri": { "type": "string", "description": "The URI to the license text of this repository", "format": "uri" }, "prependLicenseText": { "type": "array", "description": "A piece of text to prepend to the auto-detected license text of the dependency", "items": { "type": "string" } } } } ] } } ================================================ FILE: .vscode/extensions/vscode-selfhost-import-aid/.vscode/launch.json ================================================ { "configurations": [ { "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--enable-proposed-api=ms-vscode.vscode-selfhost-import-aid" ], "name": "Launch Extension", "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "request": "launch", "type": "extensionHost" } ] } ================================================ FILE: .vscode/extensions/vscode-selfhost-import-aid/.vscode/settings.json ================================================ { "editor.formatOnSave": true, "editor.defaultFormatter": "vscode.typescript-language-features", "editor.codeActionsOnSave": { "source.organizeImports": "always" } } ================================================ FILE: .vscode/extensions/vscode-selfhost-import-aid/package.json ================================================ { "name": "vscode-selfhost-import-aid", "displayName": "VS Code Selfhost Import Aid", "description": "Util to improve dealing with imports", "engines": { "vscode": "^1.88.0" }, "version": "0.0.1", "publisher": "ms-vscode", "categories": [ "Other" ], "activationEvents": [ "onLanguage:typescript" ], "main": "./out/extension.js", "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" }, "license": "MIT", "scripts": { "compile": "gulp compile-extension:vscode-selfhost-import-aid", "watch": "gulp watch-extension:vscode-selfhost-import-aid" }, "dependencies": { "typescript": "5.5.4" } } ================================================ FILE: .vscode/extensions/vscode-selfhost-import-aid/src/extension.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import * as ts from 'typescript'; import * as path from 'path'; export async function activate(context: vscode.ExtensionContext) { const fileIndex = new class { private _currentRun?: Thenable; private _disposables: vscode.Disposable[] = []; private readonly _index = new Map(); constructor() { const watcher = vscode.workspace.createFileSystemWatcher('**/*.ts', false, true, false); this._disposables.push(watcher.onDidChange(e => { this._index.set(e.toString(), e); })); this._disposables.push(watcher.onDidDelete(e => { this._index.delete(e.toString()); })); this._disposables.push(watcher); this._refresh(false); } dispose(): void { for (const disposable of this._disposables) { disposable.dispose(); } this._disposables = []; this._index.clear(); } async all(token: vscode.CancellationToken) { await Promise.race([this._currentRun, new Promise(resolve => token.onCancellationRequested(resolve))]); if (token.isCancellationRequested) { return undefined; } return Array.from(this._index.values()); } private _refresh(clear: boolean) { // TODO@jrieken LATEST API! findFiles2New this._currentRun = vscode.workspace.findFiles('src/vs/**/*.ts', '{**/node_modules/**,**/extensions/**}').then(all => { if (clear) { this._index.clear(); } for (const item of all) { this._index.set(item.toString(), item); } }); } }; const selector: vscode.DocumentSelector = 'typescript'; function findNodeAtPosition(document: vscode.TextDocument, node: ts.Node, position: vscode.Position): ts.Node | undefined { if (node.getStart() <= document.offsetAt(position) && node.getEnd() >= document.offsetAt(position)) { return ts.forEachChild(node, child => findNodeAtPosition(document, child, position)) || node; } return undefined; } function findImportAt(document: vscode.TextDocument, position: vscode.Position): ts.ImportDeclaration | undefined { const sourceFile = ts.createSourceFile(document.fileName, document.getText(), ts.ScriptTarget.Latest, true); const node = findNodeAtPosition(document, sourceFile, position); if (node && ts.isStringLiteral(node) && ts.isImportDeclaration(node.parent)) { return node.parent; } return undefined; } const completionProvider = new class implements vscode.CompletionItemProvider { async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { const index = document.getText().lastIndexOf(' from \''); if (index < 0 || document.positionAt(index).line < position.line) { // line after last import is before position // -> no completion, safe a parse call return undefined; } const node = findImportAt(document, position); if (!node) { return undefined; } const range = new vscode.Range(document.positionAt(node.moduleSpecifier.pos), document.positionAt(node.moduleSpecifier.end)); const uris = await fileIndex.all(token); if (!uris) { return undefined; } const result = new vscode.CompletionList(); result.isIncomplete = true; for (const item of uris) { if (!item.path.endsWith('.ts')) { continue; } let relativePath = path.relative(path.dirname(document.uri.path), item.path); relativePath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`; const label = path.basename(item.path, path.extname(item.path)); const insertText = ` '${relativePath.replace(/\.ts$/, '.js')}'`; const filterText = ` '${label}'`; const completion = new vscode.CompletionItem({ label: label, description: vscode.workspace.asRelativePath(item), }); completion.kind = vscode.CompletionItemKind.File; completion.insertText = insertText; completion.filterText = filterText; completion.range = range; result.items.push(completion); } return result; } }; class ImportCodeActions implements vscode.CodeActionProvider { static FixKind = vscode.CodeActionKind.QuickFix.append('esmImport'); static SourceKind = vscode.CodeActionKind.SourceFixAll.append('esmImport'); async provideCodeActions(document: vscode.TextDocument, range: vscode.Range | vscode.Selection, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { if (context.only && ImportCodeActions.SourceKind.intersects(context.only)) { return this._provideFixAll(document, context, token); } return this._provideFix(document, range, context, token); } private async _provideFixAll(document: vscode.TextDocument, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { const diagnostics = context.diagnostics .filter(d => d.code === 2307) .sort((a, b) => b.range.start.compareTo(a.range.start)); if (diagnostics.length === 0) { return undefined; } const uris = await fileIndex.all(token); if (!uris) { return undefined; } const result = new vscode.CodeAction(`Fix All ESM Imports`, ImportCodeActions.SourceKind); result.edit = new vscode.WorkspaceEdit(); result.diagnostics = []; for (const diag of diagnostics) { const actions = this._provideFixesForDiag(document, diag, uris); if (actions.length === 0) { console.log(`ESM: no fixes for "${diag.message}"`); continue; } if (actions.length > 1) { console.log(`ESM: more than one fix for "${diag.message}", taking first`); console.log(actions); } const [first] = actions; result.diagnostics.push(diag); for (const [uri, edits] of first.edit!.entries()) { result.edit.set(uri, edits); } } // console.log(result.edit.get(document.uri)); return [result]; } private async _provideFix(document: vscode.TextDocument, range: vscode.Range | vscode.Selection, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { const uris = await fileIndex.all(token); if (!uris) { return []; } const diag = context.diagnostics.find(d => d.code === 2307 && d.range.intersection(range)); return diag && this._provideFixesForDiag(document, diag, uris); } private _provideFixesForDiag(document: vscode.TextDocument, diag: vscode.Diagnostic, uris: Iterable): vscode.CodeAction[] { const node = findImportAt(document, diag.range.start)?.moduleSpecifier; if (!node || !ts.isStringLiteral(node)) { return []; } const nodeRange = new vscode.Range(document.positionAt(node.pos), document.positionAt(node.end)); const name = path.basename(node.text, path.extname(node.text)); const result: vscode.CodeAction[] = []; for (const item of uris) { if (path.basename(item.path, path.extname(item.path)) === name) { let relativePath = path.relative(path.dirname(document.uri.path), item.path).replace(/\.ts$/, '.js'); relativePath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`; const action = new vscode.CodeAction(`Fix to '${relativePath}'`, ImportCodeActions.FixKind); action.edit = new vscode.WorkspaceEdit(); action.edit.replace(document.uri, nodeRange, ` '${relativePath}'`); action.diagnostics = [diag]; result.push(action); } } return result; } } context.subscriptions.push(fileIndex); context.subscriptions.push(vscode.languages.registerCompletionItemProvider(selector, completionProvider)); context.subscriptions.push(vscode.languages.registerCodeActionsProvider(selector, new ImportCodeActions(), { providedCodeActionKinds: [ImportCodeActions.FixKind, ImportCodeActions.SourceKind] })); } ================================================ FILE: .vscode/extensions/vscode-selfhost-import-aid/tsconfig.json ================================================ { "extends": "../../../extensions/tsconfig.base.json", "compilerOptions": { "outDir": "./out", "types": [ "node", "mocha", ] }, "include": [ "src/**/*", "../../../src/vscode-dts/vscode.d.ts" ] } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/.vscode/launch.json ================================================ { "configurations": [ { "args": ["--extensionDevelopmentPath=${workspaceFolder}", "--enable-proposed-api=ms-vscode.vscode-selfhost-test-provider"], "name": "Launch Extension", "outFiles": ["${workspaceFolder}/out/**/*.js"], "request": "launch", "type": "extensionHost" } ] } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/.vscode/settings.json ================================================ { "editor.formatOnSave": true, "editor.defaultFormatter": "vscode.typescript-language-features", "editor.codeActionsOnSave": { "source.organizeImports": "always" } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/package.json ================================================ { "name": "vscode-selfhost-test-provider", "displayName": "VS Code Selfhost Test Provider", "description": "Test provider for the VS Code project", "enabledApiProposals": [ "testObserver", "testRelatedCode" ], "engines": { "vscode": "^1.88.0" }, "contributes": { "commands": [ { "command": "selfhost-test-provider.updateSnapshot", "title": "Update Snapshot", "category": "Testing", "icon": "$(merge)" }, { "command": "selfhost-test-provider.openFailureLog", "title": "Open Selfhost Failure Logs", "category": "Testing", "icon": "$(merge)" } ], "menus": { "commandPalette": [ { "command": "selfhost-test-provider.updateSnapshot", "when": "false" } ], "testing/message/context": [ { "command": "selfhost-test-provider.updateSnapshot", "group": "inline@1", "when": "testMessage == isSelfhostSnapshotMessage && !testResultOutdated" } ], "testing/message/content": [ { "command": "selfhost-test-provider.updateSnapshot", "when": "testMessage == isSelfhostSnapshotMessage && !testResultOutdated" } ] } }, "icon": "icon.png", "version": "0.4.0", "publisher": "ms-vscode", "categories": [ "Other" ], "activationEvents": [ "workspaceContains:src/vs/loader.js" ], "workspaceTrust": { "request": "onDemand", "description": "Trust is required to execute tests in the workspace." }, "main": "./out/extension.js", "prettier": { "printWidth": 100, "singleQuote": true, "tabWidth": 2, "arrowParens": "avoid" }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" }, "license": "MIT", "scripts": { "compile": "gulp compile-extension:vscode-selfhost-test-provider", "watch": "gulp watch-extension:vscode-selfhost-test-provider", "test": "npx mocha --ui tdd 'out/*.test.js'" }, "devDependencies": { "@types/mocha": "^10.0.6", "@types/node": "20.x" }, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "ansi-styles": "^5.2.0", "cockatiel": "^3.1.3", "istanbul-to-vscode": "^2.0.1" } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/coverageProvider.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { IstanbulCoverageContext } from 'istanbul-to-vscode'; import * as vscode from 'vscode'; import { SearchStrategy, SourceLocationMapper, SourceMapStore } from './testOutputScanner'; import { IScriptCoverage, OffsetToPosition, RangeCoverageTracker } from './v8CoverageWrangling'; export const istanbulCoverageContext = new IstanbulCoverageContext(); /** * Tracks coverage in per-script coverage mode. There are two modes of coverage * in this extension: generic istanbul reports, and reports from the runtime * sent before and after each test case executes. This handles the latter. */ export class PerTestCoverageTracker { private readonly scripts = new Map(); constructor(private readonly maps: SourceMapStore) { } public add(coverage: IScriptCoverage, test?: vscode.TestItem) { const script = this.scripts.get(coverage.scriptId); if (script) { return script.add(coverage, test); } // ignore internals and node_modules if (!coverage.url.startsWith('file://') || coverage.url.includes('node_modules')) { return; } if (!coverage.source) { throw new Error('expected to have source the first time a script is seen'); } const src = new Script(vscode.Uri.parse(coverage.url), coverage.source, this.maps); this.scripts.set(coverage.scriptId, src); src.add(coverage, test); } public async report(run: vscode.TestRun) { await Promise.all(Array.from(this.scripts.values()).map(s => s.report(run))); } } class Script { private converter: OffsetToPosition; /** Tracking the overall coverage for the file */ private overall = new ScriptCoverageTracker(); /** Range tracking per-test item */ private readonly perItem = new Map(); constructor( public readonly uri: vscode.Uri, source: string, private readonly maps: SourceMapStore ) { this.converter = new OffsetToPosition(source); } public add(coverage: IScriptCoverage, test?: vscode.TestItem) { this.overall.add(coverage); if (test) { const p = new ScriptCoverageTracker(); p.add(coverage); this.perItem.set(test, p); } } public async report(run: vscode.TestRun) { const mapper = await this.maps.getSourceLocationMapper(this.uri.toString()); const originalUri = (await this.maps.getSourceFile(this.uri.toString())) || this.uri; run.addCoverage(this.overall.report(originalUri, this.converter, mapper, this.perItem)); } } class ScriptCoverageTracker { private coverage = new RangeCoverageTracker(); public add(coverage: IScriptCoverage) { for (const range of RangeCoverageTracker.initializeBlocks(coverage.functions)) { this.coverage.setCovered(range.start, range.end, range.covered); } } public *toDetails( uri: vscode.Uri, convert: OffsetToPosition, mapper: SourceLocationMapper | undefined, ) { for (const range of this.coverage) { if (range.start === range.end) { continue; } const startCov = convert.toLineColumn(range.start); let start = new vscode.Position(startCov.line, startCov.column); const endCov = convert.toLineColumn(range.end); let end = new vscode.Position(endCov.line, endCov.column); if (mapper) { const startMap = mapper(start.line, start.character, SearchStrategy.FirstAfter); const endMap = startMap && mapper(end.line, end.character, SearchStrategy.FirstBefore); if (!endMap || uri.toString().toLowerCase() !== endMap.uri.toString().toLowerCase()) { continue; } start = startMap.range.start; end = endMap.range.end; } for (let i = start.line; i <= end.line; i++) { yield new vscode.StatementCoverage( range.covered, new vscode.Range( new vscode.Position(i, i === start.line ? start.character : 0), new vscode.Position(i, i === end.line ? end.character : Number.MAX_SAFE_INTEGER) ) ); } } } /** * Generates the script's coverage for the test run. * * If a source location mapper is given, it assumes the `uri` is the mapped * URI, and that any unmapped locations/outside the URI should be ignored. */ public report( uri: vscode.Uri, convert: OffsetToPosition, mapper: SourceLocationMapper | undefined, items: Map, ): V8CoverageFile { const file = new V8CoverageFile(uri, items, convert, mapper); for (const detail of this.toDetails(uri, convert, mapper)) { file.add(detail); } return file; } } export class V8CoverageFile extends vscode.FileCoverage { public details: vscode.StatementCoverage[] = []; constructor( uri: vscode.Uri, private readonly perTest: Map, private readonly convert: OffsetToPosition, private readonly mapper: SourceLocationMapper | undefined, ) { super(uri, { covered: 0, total: 0 }, undefined, undefined, [...perTest.keys()]); } public add(detail: vscode.StatementCoverage) { this.details.push(detail); this.statementCoverage.total++; if (detail.executed) { this.statementCoverage.covered++; } } public testDetails(test: vscode.TestItem): vscode.FileCoverageDetail[] { const t = this.perTest.get(test); return t ? [...t.toDetails(this.uri, this.convert, this.mapper)] : []; } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/debounce.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * Debounces the function call for an interval. */ export function debounce(duration: number, fn: () => void): (() => void) & { clear: () => void } { let timeout: NodeJS.Timeout | void; const debounced = () => { if (timeout !== undefined) { clearTimeout(timeout); } timeout = setTimeout(() => { timeout = undefined; fn(); }, duration); }; debounced.clear = () => { if (timeout) { clearTimeout(timeout); timeout = undefined; } }; return debounced; } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/extension.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { randomBytes } from 'crypto'; import { tmpdir } from 'os'; import * as path from 'path'; import * as vscode from 'vscode'; import { V8CoverageFile } from './coverageProvider'; import { FailingDeepStrictEqualAssertFixer } from './failingDeepStrictEqualAssertFixer'; import { FailureTracker } from './failureTracker'; import { registerSnapshotUpdate } from './snapshot'; import { scanTestOutput } from './testOutputScanner'; import { TestCase, TestFile, clearFileDiagnostics, guessWorkspaceFolder, itemData, } from './testTree'; import { BrowserTestRunner, PlatformTestRunner, VSCodeTestRunner } from './vscodeTestRunner'; import { ImportGraph } from './importGraph'; const TEST_FILE_PATTERN = 'src/vs/**/*.{test,integrationTest}.ts'; const getWorkspaceFolderForTestFile = (uri: vscode.Uri) => (uri.path.endsWith('.test.ts') || uri.path.endsWith('.integrationTest.ts')) && uri.path.includes('/src/vs/') ? vscode.workspace.getWorkspaceFolder(uri) : undefined; const browserArgs: [name: string, arg: string][] = [ ['Chrome', 'chromium'], ['Firefox', 'firefox'], ['Webkit', 'webkit'], ]; type FileChangeEvent = { uri: vscode.Uri; removed: boolean }; export async function activate(context: vscode.ExtensionContext) { const ctrl = vscode.tests.createTestController('selfhost-test-controller', 'VS Code Tests'); const fileChangedEmitter = new vscode.EventEmitter(); context.subscriptions.push(vscode.tests.registerTestFollowupProvider({ async provideFollowup(_result, test, taskIndex, messageIndex, _token) { return [{ title: '$(sparkle) Fix with Copilot', command: 'github.copilot.tests.fixTestFailure', arguments: [{ source: 'peekFollowup', test, message: test.taskStates[taskIndex].messages[messageIndex] }] }]; }, })); let initialWatchPromise: Promise | undefined; const resolveHandler = async (test?: vscode.TestItem) => { if (!test) { if (!initialWatchPromise) { initialWatchPromise = startWatchingWorkspace(ctrl, fileChangedEmitter); context.subscriptions.push(await initialWatchPromise); } else { await initialWatchPromise; } return; } const data = itemData.get(test); if (data instanceof TestFile) { // No need to watch this, updates will be triggered on file changes // either by the text document or file watcher. await data.updateFromDisk(ctrl, test); } }; ctrl.resolveHandler = resolveHandler; guessWorkspaceFolder().then(folder => { if (!folder) { return; } const graph = new ImportGraph( folder.uri, async () => { await resolveHandler(); return [...ctrl.items].map(([, item]) => item); }, uri => ctrl.items.get(uri.toString().toLowerCase())); ctrl.relatedCodeProvider = graph; if (context.storageUri) { context.subscriptions.push(new FailureTracker(context.storageUri.fsPath, folder.uri.fsPath)); } context.subscriptions.push(fileChangedEmitter.event(e => graph.didChange(e.uri, e.removed))); }); const createRunHandler = ( runnerCtor: { new(folder: vscode.WorkspaceFolder): VSCodeTestRunner }, kind: vscode.TestRunProfileKind, args: string[] = [] ) => { const doTestRun = async ( req: vscode.TestRunRequest, cancellationToken: vscode.CancellationToken ) => { const folder = await guessWorkspaceFolder(); if (!folder) { return; } const runner = new runnerCtor(folder); const map = await getPendingTestMap(ctrl, req.include ?? gatherTestItems(ctrl.items)); const task = ctrl.createTestRun(req); for (const test of map.values()) { task.enqueued(test); } let coverageDir: string | undefined; let currentArgs = args; if (kind === vscode.TestRunProfileKind.Coverage) { // todo: browser runs currently don't support per-test coverage if (args.includes('--browser')) { coverageDir = path.join( tmpdir(), `vscode-test-coverage-${randomBytes(8).toString('hex')}` ); currentArgs = [ ...currentArgs, '--coverage', '--coveragePath', coverageDir, '--coverageFormats', 'json', ]; } else { currentArgs = [...currentArgs, '--per-test-coverage']; } } return await scanTestOutput( map, task, kind === vscode.TestRunProfileKind.Debug ? await runner.debug(task, currentArgs, req.include) : await runner.run(currentArgs, req.include), coverageDir, cancellationToken ); }; return async (req: vscode.TestRunRequest, cancellationToken: vscode.CancellationToken) => { if (!req.continuous) { return doTestRun(req, cancellationToken); } const queuedFiles = new Set(); let debounced: NodeJS.Timeout | undefined; const listener = fileChangedEmitter.event(({ uri, removed }) => { clearTimeout(debounced); if (req.include && !req.include.some(i => i.uri?.toString() === uri.toString())) { return; } if (removed) { queuedFiles.delete(uri.toString()); } else { queuedFiles.add(uri.toString()); } debounced = setTimeout(() => { const include = req.include?.filter(t => t.uri && queuedFiles.has(t.uri?.toString())) ?? [...queuedFiles] .map(f => getOrCreateFile(ctrl, vscode.Uri.parse(f))) .filter((f): f is vscode.TestItem => !!f); queuedFiles.clear(); doTestRun( new vscode.TestRunRequest(include, req.exclude, req.profile, true), cancellationToken ); }, 1000); }); cancellationToken.onCancellationRequested(() => { clearTimeout(debounced); listener.dispose(); }); }; }; ctrl.createRunProfile( 'Run in Electron', vscode.TestRunProfileKind.Run, createRunHandler(PlatformTestRunner, vscode.TestRunProfileKind.Run), true, undefined, true ); ctrl.createRunProfile( 'Debug in Electron', vscode.TestRunProfileKind.Debug, createRunHandler(PlatformTestRunner, vscode.TestRunProfileKind.Debug), true, undefined, true ); const coverage = ctrl.createRunProfile( 'Coverage in Electron', vscode.TestRunProfileKind.Coverage, createRunHandler(PlatformTestRunner, vscode.TestRunProfileKind.Coverage), true, undefined, true ); coverage.loadDetailedCoverage = async (_run, coverage) => coverage instanceof V8CoverageFile ? coverage.details : []; coverage.loadDetailedCoverageForTest = async (_run, coverage, test) => coverage instanceof V8CoverageFile ? coverage.testDetails(test) : []; for (const [name, arg] of browserArgs) { const cfg = ctrl.createRunProfile( `Run in ${name}`, vscode.TestRunProfileKind.Run, createRunHandler(BrowserTestRunner, vscode.TestRunProfileKind.Run, [' --browser', arg]), undefined, undefined, true ); cfg.configureHandler = () => vscode.window.showInformationMessage(`Configuring ${name}`); ctrl.createRunProfile( `Debug in ${name}`, vscode.TestRunProfileKind.Debug, createRunHandler(BrowserTestRunner, vscode.TestRunProfileKind.Debug, [ '--browser', arg, '--debug-browser', ]), undefined, undefined, true ); } function updateNodeForDocument(e: vscode.TextDocument) { const node = getOrCreateFile(ctrl, e.uri); const data = node && itemData.get(node); if (data instanceof TestFile) { data.updateFromContents(ctrl, e.getText(), node!); } } for (const document of vscode.workspace.textDocuments) { updateNodeForDocument(document); } context.subscriptions.push( ctrl, fileChangedEmitter.event(({ uri, removed }) => { if (!removed) { const node = getOrCreateFile(ctrl, uri); if (node) { ctrl.invalidateTestResults(); } } }), vscode.workspace.onDidOpenTextDocument(updateNodeForDocument), vscode.workspace.onDidChangeTextDocument(e => updateNodeForDocument(e.document)), registerSnapshotUpdate(ctrl), new FailingDeepStrictEqualAssertFixer() ); } export function deactivate() { // no-op } function getOrCreateFile( controller: vscode.TestController, uri: vscode.Uri ): vscode.TestItem | undefined { const folder = getWorkspaceFolderForTestFile(uri); if (!folder) { return undefined; } const data = new TestFile(uri, folder); const existing = controller.items.get(data.getId()); if (existing) { return existing; } const file = controller.createTestItem(data.getId(), data.getLabel(), uri); controller.items.add(file); file.canResolveChildren = true; itemData.set(file, data); return file; } function gatherTestItems(collection: vscode.TestItemCollection) { const items: vscode.TestItem[] = []; collection.forEach(item => items.push(item)); return items; } async function startWatchingWorkspace( controller: vscode.TestController, fileChangedEmitter: vscode.EventEmitter ) { const workspaceFolder = await guessWorkspaceFolder(); if (!workspaceFolder) { return new vscode.Disposable(() => undefined); } const pattern = new vscode.RelativePattern(workspaceFolder, TEST_FILE_PATTERN); const watcher = vscode.workspace.createFileSystemWatcher(pattern); watcher.onDidCreate(uri => { getOrCreateFile(controller, uri); fileChangedEmitter.fire({ removed: false, uri }); }); watcher.onDidChange(uri => fileChangedEmitter.fire({ removed: false, uri })); watcher.onDidDelete(uri => { fileChangedEmitter.fire({ removed: true, uri }); clearFileDiagnostics(uri); controller.items.delete(uri.toString()); }); for (const file of await vscode.workspace.findFiles(pattern)) { getOrCreateFile(controller, file); } return watcher; } async function getPendingTestMap(ctrl: vscode.TestController, tests: Iterable) { const queue = [tests]; const titleMap = new Map(); while (queue.length) { for (const item of queue.pop()!) { const data = itemData.get(item); if (data instanceof TestFile) { if (!data.hasBeenRead) { await data.updateFromDisk(ctrl, item); } queue.push(gatherTestItems(item.children)); } else if (data instanceof TestCase) { titleMap.set(data.fullName, item); } else { queue.push(gatherTestItems(item.children)); } } } return titleMap; } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/failingDeepStrictEqualAssertFixer.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as ts from 'typescript'; import { commands, Disposable, languages, Position, Range, TestMessage, TestResultSnapshot, TestRunResult, tests, TextDocument, Uri, workspace, WorkspaceEdit, } from 'vscode'; import { memoizeLast } from './memoize'; import { getTestMessageMetadata } from './metadata'; const enum Constants { FixCommandId = 'selfhost-test.fix-test', } export class FailingDeepStrictEqualAssertFixer { private disposables: Disposable[] = []; constructor() { this.disposables.push( commands.registerCommand(Constants.FixCommandId, async (uri: Uri, position: Position) => { const document = await workspace.openTextDocument(uri); const failingAssertion = detectFailingDeepStrictEqualAssertion(document, position); if (!failingAssertion) { return; } const expectedValueNode = failingAssertion.assertion.expectedValue; if (!expectedValueNode) { return; } const start = document.positionAt(expectedValueNode.getStart()); const end = document.positionAt(expectedValueNode.getEnd()); const edit = new WorkspaceEdit(); edit.replace(uri, new Range(start, end), formatJsonValue(failingAssertion.actualJSONValue)); await workspace.applyEdit(edit); }) ); this.disposables.push( languages.registerCodeActionsProvider('typescript', { provideCodeActions: (document, range) => { const failingAssertion = detectFailingDeepStrictEqualAssertion(document, range.start); if (!failingAssertion) { return undefined; } return [ { title: 'Fix Expected Value', command: Constants.FixCommandId, arguments: [document.uri, range.start], }, ]; }, }) ); } dispose() { for (const d of this.disposables) { d.dispose(); } } } const identifierLikeRe = /^[$a-z_][a-z0-9_$]*$/i; const tsPrinter = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const formatJsonValue = (value: unknown) => { if (typeof value !== 'object') { return JSON.stringify(value); } const src = ts.createSourceFile('', `(${JSON.stringify(value)})`, ts.ScriptTarget.ES5, true); const outerExpression = src.statements[0] as ts.ExpressionStatement; const parenExpression = outerExpression.expression as ts.ParenthesizedExpression; const unquoted = ts.transform(parenExpression, [ context => (node: ts.Node) => { const visitor = (node: ts.Node): ts.Node => ts.isPropertyAssignment(node) && ts.isStringLiteralLike(node.name) && identifierLikeRe.test(node.name.text) ? ts.factory.createPropertyAssignment( ts.factory.createIdentifier(node.name.text), ts.visitNode(node.initializer, visitor) as ts.Expression ) : ts.isStringLiteralLike(node) && node.text === '[undefined]' ? ts.factory.createIdentifier('undefined') : ts.visitEachChild(node, visitor, context); return ts.visitNode(node, visitor); }, ]); return tsPrinter.printNode(ts.EmitHint.Expression, unquoted.transformed[0], src); }; /** Parses the source file, memoizing the last document so cursor moves are efficient */ const parseSourceFile = memoizeLast((text: string) => ts.createSourceFile('', text, ts.ScriptTarget.ES5, true) ); const assertionFailureMessageRe = /^Expected values to be strictly (deep-)?equal:/; /** Gets information about the failing assertion at the poisition, if any. */ function detectFailingDeepStrictEqualAssertion( document: TextDocument, position: Position ): { assertion: StrictEqualAssertion; actualJSONValue: unknown } | undefined { const sf = parseSourceFile(document.getText()); const offset = document.offsetAt(position); const assertion = StrictEqualAssertion.atPosition(sf, offset); if (!assertion) { return undefined; } const startLine = document.positionAt(assertion.offsetStart).line; const messages = getAllTestStatusMessagesAt(document.uri, startLine); const strictDeepEqualMessage = messages.find(m => assertionFailureMessageRe.test(typeof m.message === 'string' ? m.message : m.message.value) ); if (!strictDeepEqualMessage) { return undefined; } const metadata = getTestMessageMetadata(strictDeepEqualMessage); if (!metadata) { return undefined; } return { assertion: assertion, actualJSONValue: metadata.actualValue, }; } class StrictEqualAssertion { /** * Extracts the assertion at the current node, if it is one. */ public static fromNode(node: ts.Node): StrictEqualAssertion | undefined { if (!ts.isCallExpression(node)) { return undefined; } const expr = node.expression.getText(); if (expr !== 'assert.deepStrictEqual' && expr !== 'assert.strictEqual') { return undefined; } return new StrictEqualAssertion(node); } /** * Gets the equals assertion at the given offset in the file. */ public static atPosition(sf: ts.SourceFile, offset: number): StrictEqualAssertion | undefined { let node = findNodeAt(sf, offset); while (node.parent) { const obj = StrictEqualAssertion.fromNode(node); if (obj) { return obj; } node = node.parent; } return undefined; } constructor(private readonly expression: ts.CallExpression) { } /** Gets the expected value */ public get expectedValue(): ts.Expression | undefined { return this.expression.arguments[1]; } /** Gets the position of the assertion expression. */ public get offsetStart(): number { return this.expression.getStart(); } } function findNodeAt(parent: ts.Node, offset: number): ts.Node { for (const child of parent.getChildren()) { if (child.getStart() <= offset && offset <= child.getEnd()) { return findNodeAt(child, offset); } } return parent; } function getAllTestStatusMessagesAt(uri: Uri, lineNumber: number): TestMessage[] { if (tests.testResults.length === 0) { return []; } const run = tests.testResults[0]; const snapshots = getTestResultsWithUri(run, uri); const result: TestMessage[] = []; for (const snapshot of snapshots) { for (const m of snapshot.taskStates[0].messages) { if ( m.location && m.location.range.start.line <= lineNumber && lineNumber <= m.location.range.end.line ) { result.push(m); } } } return result; } function getTestResultsWithUri(testRun: TestRunResult, uri: Uri): TestResultSnapshot[] { const results: TestResultSnapshot[] = []; const walk = (r: TestResultSnapshot) => { for (const c of r.children) { walk(c); } if (r.uri?.toString() === uri.toString()) { results.push(r); } }; for (const r of testRun.results) { walk(r); } return results; } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/failureTracker.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawn } from 'child_process'; import { existsSync, mkdirSync, renameSync } from 'fs'; import { readFile, writeFile } from 'fs/promises'; import { dirname, join } from 'path'; import * as vscode from 'vscode'; interface IGitState { commitId: string; tracked: string; untracked: Record; } interface ITrackedRemediation { snapshot: vscode.TestResultSnapshot; failing: IGitState; passing: IGitState; } const MAX_FAILURES = 10; export class FailureTracker { private readonly disposables: vscode.Disposable[] = []; private readonly lastFailed = new Map< string, { snapshot: vscode.TestResultSnapshot; failing: IGitState } >(); private readonly logFile: string; private logs?: ITrackedRemediation[]; constructor(storageLocation: string, private readonly rootDir: string) { this.logFile = join(storageLocation, '.build/vscode-test-failures.json'); mkdirSync(dirname(this.logFile), { recursive: true }); const oldLogFile = join(rootDir, '.build/vscode-test-failures.json'); if (existsSync(oldLogFile)) { try { renameSync(oldLogFile, this.logFile); } catch { // ignore } } this.disposables.push( vscode.commands.registerCommand('selfhost-test-provider.openFailureLog', async () => { const doc = await vscode.workspace.openTextDocument(this.logFile); await vscode.window.showTextDocument(doc); }) ); this.disposables.push( vscode.tests.onDidChangeTestResults(() => { const last = vscode.tests.testResults[0]; if (!last) { return; } let gitState: Promise | undefined; const getGitState = () => gitState ?? (gitState = this.captureGitState()); const queue = [last.results]; for (let i = 0; i < queue.length; i++) { for (const snapshot of queue[i]) { // only interested in states of leaf tests if (snapshot.children.length) { queue.push(snapshot.children); continue; } const key = `${snapshot.uri}/${snapshot.id}`; const prev = this.lastFailed.get(key); if (snapshot.taskStates.some(s => s.state === vscode.TestResultState.Failed)) { // unset the parent to avoid a circular JSON structure: getGitState().then(s => this.lastFailed.set(key, { snapshot: { ...snapshot, parent: undefined }, failing: s, }) ); } else if (prev) { this.lastFailed.delete(key); getGitState().then(s => this.append({ ...prev, passing: s })); } } } }) ); } private async append(log: ITrackedRemediation) { if (!this.logs) { try { this.logs = JSON.parse(await readFile(this.logFile, 'utf-8')); } catch { this.logs = []; } } const logs = this.logs!; logs.push(log); if (logs.length > MAX_FAILURES) { logs.splice(0, logs.length - MAX_FAILURES); } await writeFile(this.logFile, JSON.stringify(logs, undefined, 2)); } private async captureGitState() { const [commitId, tracked, untracked] = await Promise.all([ this.exec('git', ['rev-parse', 'HEAD']), this.exec('git', ['diff', 'HEAD']), this.exec('git', ['ls-files', '--others', '--exclude-standard']).then(async output => { const mapping: Record = {}; await Promise.all( output .trim() .split('\n') .map(async f => { mapping[f] = await readFile(join(this.rootDir, f), 'utf-8'); }) ); return mapping; }), ]); return { commitId, tracked, untracked }; } public dispose() { this.disposables.forEach(d => d.dispose()); } private exec(command: string, args: string[]): Promise { return new Promise((resolve, reject) => { const child = spawn(command, args, { stdio: 'pipe', cwd: this.rootDir }); let output = ''; child.stdout.setEncoding('utf-8').on('data', b => (output += b)); child.stderr.setEncoding('utf-8').on('data', b => (output += b)); child.on('error', reject); child.on('exit', code => code === 0 ? resolve(output) : reject(new Error(`Failed with error code ${code}\n${output}`)) ); }); } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/importGraph.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { join } from 'path'; import * as vscode from 'vscode'; import { bulkhead } from 'cockatiel'; import { promises as fs } from 'fs'; const maxInt32 = 2 ** 31 - 1; // limit concurrency to avoid overwhelming the filesystem during discovery const discoverLimiter = bulkhead(8, Infinity); // Max import distance when listing related code to improve relevancy. const defaultMaxDistance = 3; /** * Maintains a graph of imports in the codebase. This works lazily resolving * imports and re-parsing files only on request. * * This is a rough, file-level graph derived from simple regex matching on * source files to avoid having to parse the AST of every file in the codebase, * which is possible but more intensive. (See: all the years of work from the * TS language server.) * * A more advanced implementation could use references from the language server. */ export class ImportGraph implements vscode.TestRelatedCodeProvider { private graph = new Map(); constructor( private readonly root: vscode.Uri, private readonly discoverWorkspaceTests: () => Thenable, private readonly getTestNodeForDoc: (uri: vscode.Uri) => vscode.TestItem | undefined, ) { } /** @inheritdoc */ public async provideRelatedCode(test: vscode.TestItem, token: vscode.CancellationToken): Promise { // this is kind of a stub for this implementation. Naive following imports // isn't that useful for finding a test's related code. const node = await this.discoverOutwards(test.uri, new Set(), defaultMaxDistance, token); if (!node) { return []; } const imports = new Set(); const queue = [{ distance: 0, next: node.imports }]; while (queue.length) { const { distance, next } = queue.shift()!; for (const imp of next) { if (imports.has(imp.path)) { continue; } imports.add(imp.path); if (distance < defaultMaxDistance) { queue.push({ next: imp.imports, distance: distance + 1 }); } } } return [...imports].map(importPath => new vscode.Location( vscode.Uri.file(join(this.root.fsPath, 'src', `${importPath}.ts`)), new vscode.Range(0, 0, maxInt32, 0), ), ); } /** @inheritdoc */ public async provideRelatedTests(document: vscode.TextDocument, _position: vscode.Position, token: vscode.CancellationToken): Promise { // Expand all known tests to ensure imports of this file are realized. const rootTests = await this.discoverWorkspaceTests(); const seen = new Set(); await Promise.all(rootTests.map(v => v.uri && this.discoverOutwards(v.uri, seen, defaultMaxDistance, token))); const node = this.getNode(document.uri); if (!node) { return []; } const tests: vscode.TestItem[] = []; const queue: { next: FileNode; distance: number }[] = [{ next: node, distance: 0 }]; const visited = new Set(); let maxDistance = Infinity; while (queue.length) { const { next, distance } = queue.shift()!; if (visited.has(next)) { continue; } visited.add(next); const testForDoc = this.getTestNodeForDoc(next.uri); if (testForDoc) { tests.push(testForDoc); // only look for tests half again as far away as the closest test to keep things relevant if (!Number.isFinite(maxDistance)) { maxDistance = distance * 3 / 2; } } if (distance < maxDistance) { for (const importedByNode of next.importedBy) { queue.push({ next: importedByNode, distance: distance + 1 }); } } } return tests; } public didChange(uri: vscode.Uri, deleted: boolean) { const rel = this.uriToImportPath(uri); const node = rel && this.graph.get(rel); if (!node) { return; } if (deleted) { this.graph.delete(rel); for (const imp of node.imports) { imp.importedBy.delete(node); } } else { node.isSynced = false; } } private getNode(uri: vscode.Uri | undefined): FileNode | undefined { const rel = this.uriToImportPath(uri); return rel ? this.graph.get(rel) : undefined; } /** Discover all nodes that import the file */ private async discoverOutwards(uri: vscode.Uri | undefined, seen: Set, maxDistance: number, token: vscode.CancellationToken): Promise { const rel = this.uriToImportPath(uri); if (!rel) { return undefined; } let node = this.graph.get(rel); if (!node) { node = new FileNode(uri!, rel); this.graph.set(rel, node); } await this.discoverOutwardsInner(node, seen, maxDistance, token); return node; } private async discoverOutwardsInner(node: FileNode, seen: Set, maxDistance: number, token: vscode.CancellationToken) { if (seen.has(node.path) || maxDistance === 0) { return; } seen.add(node.path); if (node.isSynced === false) { await this.syncNode(node); } else if (node.isSynced instanceof Promise) { await node.isSynced; } if (token.isCancellationRequested) { return; } await Promise.all([...node.imports].map(i => this.discoverOutwardsInner(i, seen, maxDistance - 1, token))); } private async syncNode(node: FileNode) { node.isSynced = discoverLimiter.execute(async () => { const doc = vscode.workspace.textDocuments.find(d => d.uri.toString() === node.uri.toString()); let text: string; if (doc) { text = doc.getText(); } else { try { text = await fs.readFile(node.uri.fsPath, 'utf8'); } catch { text = ''; } } for (const imp of node.imports) { imp.importedBy.delete(node); } node.imports.clear(); for (const [, importPath] of text.matchAll(IMPORT_RE)) { let imp = this.graph.get(importPath); if (!imp) { imp = new FileNode(this.importPathToUri(importPath), importPath); this.graph.set(importPath, imp); } imp.importedBy.add(node); node.imports.add(imp); } node.isSynced = true; }); await node.isSynced; } private uriToImportPath(uri: vscode.Uri | undefined) { if (!uri) { return undefined; } const relativePath = vscode.workspace.asRelativePath(uri).replaceAll('\\', '/'); if (!relativePath.startsWith('src/vs/') || !relativePath.endsWith('.ts')) { return undefined; } return relativePath.slice('src/'.length, -'.ts'.length); } private importPathToUri(importPath: string) { return vscode.Uri.file(join(this.root.fsPath, 'src', `${importPath}.ts`)); } } const IMPORT_RE = /import .*? from ["'](vs\/[^"']+)/g; class FileNode { public imports = new Set(); public importedBy = new Set(); public isSynced: boolean | Promise = false; // Path is the *import path* starting with `vs/` constructor( public readonly uri: vscode.Uri, public readonly path: string, ) { } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/memoize.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export const memoizeLast = (fn: (args: A) => T): ((args: A) => T) => { let last: { arg: A; result: T } | undefined; return arg => { if (last && last.arg === arg) { return last.result; } const result = fn(arg); last = { arg, result }; return result; }; }; ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/metadata.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TestMessage } from 'vscode'; export interface TestMessageMetadata { expectedValue: unknown; actualValue: unknown; } const cache = new Array<{ id: string; metadata: TestMessageMetadata }>(); let id = 0; function getId(): string { return `msg:${id++}:`; } const regexp = /msg:\d+:/; export function attachTestMessageMetadata( message: TestMessage, metadata: TestMessageMetadata ): void { const existingMetadata = getTestMessageMetadata(message); if (existingMetadata) { Object.assign(existingMetadata, metadata); return; } const id = getId(); if (typeof message.message === 'string') { message.message = `${message.message}\n${id}`; } else { message.message.appendText(`\n${id}`); } cache.push({ id, metadata }); while (cache.length > 100) { cache.shift(); } } export function getTestMessageMetadata(message: TestMessage): TestMessageMetadata | undefined { let value: string; if (typeof message.message === 'string') { value = message.message; } else { value = message.message.value; } const result = regexp.exec(value); if (!result) { return undefined; } const id = result[0]; return cache.find(c => c.id === id)?.metadata; } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/snapshot.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { promises as fs } from 'fs'; import * as vscode from 'vscode'; export const snapshotComment = '\n\n// Snapshot file: '; export const registerSnapshotUpdate = (ctrl: vscode.TestController) => vscode.commands.registerCommand('selfhost-test-provider.updateSnapshot', async args => { const message: vscode.TestMessage = args.message; const index = message.expectedOutput?.indexOf(snapshotComment); if (!message.expectedOutput || !message.actualOutput || !index || index === -1) { vscode.window.showErrorMessage('Could not find snapshot comment in message'); return; } const file = message.expectedOutput.slice(index + snapshotComment.length); await fs.writeFile(file, message.actualOutput); ctrl.invalidateTestResults(args.test); }); ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/sourceUtils.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as ts from 'typescript'; import * as vscode from 'vscode'; import { TestCase, TestConstruct, TestSuite, VSCodeTest } from './testTree'; const suiteNames = new Set(['suite', 'flakySuite']); const testNames = new Set(['test']); export const enum Action { Skip, Recurse, } export const extractTestFromNode = (src: ts.SourceFile, node: ts.Node, parent: VSCodeTest) => { if (!ts.isCallExpression(node)) { return Action.Recurse; } const asSuite = identifyCall(node.expression, suiteNames); const asTest = identifyCall(node.expression, testNames); const either = asSuite || asTest; if (either === IdentifiedCall.Skipped) { return Action.Skip; } if (either === IdentifiedCall.Nothing) { return Action.Recurse; } const name = node.arguments[0]; const func = node.arguments[1]; if (!name || !ts.isStringLiteralLike(name) || !func) { return Action.Recurse; } const start = src.getLineAndCharacterOfPosition(name.pos); const end = src.getLineAndCharacterOfPosition(func.end); const range = new vscode.Range( new vscode.Position(start.line, start.character), new vscode.Position(end.line, end.character) ); const cparent = parent instanceof TestConstruct ? parent : undefined; // we know this is either a suite or a test because we checked for skipped/nothing above if (asTest) { return new TestCase(name.text, range, cparent); } if (asSuite) { return new TestSuite(name.text, range, cparent); } throw new Error('unreachable'); }; const enum IdentifiedCall { Nothing, Skipped, IsThing, } const identifyCall = (lhs: ts.Node, needles: ReadonlySet): IdentifiedCall => { if (ts.isIdentifier(lhs)) { return needles.has(lhs.escapedText || lhs.text) ? IdentifiedCall.IsThing : IdentifiedCall.Nothing; } if (isPropertyCall(lhs) && lhs.name.text === 'skip') { return needles.has(lhs.expression.text) ? IdentifiedCall.Skipped : IdentifiedCall.Nothing; } if (ts.isParenthesizedExpression(lhs) && ts.isConditionalExpression(lhs.expression)) { return Math.max(identifyCall(lhs.expression.whenTrue, needles), identifyCall(lhs.expression.whenFalse, needles)); } return IdentifiedCall.Nothing; }; const isPropertyCall = ( lhs: ts.Node ): lhs is ts.PropertyAccessExpression & { expression: ts.Identifier; name: ts.Identifier } => ts.isPropertyAccessExpression(lhs) && ts.isIdentifier(lhs.expression) && ts.isIdentifier(lhs.name); ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/stackTraceParser.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Copied from https://github.com/microsoft/vscode-js-debug/blob/1d104b5184736677ab5cc280c70bbd227403850c/src/common/stackTraceParser.ts#L18 // Either match lines like // " at fulfilled (/Users/roblou/code/testapp-node2/out/app.js:5:58)" // or // " at /Users/roblou/code/testapp-node2/out/app.js:60:23" // and replace the path in them const re1 = /^(\W*at .*\()(.*):(\d+):(\d+)(\))$/; const re2 = /^(\W*at )(.*):(\d+):(\d+)$/; const getLabelRe = /^\W*at (.*) \($/; /** * Parses a textual stack trace. */ export class StackTraceParser { /** Gets whether the stacktrace has any locations in it. */ public static isStackLike(str: string) { return re1.test(str) || re2.test(str); } constructor(private readonly stack: string) { } /** Iterates over segments of text and locations in the stack. */ *[Symbol.iterator]() { for (const line of this.stack.split('\n')) { const match = re1.exec(line) || re2.exec(line); if (!match) { yield line + '\n'; continue; } const [, prefix, url, lineNo, columnNo, suffix] = match; if (prefix) { yield prefix; } yield new StackTraceLocation(getLabelRe.exec(prefix)?.[1], url, Number(lineNo), Number(columnNo)); if (suffix) { yield suffix; } yield '\n'; } } } export class StackTraceLocation { constructor( public readonly label: string | undefined, public readonly path: string, public readonly lineBase1: number, public readonly columnBase1: number, ) { } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/streamSplitter.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // DO NOT EDIT DIRECTLY: copied from src/vs/base/node/nodeStreams.ts import { Transform } from 'stream'; /** * A Transform stream that splits the input on the "splitter" substring. * The resulting chunks will contain (and trail with) the splitter match. * The last chunk when the stream ends will be emitted even if a splitter * is not encountered. */ export class StreamSplitter extends Transform { private buffer: Buffer | undefined; private readonly splitter: number; private readonly spitterLen: number; constructor(splitter: string | number | Buffer) { super(); if (typeof splitter === 'number') { this.splitter = splitter; this.spitterLen = 1; } else { throw new Error('not implemented here'); } } override _transform( chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: any) => void ): void { if (!this.buffer) { this.buffer = chunk; } else { this.buffer = Buffer.concat([this.buffer, chunk]); } let offset = 0; while (offset < this.buffer.length) { const index = this.buffer.indexOf(this.splitter, offset); if (index === -1) { break; } this.push(this.buffer.slice(offset, index + this.spitterLen)); offset = index + this.spitterLen; } this.buffer = offset === this.buffer.length ? undefined : this.buffer.slice(offset); callback(); } override _flush(callback: (error?: Error | null, data?: any) => void): void { if (this.buffer) { this.push(this.buffer); } callback(); } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/testOutputScanner.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { decodedMappings, GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND, originalPositionFor, TraceMap, } from '@jridgewell/trace-mapping'; import * as styles from 'ansi-styles'; import { ChildProcessWithoutNullStreams } from 'child_process'; import * as vscode from 'vscode'; import { istanbulCoverageContext, PerTestCoverageTracker } from './coverageProvider'; import { attachTestMessageMetadata } from './metadata'; import { snapshotComment } from './snapshot'; import { StackTraceLocation, StackTraceParser } from './stackTraceParser'; import { StreamSplitter } from './streamSplitter'; import { getContentFromFilesystem } from './testTree'; import { IScriptCoverage } from './v8CoverageWrangling'; export const enum MochaEvent { Start = 'start', TestStart = 'testStart', Pass = 'pass', Fail = 'fail', End = 'end', // custom events: CoverageInit = 'coverageInit', CoverageIncrement = 'coverageIncrement', } export interface IStartEvent { total: number; } export interface ITestStartEvent { title: string; fullTitle: string; file: string; currentRetry: number; speed: string; } export interface IPassEvent extends ITestStartEvent { duration: number; } export interface IFailEvent extends IPassEvent { err: string; stack: string | null; expected?: string; actual?: string; expectedJSON?: unknown; actualJSON?: unknown; snapshotPath?: string; } export interface IEndEvent { suites: number; tests: number; passes: number; pending: number; failures: number; start: string /* ISO date */; end: string /* ISO date */; } export interface ITestCoverageCoverage { file: string; fullTitle: string; coverage: { result: IScriptCoverage[] }; } export type MochaEventTuple = | [MochaEvent.Start, IStartEvent] | [MochaEvent.TestStart, ITestStartEvent] | [MochaEvent.Pass, IPassEvent] | [MochaEvent.Fail, IFailEvent] | [MochaEvent.End, IEndEvent] | [MochaEvent.CoverageInit, { result: IScriptCoverage[] }] | [MochaEvent.CoverageIncrement, ITestCoverageCoverage]; const LF = '\n'.charCodeAt(0); export class TestOutputScanner implements vscode.Disposable { protected mochaEventEmitter = new vscode.EventEmitter(); protected outputEventEmitter = new vscode.EventEmitter(); protected onExitEmitter = new vscode.EventEmitter(); /** * Fired when a mocha event comes in. */ public readonly onMochaEvent = this.mochaEventEmitter.event; /** * Fired when other output from the process comes in. */ public readonly onOtherOutput = this.outputEventEmitter.event; /** * Fired when the process encounters an error, or exits. */ public readonly onRunnerExit = this.onExitEmitter.event; constructor(private readonly process: ChildProcessWithoutNullStreams, private args?: string[]) { process.stdout.pipe(new StreamSplitter(LF)).on('data', this.processData); process.stderr.pipe(new StreamSplitter(LF)).on('data', this.processData); process.on('error', e => this.onExitEmitter.fire(e.message)); process.on('exit', code => this.onExitEmitter.fire(code ? `Test process exited with code ${code}` : undefined) ); } /** * @override */ public dispose() { try { this.process.kill(); } catch { // ignored } } protected readonly processData = (data: string | Buffer) => { if (this.args) { this.outputEventEmitter.fire(`./scripts/test ${this.args.join(' ')}`); this.args = undefined; } data = data.toString(); try { const parsed = JSON.parse(data.trim()) as unknown; if (parsed instanceof Array && parsed.length === 2 && typeof parsed[0] === 'string') { this.mochaEventEmitter.fire(parsed as MochaEventTuple); } else { this.outputEventEmitter.fire(data); } } catch { this.outputEventEmitter.fire(data); } }; } type QueuedOutput = string | [string, vscode.Location | undefined, vscode.TestItem | undefined]; export async function scanTestOutput( tests: Map, task: vscode.TestRun, scanner: TestOutputScanner, coverageDir: string | undefined, cancellation: vscode.CancellationToken ): Promise { const exitBlockers: Set> = new Set(); const skippedTests = new Set(tests.values()); const store = new SourceMapStore(); let outputQueue = Promise.resolve(); const enqueueOutput = (fn: QueuedOutput | (() => Promise)) => { exitBlockers.delete(outputQueue); outputQueue = outputQueue.finally(async () => { const r = typeof fn === 'function' ? await fn() : fn; typeof r === 'string' ? task.appendOutput(r) : task.appendOutput(...r); }); exitBlockers.add(outputQueue); return outputQueue; }; const enqueueExitBlocker = (prom: Promise): Promise => { exitBlockers.add(prom); prom.finally(() => exitBlockers.delete(prom)); return prom; }; let perTestCoverage: PerTestCoverageTracker | undefined; let lastTest: vscode.TestItem | undefined; let ranAnyTest = false; try { if (cancellation.isCancellationRequested) { return; } await new Promise(resolve => { cancellation.onCancellationRequested(() => { resolve(); }); let currentTest: vscode.TestItem | undefined; scanner.onRunnerExit(err => { if (err) { enqueueOutput(err + crlf); } resolve(); }); scanner.onOtherOutput(str => { const match = spdlogRe.exec(str); if (!match) { enqueueOutput(str + crlf); return; } const logLocation = store.getSourceLocation(match[2], Number(match[3]) - 1); const logContents = replaceAllLocations(store, match[1]); const test = currentTest; enqueueOutput(() => Promise.all([logLocation, logContents]).then(([location, contents]) => [ contents + crlf, location, test, ]) ); }); scanner.onMochaEvent(evt => { switch (evt[0]) { case MochaEvent.Start: break; // no-op case MochaEvent.TestStart: currentTest = tests.get(evt[1].fullTitle); if (!currentTest) { console.warn(`Could not find test ${evt[1].fullTitle}`); return; } skippedTests.delete(currentTest); task.started(currentTest); ranAnyTest = true; break; case MochaEvent.Pass: { const title = evt[1].fullTitle; const tcase = tests.get(title); enqueueOutput(` ${styles.green.open}√${styles.green.close} ${title}\r\n`); if (tcase) { lastTest = tcase; task.passed(tcase, evt[1].duration); } } break; case MochaEvent.Fail: { const { err, stack, duration, expected, expectedJSON, actual, actualJSON, snapshotPath, fullTitle: id, } = evt[1]; let tcase = tests.get(id); // report failures on hook to the last-seen test, or first test if none run yet if (!tcase && (id.includes('hook for') || id.includes('hook in'))) { tcase = lastTest ?? tests.values().next().value; } enqueueOutput(`${styles.red.open} x ${id}${styles.red.close}\r\n`); const rawErr = stack || err; const locationsReplaced = replaceAllLocations(store, forceCRLF(rawErr)); if (rawErr) { enqueueOutput(async () => [await locationsReplaced, undefined, tcase]); } if (!tcase) { return; } const hasDiff = actual !== undefined && expected !== undefined && (expected !== '[undefined]' || actual !== '[undefined]'); const testFirstLine = tcase.range && new vscode.Location( tcase.uri!, new vscode.Range( tcase.range.start, new vscode.Position(tcase.range.start.line, 100) ) ); enqueueExitBlocker( (async () => { const stackInfo = await deriveStackLocations(store, rawErr, tcase!); let message: vscode.TestMessage; if (hasDiff) { message = new vscode.TestMessage(tryMakeMarkdown(err)); message.actualOutput = outputToString(actual); message.expectedOutput = outputToString(expected); if (snapshotPath) { message.contextValue = 'isSelfhostSnapshotMessage'; message.expectedOutput += snapshotComment + snapshotPath; } attachTestMessageMetadata(message, { expectedValue: expectedJSON, actualValue: actualJSON, }); } else { message = new vscode.TestMessage( stack ? await sourcemapStack(store, stack) : await locationsReplaced ); } message.location = stackInfo.primary ?? testFirstLine; message.stackTrace = stackInfo.stack; task.failed(tcase!, message, duration); })() ); } break; case MochaEvent.End: // no-op, we wait until the process exits to ensure coverage is written out break; case MochaEvent.CoverageInit: perTestCoverage ??= new PerTestCoverageTracker(store); for (const result of evt[1].result) { perTestCoverage.add(result); } break; case MochaEvent.CoverageIncrement: { const { fullTitle, coverage } = evt[1]; const tcase = tests.get(fullTitle); if (tcase) { perTestCoverage ??= new PerTestCoverageTracker(store); for (const result of coverage.result) { perTestCoverage.add(result, tcase); } } break; } } }); }); if (perTestCoverage) { enqueueExitBlocker(perTestCoverage.report(task)); } await Promise.all([...exitBlockers]); if (coverageDir) { try { await istanbulCoverageContext.apply(task, coverageDir, { mapFileUri: uri => store.getSourceFile(uri.toString()), mapLocation: (uri, position) => store.getSourceLocation(uri.toString(), position.line, position.character), }); } catch (e) { const msg = `Error loading coverage:\n\n${e}\n`; task.appendOutput(msg.replace(/\n/g, crlf)); } } // no tests? Possible crash, show output: if (!ranAnyTest) { await vscode.commands.executeCommand('testing.showMostRecentOutput'); } } catch (e) { task.appendOutput((e as Error).stack || (e as Error).message); } finally { scanner.dispose(); for (const test of skippedTests) { task.skipped(test); } task.end(); } } const spdlogRe = /"(.+)", source: (file:\/\/\/.*?)+ \(([0-9]+)\)/; const crlf = '\r\n'; const forceCRLF = (str: string) => str.replace(/(? { locationRe.lastIndex = 0; const replacements = await Promise.all( [...str.matchAll(locationRe)].map(async match => { const location = await deriveSourceLocation(store, match); if (!location) { return; } return { from: match[0], to: location?.uri.with({ fragment: `L${location.range.start.line + 1}:${location.range.start.character + 1}`, }), }; }) ); for (const replacement of replacements) { if (replacement) { str = str.replace(replacement.from, replacement.to.toString(true)); } } return str; }; const outputToString = (output: unknown) => typeof output === 'object' ? JSON.stringify(output, null, 2) : String(output); const tryMakeMarkdown = (message: string) => { const lines = message.split('\n'); const start = lines.findIndex(l => l.includes('+ actual')); if (start === -1) { return message; } lines.splice(start, 1, '```diff'); lines.push('```'); return new vscode.MarkdownString(lines.join('\n')); }; const inlineSourcemapRe = /^\/\/# sourceMappingURL=data:application\/json;base64,(.+)/m; const sourceMapBiases = [GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND] as const; export const enum SearchStrategy { FirstBefore = -1, FirstAfter = 1, } export type SourceLocationMapper = (line: number, col: number, strategy: SearchStrategy) => vscode.Location | undefined; export class SourceMapStore { private readonly cache = new Map>(); async getSourceLocationMapper(fileUri: string): Promise { const sourceMap = await this.loadSourceMap(fileUri); return (line, col, strategy) => { if (!sourceMap) { return undefined; } // 1. Look for the ideal position on this line if it exists const idealPosition = originalPositionFor(sourceMap, { column: col, line: line + 1, bias: SearchStrategy.FirstAfter ? GREATEST_LOWER_BOUND : LEAST_UPPER_BOUND }); if (idealPosition.line !== null && idealPosition.column !== null && idealPosition.source !== null) { return new vscode.Location( this.completeSourceMapUrl(sourceMap, idealPosition.source), new vscode.Position(idealPosition.line - 1, idealPosition.column) ); } // Otherwise get the first/last valid mapping on another line. const decoded = decodedMappings(sourceMap); const enum MapField { COLUMN = 0, SOURCES_INDEX = 1, SOURCE_LINE = 2, SOURCE_COLUMN = 3, } do { line += strategy; const segments = decoded[line]; if (!segments?.length) { continue; } const index = strategy === SearchStrategy.FirstBefore ? findLastIndex(segments, s => s.length !== 1) : segments.findIndex(s => s.length !== 1); const segment = segments[index]; if (!segment || segment.length === 1) { continue; } return new vscode.Location( this.completeSourceMapUrl(sourceMap, sourceMap.sources[segment[MapField.SOURCES_INDEX]]!), new vscode.Position(segment[MapField.SOURCE_LINE] - 1, segment[MapField.SOURCE_COLUMN]) ); } while (strategy === SearchStrategy.FirstBefore ? line > 0 : line < decoded.length); return undefined; }; } /** Gets an original location from a base 0 line and column */ async getSourceLocation(fileUri: string, line: number, col = 0) { const sourceMap = await this.loadSourceMap(fileUri); if (!sourceMap) { return undefined; } let smLine = line + 1; // if the range is after the end of mappings, adjust it to the last mapped line const decoded = decodedMappings(sourceMap); if (decoded.length <= line) { smLine = decoded.length; // base 1, no -1 needed col = Number.MAX_SAFE_INTEGER; } for (const bias of sourceMapBiases) { const position = originalPositionFor(sourceMap, { column: col, line: smLine, bias }); if (position.line !== null && position.column !== null && position.source !== null) { return new vscode.Location( this.completeSourceMapUrl(sourceMap, position.source), new vscode.Position(position.line - 1, position.column) ); } } return undefined; } async getSourceFile(compiledUri: string) { const sourceMap = await this.loadSourceMap(compiledUri); if (!sourceMap) { return undefined; } if (sourceMap.sources[0]) { return this.completeSourceMapUrl(sourceMap, sourceMap.sources[0]); } for (const bias of sourceMapBiases) { const position = originalPositionFor(sourceMap, { column: 0, line: 1, bias }); if (position.source !== null) { return this.completeSourceMapUrl(sourceMap, position.source); } } return undefined; } private completeSourceMapUrl(sm: TraceMap, source: string) { if (sm.sourceRoot) { try { return vscode.Uri.parse(new URL(source, sm.sourceRoot).toString()); } catch { // ignored } } return vscode.Uri.parse(source); } private loadSourceMap(fileUri: string) { const existing = this.cache.get(fileUri); if (existing) { return existing; } const promise = (async () => { try { const contents = await getContentFromFilesystem(vscode.Uri.parse(fileUri)); const sourcemapMatch = inlineSourcemapRe.exec(contents); if (!sourcemapMatch) { return; } const decoded = Buffer.from(sourcemapMatch[1], 'base64').toString(); return new TraceMap(decoded, fileUri); } catch (e) { console.warn(`Error parsing sourcemap for ${fileUri}: ${(e as Error).stack}`); return; } })(); this.cache.set(fileUri, promise); return promise; } } const locationRe = /(file:\/{3}.+):([0-9]+):([0-9]+)/g; async function replaceAllLocations(store: SourceMapStore, str: string) { const output: (string | Promise)[] = []; let lastIndex = 0; for (const match of str.matchAll(locationRe)) { const locationPromise = deriveSourceLocation(store, match); const startIndex = match.index || 0; const endIndex = startIndex + match[0].length; if (startIndex > lastIndex) { output.push(str.substring(lastIndex, startIndex)); } output.push( locationPromise.then(location => location ? `${location.uri}:${location.range.start.line + 1}:${location.range.start.character + 1}` : match[0] ) ); lastIndex = endIndex; } // Preserve the remaining string after the last match if (lastIndex < str.length) { output.push(str.substring(lastIndex)); } const values = await Promise.all(output); return values.join(''); } async function deriveStackLocations( store: SourceMapStore, stack: string, tcase: vscode.TestItem ) { locationRe.lastIndex = 0; const locationsRaw = [...new StackTraceParser(stack)].filter(t => t instanceof StackTraceLocation); const locationsMapped = await Promise.all(locationsRaw.map(async location => { const mapped = location.path.startsWith('file:') ? await store.getSourceLocation(location.path, location.lineBase1 - 1, location.columnBase1 - 1) : undefined; const stack = new vscode.TestMessageStackFrame(location.label || '', mapped?.uri, mapped?.range.start || new vscode.Position(location.lineBase1 - 1, location.columnBase1 - 1)); return { location: mapped, stack }; })); let best: undefined | { location: vscode.Location; score: number }; for (const { location } of locationsMapped) { if (!location) { continue; } let score = 0; if (tcase.uri && tcase.uri.toString() === location.uri.toString()) { score = 1; if (tcase.range && tcase.range.contains(location?.range)) { score = 2; } } if (!best || score > best.score) { best = { location, score }; } } return { stack: locationsMapped.map(s => s.stack), primary: best?.location }; } async function deriveSourceLocation(store: SourceMapStore, parts: RegExpMatchArray) { const [, fileUri, line, col] = parts; return store.getSourceLocation(fileUri, Number(line) - 1, Number(col)); } function findLastIndex(arr: T[], predicate: (value: T) => boolean) { for (let i = arr.length - 1; i >= 0; i--) { if (predicate(arr[i])) { return i; } } return -1; } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/testTree.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { join, relative } from 'path'; import * as ts from 'typescript'; import { TextDecoder } from 'util'; import * as vscode from 'vscode'; import { Action, extractTestFromNode } from './sourceUtils'; const textDecoder = new TextDecoder('utf-8'); const diagnosticCollection = vscode.languages.createDiagnosticCollection('selfhostTestProvider'); type ContentGetter = (uri: vscode.Uri) => Promise; export const itemData = new WeakMap(); export const clearFileDiagnostics = (uri: vscode.Uri) => diagnosticCollection.delete(uri); /** * Tries to guess which workspace folder VS Code is in. */ export const guessWorkspaceFolder = async () => { if (!vscode.workspace.workspaceFolders) { return undefined; } if (vscode.workspace.workspaceFolders.length < 2) { return vscode.workspace.workspaceFolders[0]; } for (const folder of vscode.workspace.workspaceFolders) { try { await vscode.workspace.fs.stat(vscode.Uri.joinPath(folder.uri, 'src/vs/loader.js')); return folder; } catch { // ignored } } return undefined; }; export const getContentFromFilesystem: ContentGetter = async uri => { try { const rawContent = await vscode.workspace.fs.readFile(uri); return textDecoder.decode(rawContent); } catch (e) { console.warn(`Error providing tests for ${uri.fsPath}`, e); return ''; } }; export class TestFile { public hasBeenRead = false; constructor( public readonly uri: vscode.Uri, public readonly workspaceFolder: vscode.WorkspaceFolder ) {} public getId() { return this.uri.toString().toLowerCase(); } public getLabel() { return relative(join(this.workspaceFolder.uri.fsPath, 'src'), this.uri.fsPath); } public async updateFromDisk(controller: vscode.TestController, item: vscode.TestItem) { try { const content = await getContentFromFilesystem(item.uri!); item.error = undefined; this.updateFromContents(controller, content, item); } catch (e) { item.error = (e as Error).stack; } } /** * Refreshes all tests in this file, `sourceReader` provided by the root. */ public updateFromContents( controller: vscode.TestController, content: string, file: vscode.TestItem ) { try { const diagnostics: vscode.Diagnostic[] = []; const ast = ts.createSourceFile( this.uri.path.split('/').pop()!, content, ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS ); const parents: { item: vscode.TestItem; children: vscode.TestItem[] }[] = [ { item: file, children: [] }, ]; const traverse = (node: ts.Node) => { const parent = parents[parents.length - 1]; const childData = extractTestFromNode(ast, node, itemData.get(parent.item)!); if (childData === Action.Skip) { return; } if (childData === Action.Recurse) { ts.forEachChild(node, traverse); return; } const id = `${file.uri}/${childData.fullName}`.toLowerCase(); // Skip duplicated tests. They won't run correctly with the way // mocha reports them, and will error if we try to insert them. const existing = parent.children.find(c => c.id === id); if (existing) { const diagnostic = new vscode.Diagnostic( childData.range, 'Duplicate tests cannot be run individually and will not be reported correctly by the test framework. Please rename them.', vscode.DiagnosticSeverity.Warning ); diagnostic.relatedInformation = [ new vscode.DiagnosticRelatedInformation( new vscode.Location(existing.uri!, existing.range!), 'First declared here' ), ]; diagnostics.push(diagnostic); return; } const item = controller.createTestItem(id, childData.name, file.uri); itemData.set(item, childData); item.range = childData.range; parent.children.push(item); if (childData instanceof TestSuite) { parents.push({ item: item, children: [] }); ts.forEachChild(node, traverse); item.children.replace(parents.pop()!.children); } }; ts.forEachChild(ast, traverse); file.error = undefined; file.children.replace(parents[0].children); diagnosticCollection.set(this.uri, diagnostics.length ? diagnostics : undefined); this.hasBeenRead = true; } catch (e) { file.error = String((e as Error).stack || (e as Error).message); } } } export abstract class TestConstruct { public fullName: string; constructor( public readonly name: string, public readonly range: vscode.Range, parent?: TestConstruct ) { this.fullName = parent ? `${parent.fullName} ${name}` : name; } } export class TestSuite extends TestConstruct {} export class TestCase extends TestConstruct {} export type VSCodeTest = TestFile | TestSuite | TestCase; ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/v8CoverageWrangling.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { RangeCoverageTracker } from './v8CoverageWrangling'; suite('v8CoverageWrangling', () => { suite('RangeCoverageTracker', () => { test('covers new range', () => { const rt = new RangeCoverageTracker(); rt.cover(5, 10); assert.deepStrictEqual([...rt], [{ start: 5, end: 10, covered: true }]); }); test('non overlapping ranges', () => { const rt = new RangeCoverageTracker(); rt.cover(5, 10); rt.cover(15, 20); rt.cover(12, 13); assert.deepStrictEqual( [...rt], [ { start: 5, end: 10, covered: true }, { start: 12, end: 13, covered: true }, { start: 15, end: 20, covered: true }, ] ); }); test('covers exact', () => { const rt = new RangeCoverageTracker(); rt.uncovered(5, 10); rt.cover(5, 10); assert.deepStrictEqual([...rt], [{ start: 5, end: 10, covered: true }]); }); test('overlap at start', () => { const rt = new RangeCoverageTracker(); rt.uncovered(5, 10); rt.cover(2, 7); assert.deepStrictEqual( [...rt], [ { start: 2, end: 7, covered: true }, { start: 7, end: 10, covered: false }, ] ); }); test('overlap at end', () => { const rt = new RangeCoverageTracker(); rt.cover(5, 10); rt.uncovered(2, 7); assert.deepStrictEqual( [...rt], [ { start: 2, end: 5, covered: false }, { start: 5, end: 10, covered: true }, ] ); }); test('inner contained', () => { const rt = new RangeCoverageTracker(); rt.cover(5, 10); rt.uncovered(2, 12); assert.deepStrictEqual( [...rt], [ { start: 2, end: 5, covered: false }, { start: 5, end: 10, covered: true }, { start: 10, end: 12, covered: false }, ] ); }); test('outer contained', () => { const rt = new RangeCoverageTracker(); rt.uncovered(5, 10); rt.cover(7, 9); assert.deepStrictEqual( [...rt], [ { start: 5, end: 7, covered: false }, { start: 7, end: 9, covered: true }, { start: 9, end: 10, covered: false }, ] ); }); test('boundary touching', () => { const rt = new RangeCoverageTracker(); rt.uncovered(5, 10); rt.cover(10, 15); rt.uncovered(15, 20); assert.deepStrictEqual( [...rt], [ { start: 5, end: 10, covered: false }, { start: 10, end: 15, covered: true }, { start: 15, end: 20, covered: false }, ] ); }); suite('initializeBlock', () => { test('simple tree', () => { const rt = RangeCoverageTracker.initializeBlocks([ { functionName: 'outer', isBlockCoverage: true, ranges: [ { count: 1, startOffset: 5, endOffset: 30 }, { count: 1, startOffset: 8, endOffset: 10 }, { count: 0, startOffset: 15, endOffset: 20 }, ], }, ]); assert.deepStrictEqual( [...rt], [ { start: 5, end: 15, covered: true }, { start: 15, end: 20, covered: false }, { start: 20, end: 30, covered: true }, ] ); }); test('separate branches', () => { const rt = RangeCoverageTracker.initializeBlocks([ { functionName: 'outer', isBlockCoverage: true, ranges: [ { count: 1, startOffset: 5, endOffset: 8 }, { count: 1, startOffset: 10, endOffset: 12 }, { count: 0, startOffset: 15, endOffset: 20 }, ], }, ]); assert.deepStrictEqual( [...rt], [ { start: 5, end: 8, covered: true }, { start: 10, end: 12, covered: true }, { start: 15, end: 20, covered: false }, ] ); }); }); }); }); ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/v8CoverageWrangling.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export interface ICoverageRange { start: number; end: number; covered: boolean; } export interface IV8FunctionCoverage { functionName: string; isBlockCoverage: boolean; ranges: IV8CoverageRange[]; } export interface IV8CoverageRange { startOffset: number; endOffset: number; count: number; } /** V8 Script coverage data */ export interface IScriptCoverage { scriptId: string; url: string; // Script source added by the runner the first time the script is emitted. source?: string; functions: IV8FunctionCoverage[]; } export class RangeCoverageTracker implements Iterable { /** * A noncontiguous, non-overlapping, ordered set of ranges and whether * that range has been covered. */ private ranges: readonly ICoverageRange[] = []; /** * Adds a coverage tracker initialized for a function with {@link isBlockCoverage} set to true. */ public static initializeBlocks(fns: IV8FunctionCoverage[]) { const rt = new RangeCoverageTracker(); let start = 0; const stack: IV8CoverageRange[] = []; // note: comes pre-sorted from V8 for (const { ranges } of fns) { for (const range of ranges) { while (stack.length && stack[stack.length - 1].endOffset < range.startOffset) { const last = stack.pop()!; rt.setCovered(start, last.endOffset, last.count > 0); start = last.endOffset; } if (range.startOffset > start && stack.length) { rt.setCovered(start, range.startOffset, !!stack[stack.length - 1].count); } start = range.startOffset; stack.push(range); } } while (stack.length) { const last = stack.pop()!; rt.setCovered(start, last.endOffset, last.count > 0); start = last.endOffset; } return rt; } /** Makes a copy of the range tracker. */ public clone() { const rt = new RangeCoverageTracker(); rt.ranges = this.ranges.slice(); return rt; } /** Marks a range covered */ public cover(start: number, end: number) { this.setCovered(start, end, true); } /** Marks a range as uncovered */ public uncovered(start: number, end: number) { this.setCovered(start, end, false); } /** Iterates over coverage ranges */ [Symbol.iterator]() { return this.ranges[Symbol.iterator](); } /** * Marks the given character range as being covered or uncovered. * * todo@connor4312: this is a hot path is could probably be optimized to * avoid rebuilding the array. Maybe with a nice tree structure? */ public setCovered(start: number, end: number, covered: boolean) { const newRanges: ICoverageRange[] = []; let i = 0; for (; i < this.ranges.length && this.ranges[i].end <= start; i++) { newRanges.push(this.ranges[i]); } const push = (range: ICoverageRange) => { const last = newRanges.length && newRanges[newRanges.length - 1]; if (last && last.end === range.start && last.covered === range.covered) { last.end = range.end; } else { newRanges.push(range); } }; push({ start, end, covered }); for (; i < this.ranges.length; i++) { const range = this.ranges[i]; const last = newRanges[newRanges.length - 1]; if (range.start === last.start && range.end === last.end) { // ranges are equal: last.covered ||= range.covered; } else if (range.end < last.start || range.start > last.end) { // ranges don't overlap push(range); } else if (range.start < last.start && range.end > last.end) { // range contains last: newRanges.pop(); push({ start: range.start, end: last.start, covered: range.covered }); push({ start: last.start, end: last.end, covered: range.covered || last.covered }); push({ start: last.end, end: range.end, covered: range.covered }); } else if (range.start >= last.start && range.end <= last.end) { // last contains range: newRanges.pop(); push({ start: last.start, end: range.start, covered: last.covered }); push({ start: range.start, end: range.end, covered: range.covered || last.covered }); push({ start: range.end, end: last.end, covered: last.covered }); } else if (range.start < last.start && range.end <= last.end) { // range overlaps start of last: newRanges.pop(); push({ start: range.start, end: last.start, covered: range.covered }); push({ start: last.start, end: range.end, covered: range.covered || last.covered }); push({ start: range.end, end: last.end, covered: last.covered }); } else if (range.start >= last.start && range.end > last.end) { // range overlaps end of last: newRanges.pop(); push({ start: last.start, end: range.start, covered: last.covered }); push({ start: range.start, end: last.end, covered: range.covered || last.covered }); push({ start: last.end, end: range.end, covered: range.covered }); } else { throw new Error('unreachable'); } } this.ranges = newRanges; } } export class OffsetToPosition { /** Line numbers to byte offsets. */ public readonly lines: number[] = []; public readonly totalLength: number; constructor(source: string) { this.lines.push(0); for (let i = source.indexOf('\n'); i !== -1; i = source.indexOf('\n', i + 1)) { this.lines.push(i + 1); } this.totalLength = source.length; } public getLineLength(lineNumber: number): number { return ( (lineNumber < this.lines.length - 1 ? this.lines[lineNumber + 1] - 1 : this.totalLength) - this.lines[lineNumber] ); } /** * Gets the line the offset appears on. */ public getLineOfOffset(offset: number): number { let low = 0; let high = this.lines.length; while (low < high) { const mid = Math.floor((low + high) / 2); if (this.lines[mid] > offset) { high = mid; } else { low = mid + 1; } } return low - 1; } /** * Converts from a file offset to a base 0 line/column . */ public toLineColumn(offset: number): { line: number; column: number } { const line = this.getLineOfOffset(offset); return { line: line, column: offset - this.lines[line] }; } } ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/src/vscodeTestRunner.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawn } from 'child_process'; import { promises as fs } from 'fs'; import { AddressInfo, createServer } from 'net'; import * as path from 'path'; import * as vscode from 'vscode'; import { TestOutputScanner } from './testOutputScanner'; import { TestCase, TestFile, TestSuite, itemData } from './testTree'; /** * From MDN * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping */ const escapeRe = (s: string) => s.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); const TEST_ELECTRON_SCRIPT_PATH = 'test/unit/electron/index.js'; const TEST_BROWSER_SCRIPT_PATH = 'test/unit/browser/index.js'; const ATTACH_CONFIG_NAME = 'Attach to VS Code'; const DEBUG_TYPE = 'pwa-chrome'; export abstract class VSCodeTestRunner { constructor(protected readonly repoLocation: vscode.WorkspaceFolder) { } public async run(baseArgs: ReadonlyArray, filter?: ReadonlyArray) { const args = this.prepareArguments(baseArgs, filter); const cp = spawn(await this.binaryPath(), args, { cwd: this.repoLocation.uri.fsPath, stdio: 'pipe', env: this.getEnvironment(), }); return new TestOutputScanner(cp, args); } public async debug(testRun: vscode.TestRun, baseArgs: ReadonlyArray, filter?: ReadonlyArray) { const port = await this.findOpenPort(); const baseConfiguration = vscode.workspace .getConfiguration('launch', this.repoLocation) .get('configurations', []) .find(c => c.name === ATTACH_CONFIG_NAME); if (!baseConfiguration) { throw new Error(`Could not find launch configuration ${ATTACH_CONFIG_NAME}`); } const server = this.createWaitServer(); const args = [ ...this.prepareArguments(baseArgs, filter), `--remote-debugging-port=${port}`, // for breakpoint freeze: https://github.com/microsoft/vscode/issues/122225#issuecomment-885377304 '--js-flags="--regexp_interpret_all"', // for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910 '--disable-features=CalculateNativeWinOcclusion', '--timeout=0', `--waitServer=${server.port}`, ]; const cp = spawn(await this.binaryPath(), args, { cwd: this.repoLocation.uri.fsPath, stdio: 'pipe', env: this.getEnvironment(port), }); // Register a descriptor factory that signals the server when any // breakpoint set requests on the debugee have been completed. const factory = vscode.debug.registerDebugAdapterTrackerFactory(DEBUG_TYPE, { createDebugAdapterTracker(session) { if (!session.parentSession || session.parentSession !== rootSession) { return; } let initRequestId: number | undefined; return { onDidSendMessage(message) { if (message.type === 'response' && message.request_seq === initRequestId) { server.ready(); } }, onWillReceiveMessage(message) { if (initRequestId !== undefined) { return; } if (message.command === 'launch' || message.command === 'attach') { initRequestId = message.seq; } }, }; }, }); vscode.debug.startDebugging(this.repoLocation, { ...baseConfiguration, port }, { testRun }); let exited = false; let rootSession: vscode.DebugSession | undefined; cp.once('exit', () => { exited = true; server.dispose(); listener.dispose(); factory.dispose(); if (rootSession) { vscode.debug.stopDebugging(rootSession); } }); const listener = vscode.debug.onDidStartDebugSession(s => { if (s.name === ATTACH_CONFIG_NAME && !rootSession) { if (exited) { vscode.debug.stopDebugging(rootSession); } else { rootSession = s; } } }); return new TestOutputScanner(cp, args); } private findOpenPort(): Promise { return new Promise((resolve, reject) => { const server = createServer(); server.listen(0, () => { const address = server.address() as AddressInfo; const port = address.port; server.close(() => { resolve(port); }); }); server.on('error', (error: Error) => { reject(error); }); }); } protected getEnvironment(_remoteDebugPort?: number): NodeJS.ProcessEnv { return { ...process.env, ELECTRON_RUN_AS_NODE: undefined, ELECTRON_ENABLE_LOGGING: '1', }; } private prepareArguments( baseArgs: ReadonlyArray, filter?: ReadonlyArray ) { const args = [...this.getDefaultArgs(), ...baseArgs, '--reporter', 'full-json-stream']; if (!filter) { return args; } const grepRe: string[] = []; const runPaths = new Set(); const addTestFileRunPath = (data: TestFile) => runPaths.add( path.relative(data.workspaceFolder.uri.fsPath, data.uri.fsPath).replace(/\\/g, '/') ); const itemDatas = filter.map(f => itemData.get(f)); /** If true, we have to be careful with greps, as a grep for one test file affects the run of the other test file. */ const hasBothTestCaseOrTestSuiteAndTestFileFilters = itemDatas.some(d => (d instanceof TestCase) || (d instanceof TestSuite)) && itemDatas.some(d => d instanceof TestFile); function addTestCaseOrSuite(data: TestCase | TestSuite, test: vscode.TestItem): void { grepRe.push(escapeRe(data.fullName) + (data instanceof TestCase ? '$' : ' ')); for (let p = test.parent; p; p = p.parent) { const parentData = itemData.get(p); if (parentData instanceof TestFile) { addTestFileRunPath(parentData); } } } for (const test of filter) { const data = itemData.get(test); if (data instanceof TestCase || data instanceof TestSuite) { addTestCaseOrSuite(data, test); } else if (data instanceof TestFile) { if (!hasBothTestCaseOrTestSuiteAndTestFileFilters) { addTestFileRunPath(data); } else { // We add all the items individually so they get their own grep expressions. for (const [_id, nestedTest] of test.children) { const childData = itemData.get(nestedTest); if (childData instanceof TestCase || childData instanceof TestSuite) { addTestCaseOrSuite(childData, nestedTest); } else { console.error('Unexpected test item in test file', nestedTest.id, nestedTest.label); } } } } } if (grepRe.length) { args.push('--grep', `/^(${grepRe.join('|')})/`); } if (runPaths.size) { args.push(...[...runPaths].flatMap(p => ['--run', p])); } return args; } protected abstract getDefaultArgs(): string[]; protected abstract binaryPath(): Promise; protected async readProductJson() { const projectJson = await fs.readFile( path.join(this.repoLocation.uri.fsPath, 'product.json'), 'utf-8' ); try { return JSON.parse(projectJson); } catch (e) { throw new Error(`Error parsing product.json: ${(e as Error).message}`); } } private createWaitServer() { const onReady = new vscode.EventEmitter(); let ready = false; const server = createServer(socket => { if (ready) { socket.end(); } else { onReady.event(() => socket.end()); } }); server.listen(0); return { port: (server.address() as AddressInfo).port, ready: () => { ready = true; onReady.fire(); }, dispose: () => { server.close(); }, }; } } export class BrowserTestRunner extends VSCodeTestRunner { /** @override */ protected binaryPath(): Promise { return Promise.resolve(process.execPath); } /** @override */ protected override getEnvironment(remoteDebugPort?: number) { return { ...super.getEnvironment(remoteDebugPort), PLAYWRIGHT_CHROMIUM_DEBUG_PORT: remoteDebugPort ? String(remoteDebugPort) : undefined, ELECTRON_RUN_AS_NODE: '1', }; } /** @override */ protected getDefaultArgs() { return [TEST_BROWSER_SCRIPT_PATH]; } } export class WindowsTestRunner extends VSCodeTestRunner { /** @override */ protected async binaryPath() { const { nameShort } = await this.readProductJson(); return path.join(this.repoLocation.uri.fsPath, `.build/electron/${nameShort}.exe`); } /** @override */ protected getDefaultArgs() { return [TEST_ELECTRON_SCRIPT_PATH]; } } export class PosixTestRunner extends VSCodeTestRunner { /** @override */ protected async binaryPath() { const { applicationName } = await this.readProductJson(); return path.join(this.repoLocation.uri.fsPath, `.build/electron/${applicationName}`); } /** @override */ protected getDefaultArgs() { return [TEST_ELECTRON_SCRIPT_PATH]; } } export class DarwinTestRunner extends PosixTestRunner { /** @override */ protected override getDefaultArgs() { return [ TEST_ELECTRON_SCRIPT_PATH, '--no-sandbox', '--disable-dev-shm-usage', '--use-gl=swiftshader', ]; } /** @override */ protected override async binaryPath() { const { nameLong } = await this.readProductJson(); return path.join( this.repoLocation.uri.fsPath, `.build/electron/${nameLong}.app/Contents/MacOS/Electron` ); } } export const PlatformTestRunner = process.platform === 'win32' ? WindowsTestRunner : process.platform === 'darwin' ? DarwinTestRunner : PosixTestRunner; ================================================ FILE: .vscode/extensions/vscode-selfhost-test-provider/tsconfig.json ================================================ { "extends": "../../../extensions/tsconfig.base.json", "compilerOptions": { "outDir": "./out", "types": [ "node", "mocha", ] }, "include": [ "src/**/*", "../../../src/vscode-dts/vscode.d.ts", "../../../src/vscode-dts/vscode.proposed.testObserver.d.ts", "../../../src/vscode-dts/vscode.proposed.testRelatedCode.d.ts" ] } ================================================ FILE: .vscode/extensions.json ================================================ { // See https://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format "recommendations": [ "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "github.vscode-pull-request-github", "ms-vscode.vscode-github-issue-notebooks", "ms-vscode.extension-test-runner", "jrieken.vscode-pr-pinger" ] } ================================================ FILE: .vscode/launch.json ================================================ { "version": "0.1.0", "configurations": [ { "type": "node", "request": "launch", "name": "Gulp Build", "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", "stopOnEntry": true, "args": [ "hygiene" ] }, { "type": "node", "request": "attach", "restart": true, "name": "Attach to Extension Host", "timeout": 0, "port": 5870, "outFiles": [ "${workspaceFolder}/out/**/*.js", "${workspaceFolder}/extensions/*/out/**/*.js" ] }, { "type": "node", "request": "attach", "restart": true, "name": "Attach to Shared Process", "timeout": 0, "port": 5879, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] }, { "type": "node", "request": "attach", "name": "Attach to Search Process", "port": 5876, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] }, { "type": "node", "request": "attach", "name": "Attach to Pty Host Process", "port": 5877, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] }, { "type": "node", "request": "attach", "name": "Attach to CLI Process", "port": 5874, "outFiles": [ "${workspaceFolder}/out/**/*.js" ] }, { "type": "node", "request": "attach", "name": "Attach to Main Process", "timeout": 30000, "port": 5875, "continueOnAttach": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "hidden": true, } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Emmet Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/emmet/test-workspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/emmet", "--extensionTestsPath=${workspaceFolder}/extensions/emmet/out/test" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 6 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Configuration Editing Tests", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}/extensions/configuration-editing", "--extensionTestsPath=${workspaceFolder}/extensions/configuration-editing/out/test" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 6 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Git Tests", "runtimeExecutable": "${execPath}", "args": [ "/tmp/my4g9l", "--extensionDevelopmentPath=${workspaceFolder}/extensions/git", "--extensionTestsPath=${workspaceFolder}/extensions/git/out/test" ], "outFiles": [ "${workspaceFolder}/extensions/git/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 6 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Github Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/github/testWorkspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/github", "--extensionTestsPath=${workspaceFolder}/extensions/github/out/test" ], "outFiles": [ "${workspaceFolder}/extensions/github/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 6 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code API Tests (single folder)", "runtimeExecutable": "${execPath}", "args": [ // "${workspaceFolder}", // Uncomment for running out of sources. "${workspaceFolder}/extensions/vscode-api-tests/testWorkspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-api-tests", "--extensionTestsPath=${workspaceFolder}/extensions/vscode-api-tests/out/singlefolder-tests", "--disable-extensions" ], "outFiles": [ "${workspaceFolder}/extensions/vscode-api-tests/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 3 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code API Tests (workspace)", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/vscode-api-tests/testworkspace.code-workspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-api-tests", "--extensionTestsPath=${workspaceFolder}/extensions/vscode-api-tests/out/workspace-tests" ], "outFiles": [ "${workspaceFolder}/extensions/vscode-api-tests/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 4 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Tokenizer Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/vscode-colorize-tests/test", "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-colorize-tests", "--extensionTestsPath=${workspaceFolder}/extensions/vscode-colorize-tests/out" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 5 } }, { "type": "extensionHost", "request": "launch", "name": "VS Code Tokenizer Performance Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/vscode-colorize-perf-tests/test", "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-colorize-perf-tests", "--extensionTestsPath=${workspaceFolder}/extensions/vscode-colorize-perf-tests/out" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 6 } }, { "type": "chrome", "request": "attach", "name": "Attach to VS Code", "browserAttachLocation": "workspace", "port": 9222, "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "resolveSourceMapLocations": [ "${workspaceFolder}/out/**/*.js" ], "perScriptSourcemaps": "yes" }, { "type": "chrome", "request": "launch", "name": "Launch VS Code Internal", "windows": { "runtimeExecutable": "${workspaceFolder}/scripts/code.bat" }, "osx": { "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" }, "linux": { "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" }, "port": 9222, "timeout": 0, "env": { "VSCODE_EXTHOST_WILL_SEND_SOCKET": null, "VSCODE_SKIP_PRELAUNCH": "1", }, "cleanUp": "wholeBrowser", "runtimeArgs": [ "--inspect-brk=5875", "--no-cached-data", "--crash-reporter-directory=${workspaceFolder}/.profile-oss/crashes", // for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910 "--disable-features=CalculateNativeWinOcclusion", "--disable-extension=vscode.vscode-api-tests" ], "userDataDir": "${userHome}/.vscode-oss-dev", "webRoot": "${workspaceFolder}", "cascadeTerminateToConfigurations": [ "Attach to Extension Host" ], "pauseForSourceMap": false, "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "browserLaunchLocation": "workspace", "presentation": { "hidden": true, }, }, { // To debug observables you also need the extension "ms-vscode.debug-value-editor" "type": "chrome", "request": "launch", "name": "Launch VS Code Internal (Dev Debug)", "windows": { "runtimeExecutable": "${workspaceFolder}/scripts/code.bat" }, "osx": { "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" }, "linux": { "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" }, "port": 9222, "timeout": 0, "env": { "VSCODE_EXTHOST_WILL_SEND_SOCKET": null, "VSCODE_SKIP_PRELAUNCH": "1", "VSCODE_DEV_DEBUG": "1", }, "cleanUp": "wholeBrowser", "runtimeArgs": [ "--inspect-brk=5875", "--no-cached-data", "--crash-reporter-directory=${workspaceFolder}/.profile-oss/crashes", // for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910 "--disable-features=CalculateNativeWinOcclusion", "--disable-extension=vscode.vscode-api-tests" ], "userDataDir": "${userHome}/.vscode-oss-dev", "webRoot": "${workspaceFolder}", "cascadeTerminateToConfigurations": [ "Attach to Extension Host" ], "pauseForSourceMap": false, "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "browserLaunchLocation": "workspace", "presentation": { "hidden": true, }, }, { "type": "node", "request": "launch", "name": "VS Code Server (Web)", "runtimeExecutable": "${workspaceFolder}/scripts/code-server.sh", "windows": { "runtimeExecutable": "${workspaceFolder}/scripts/code-server.bat", }, "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "0_vscode", "order": 2 } }, { "type": "node", "request": "launch", "name": "Main Process", "attachSimplePort": 5875, "enableContentValidation": false, "runtimeExecutable": "${workspaceFolder}/scripts/code.sh", "windows": { "runtimeExecutable": "${workspaceFolder}/scripts/code.bat", }, "runtimeArgs": [ "--inspect-brk=5875", "--no-cached-data", ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "presentation": { "group": "1_vscode", "order": 1 } }, { "type": "chrome", "request": "launch", "outFiles": [], "perScriptSourcemaps": "yes", "name": "VS Code Server (Web, Chrome)", "url": "http://localhost:8080?tkn=dev-token", "preLaunchTask": "Run code server", "presentation": { "group": "0_vscode", "order": 3 } }, { "type": "msedge", "request": "launch", "outFiles": [], "perScriptSourcemaps": "yes", "name": "VS Code Server (Web, Edge)", "url": "http://localhost:8080?tkn=dev-token", "pauseForSourceMap": false, "preLaunchTask": "Run code server", "presentation": { "group": "0_vscode", "order": 3 } }, { "type": "chrome", "request": "launch", "outFiles": [], "perScriptSourcemaps": "yes", "name": "VS Code Web (Chrome)", "url": "http://localhost:8080", "preLaunchTask": "Run code web", "presentation": { "group": "0_vscode", "order": 3 } }, { "type": "msedge", "request": "launch", "outFiles": [], "perScriptSourcemaps": "yes", "name": "VS Code Web (Edge)", "url": "http://localhost:8080", "pauseForSourceMap": false, "preLaunchTask": "Run code web", "presentation": { "group": "0_vscode", "order": 3 } }, { "type": "node", "request": "launch", "name": "Git Unit Tests", "program": "${workspaceFolder}/extensions/git/node_modules/mocha/bin/_mocha", "stopOnEntry": false, "cwd": "${workspaceFolder}/extensions/git", "outFiles": [ "${workspaceFolder}/extensions/git/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 10 } }, { "type": "node", "request": "launch", "name": "HTML Server Unit Tests", "program": "${workspaceFolder}/extensions/html-language-features/server/test/index.js", "stopOnEntry": false, "cwd": "${workspaceFolder}/extensions/html-language-features/server", "outFiles": [ "${workspaceFolder}/extensions/html-language-features/server/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 10 } }, { "type": "node", "request": "launch", "name": "CSS Server Unit Tests", "program": "${workspaceFolder}/extensions/css-language-features/server/test/index.js", "stopOnEntry": false, "cwd": "${workspaceFolder}/extensions/css-language-features/server", "outFiles": [ "${workspaceFolder}/extensions/css-language-features/server/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 10 } }, { "type": "extensionHost", "request": "launch", "name": "Markdown Extension Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/markdown-language-features/test-workspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/markdown-language-features", "--extensionTestsPath=${workspaceFolder}/extensions/markdown-language-features/out/test" ], "outFiles": [ "${workspaceFolder}/extensions/markdown-language-features/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 7 } }, { "type": "extensionHost", "request": "launch", "name": "TypeScript Extension Tests", "runtimeExecutable": "${execPath}", "args": [ "${workspaceFolder}/extensions/typescript-language-features/test-workspace", "--extensionDevelopmentPath=${workspaceFolder}/extensions/typescript-language-features", "--extensionTestsPath=${workspaceFolder}/extensions/typescript-language-features/out/test" ], "outFiles": [ "${workspaceFolder}/extensions/typescript-language-features/out/**/*.js" ], "presentation": { "group": "5_tests", "order": 8 } }, { "type": "node", "request": "launch", "name": "Run Unit Tests", "program": "${workspaceFolder}/test/unit/electron/index.js", "runtimeExecutable": "${workspaceFolder}/.build/electron/Code - OSS.app/Contents/MacOS/Electron", "windows": { "runtimeExecutable": "${workspaceFolder}/.build/electron/Code - OSS.exe" }, "linux": { "runtimeExecutable": "${workspaceFolder}/.build/electron/code-oss" }, "outputCapture": "std", "args": [ "--remote-debugging-port=9222" ], "cwd": "${workspaceFolder}", "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "cascadeTerminateToConfigurations": [ "Attach to VS Code" ], "env": { "MOCHA_COLORS": "true" }, "presentation": { "hidden": true } }, { "type": "node", "request": "launch", "name": "Run Unit Tests For Current File", "program": "${workspaceFolder}/test/unit/electron/index.js", "runtimeExecutable": "${workspaceFolder}/.build/electron/Code - OSS.app/Contents/MacOS/Electron", "windows": { "runtimeExecutable": "${workspaceFolder}/.build/electron/Code - OSS.exe" }, "linux": { "runtimeExecutable": "${workspaceFolder}/.build/electron/code-oss" }, "cascadeTerminateToConfigurations": [ "Attach to VS Code" ], "outputCapture": "std", "args": [ "--remote-debugging-port=9222", "--run", "${relativeFile}" ], "cwd": "${workspaceFolder}", "outFiles": [ "${workspaceFolder}/out/**/*.js" ], "env": { "MOCHA_COLORS": "true" }, "presentation": { "hidden": true } }, { "type": "node", "request": "launch", "name": "Launch Smoke Test", "program": "${workspaceFolder}/test/smoke/test/index.js", "cwd": "${workspaceFolder}/test/smoke", "timeout": 240000, "args": [ "-l", "${workspaceFolder}/.build/electron/Code - OSS.app/Contents/MacOS/Electron" ], "outFiles": [ "${cwd}/out/**/*.js" ], "env": { "NODE_ENV": "development", "VSCODE_DEV": "1", "VSCODE_CLI": "1" } }, { "name": "Launch Built-in Extension", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceRoot}/extensions/debug-auto-launch" ] }, { "name": "Monaco Editor Playground", "type": "chrome", "request": "launch", "url": "http://localhost:5001", "preLaunchTask": "Launch Http Server", "presentation": { "group": "monaco", "order": 4 } } ], "compounds": [ { "name": "VS Code", "stopAll": true, "configurations": [ "Launch VS Code Internal", "Attach to Main Process", "Attach to Extension Host", "Attach to Shared Process", ], "preLaunchTask": "Ensure Prelaunch Dependencies", "presentation": { "group": "0_vscode", "order": 1 } }, { "name": "VS Code (Debug Observables)", "stopAll": true, "configurations": [ "Launch VS Code Internal (Dev Debug)", "Attach to Main Process", "Attach to Extension Host", "Attach to Shared Process", ], "preLaunchTask": "Ensure Prelaunch Dependencies", "presentation": { "group": "0_vscode", "order": 1 } }, { "name": "Search, Renderer, and Main processes", "configurations": [ "Launch VS Code Internal", "Attach to Main Process", "Attach to Search Process" ], "presentation": { "group": "1_vscode", "order": 4 } }, { "name": "Renderer, Extension Host, and Main processes", "configurations": [ "Launch VS Code Internal", "Attach to Main Process", "Attach to Extension Host" ], "presentation": { "group": "1_vscode", "order": 3 } }, { "name": "Debug Unit Tests", "configurations": [ "Attach to VS Code", "Run Unit Tests" ], "presentation": { "group": "1_vscode", "order": 2 } }, { "name": "Debug Unit Tests (Current File)", "configurations": [ "Attach to VS Code", "Run Unit Tests For Current File" ], "presentation": { "group": "1_vscode", "order": 2 } }, { "name": "Renderer and Main processes", "stopAll": true, "configurations": [ "Launch VS Code Internal", "Attach to Main Process" ], "preLaunchTask": "Ensure Prelaunch Dependencies" }, ] } ================================================ FILE: .vscode/notebooks/api.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "#### Config" }, { "kind": 2, "language": "github-issues", "value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"March 2025\"" }, { "kind": 1, "language": "markdown", "value": "### Finalization" }, { "kind": 2, "language": "github-issues", "value": "$REPO $MILESTONE label:api-finalization" }, { "kind": 1, "language": "markdown", "value": "### Proposals" }, { "kind": 2, "language": "github-issues", "value": "$REPO $MILESTONE is:open label:api-proposal sort:created-asc" } ] ================================================ FILE: .vscode/notebooks/endgame.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "#### Macros" }, { "kind": 2, "language": "github-issues", "value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n\r\n$MILESTONE=milestone:\"March 2025\"" }, { "kind": 1, "language": "markdown", "value": "# Preparation" }, { "kind": 1, "language": "markdown", "value": "## Open Pull Requests on the Milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:pr is:open" }, { "kind": 1, "language": "markdown", "value": "## Unverified Older Insiders-Released Issues" }, { "kind": 2, "language": "github-issues", "value": "$REPOS -$MILESTONE is:issue is:closed reason:completed label:bug label:insiders-released -label:verified -label:*duplicate -label:*as-designed -label:z-author-verified -label:on-testplan -label:error-telemetry" }, { "kind": 1, "language": "markdown", "value": "## Unverified Older Insiders-Released Feature Requests" }, { "kind": 2, "language": "github-issues", "value": "$REPOS -$MILESTONE is:issue is:closed reason:completed label:feature-request label:insiders-released -label:on-testplan -label:verified -label:*duplicate -label:error-telemetry" }, { "kind": 1, "language": "markdown", "value": "## Open Issues on the Milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:open -label:iteration-plan -label:endgame-plan -label:testplan-item" }, { "kind": 1, "language": "markdown", "value": "## Feature Requests Missing Labels" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate" }, { "kind": 1, "language": "markdown", "value": "## Open Test Plan Items without milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:open label:testplan-item no:milestone" }, { "kind": 1, "language": "markdown", "value": "# Testing" }, { "kind": 1, "language": "markdown", "value": "## Test Plan Items" }, { "kind": 2, "language": "github-issues", "value": "$REPOS is:issue is:open label:testplan-item" }, { "kind": 1, "language": "markdown", "value": "## Verification Needed" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed label:verification-needed -label:verified -label:on-testplan" }, { "kind": 1, "language": "markdown", "value": "# Verification" }, { "kind": 1, "language": "markdown", "value": "## Verifiable Fixes" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:z-author-verified -label:unreleased -label:*not-reproducible -label:*out-of-scope" }, { "kind": 1, "language": "markdown", "value": "## Verifiable Fixes Missing Steps" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug label:verification-steps-needed -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:z-author-verified -label:unreleased -label:*not-reproducible" }, { "kind": 1, "language": "markdown", "value": "## Unreleased Fixes" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:z-author-verified label:unreleased -label:*not-reproducible" }, { "kind": 1, "language": "markdown", "value": "## All Unverified Fixes" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:z-author-verified -label:*not-reproducible" }, { "kind": 1, "language": "markdown", "value": "# Candidates" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE is:issue is:open label:candidate" } ] ================================================ FILE: .vscode/notebooks/grooming-delta.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "## Config" }, { "kind": 2, "language": "github-issues", "value": "$since=2021-10-01" }, { "kind": 1, "language": "markdown", "value": "# vscode\n\nQuery exceeds the maximum result. Run the query manually: `is:issue is:open closed:>2021-10-01`" }, { "kind": 2, "language": "github-issues", "value": "//repo:microsoft/vscode is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "//repo:microsoft/vscode is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-remote-release" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-remote-release is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-remote-release is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-editor" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-editor is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-editor is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-docs" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-docs is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-docs is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-js-debug" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-js-debug is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-js-debug is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# language-server-protocol" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/language-server-protocol is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/language-server-protocol is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-eslint" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-eslint is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-eslint is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-css-languageservice" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-css-languageservice is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-css-languageservice is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-test" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-test is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-test is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-pull-request-github" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-pull-request-github is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-test is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-chrome-debug-core" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-chrome-debug-core is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-chrome-debug-core is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-debugadapter-node" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-debugadapter-node is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-debugadapter-node is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-emmet-helper" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-emmet-helper is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-emmet-helper is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-extension-vscode\n\nDeprecated" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-extension-vscode is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-extension-vscode is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-extension-samples" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-extension-samples is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-extension-samples is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-filewatcher-windows" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-filewatcher-windows is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-filewatcher-windows is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-generator-code" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-generator-code is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-generator-code is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-html-languageservice" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-html-languageservice is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-html-languageservice is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-json-languageservice" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-json-languageservice is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-json-languageservice is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-languageserver-node" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-languageserver-node is:issue closed:>$since" }, { "kind": 1, "language": "markdown", "value": "" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-languageserver-node is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-loader" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-loader is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-loader is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-mono-debug" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-mono-debug is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-mono-debug is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-node-debug" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-node-debug is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-node-debug is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-node-debug2" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-node-debug2 is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-node-debug2 is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-recipes" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-recipes is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-recipes is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-textmate" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-textmate is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-textmate is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-themes" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-themes is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-themes is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-vsce" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-vsce is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-vsce is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-website" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-website is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-website is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-windows-process-tree" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-windows-process-tree is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-windows-process-tree is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# debug-adapter-protocol" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/debug-adapter-protocol is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/debug-adapter-protocol is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# inno-updater" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/inno-updater is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/inno-updater is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-languages" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-languages is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-languages is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-typescript" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-typescript is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-typescript is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-css" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-css is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-css is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-json" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-json is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-json is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-html" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-html is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-html is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# monaco-editor-webpack-plugin" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-editor-webpack-plugin is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/monaco-editor-webpack-plugin is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# node-jsonc-parser" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/node-jsonc-parser is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/node-jsonc-parser is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-jupyter" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-jupyter is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-jupyter is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-python" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-python is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-python is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "# vscode-livepreview" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-livepreview is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-livepreview is:issue created:>$since" }, { "kind": 1, "language": "markdown", "value": "" }, { "kind": 1, "language": "markdown", "value": "# vscode-test" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-test is:issue closed:>$since" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-test is:issue created:>$since" } ] ================================================ FILE: .vscode/notebooks/grooming.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "#### Config" }, { "kind": 2, "language": "github-issues", "value": "// list of repos we work in\r\n$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n\r\n$assignee=@me\r\n" }, { "kind": 1, "language": "markdown", "value": "#### Missing Type label\r\n" }, { "kind": 2, "language": "github-issues", "value": "$repos assignee:$assignee is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering -label:endgame-plan\r\n" }, { "kind": 1, "language": "markdown", "value": "#### Missing Area Label\r\n\r\nFeature area labels are light or strong blue (`1d76db` or `c5def5`) and they denote a specific feature or feature area, like `editor-clipboard` or `file-explorer`\r\n" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode assignee:$assignee is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-widgets -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keyboard-layout -label:chat -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-accessibility -label:notebook-api -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commands -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-serialization -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:notebook-sticky-scroll -label:notebook-format -label:notebook-code-actions -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-sticky-scroll -label:terminal-tabs -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat -label:panel-chat -label:quick-chat -label:tasks -label:error-list -label:winget -label:tree-views -label:freeze-slow-crash-leak -label:engineering -label:cross-file-editing -label:microsoft-authentication -label:github-authentication -label:lm-access -label:secret-storage" }, { "kind": 1, "language": "markdown", "value": "### Missing Milestone\r\n" }, { "kind": 2, "language": "github-issues", "value": "$repos assignee:$assignee is:open type:issue no:milestone -label:info-needed -label:triage-needed -label:confirmation-pending -label:under-discussion\r\n" }, { "kind": 1, "language": "markdown", "value": "#### Not Actionable\r\n" }, { "kind": 2, "language": "github-issues", "value": "$repos assignee:$assignee is:open label:\"info-needed\"\r\n" } ] ================================================ FILE: .vscode/notebooks/inbox.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "## tl;dr: Triage Inbox\n\nAll inbox issues but not those that need more information. These issues need to be triaged, e.g assigned to a user or ask for more information" }, { "kind": 2, "language": "github-issues", "value": "$inbox -label:\"info-needed\" sort:created-desc" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode label:triage-needed is:open" }, { "kind": 1, "language": "markdown", "value": "##### `Config`: defines the inbox query" }, { "kind": 2, "language": "github-issues", "value": "$inbox=repo:microsoft/vscode is:open no:assignee -label:feature-request -label:testplan-item -label:plan-item " }, { "kind": 1, "language": "markdown", "value": "## Inbox tracking and Issue triage" }, { "kind": 1, "language": "markdown", "value": "New issues or pull requests submitted by the community are initially triaged by an [automatic classification bot](https://github.com/microsoft/vscode-github-triage-actions/tree/master/classifier-deep). Issues that the bot does not correctly triage are then triaged by a team member. The team rotates the inbox tracker on a weekly basis.\n\nA [mirror](https://github.com/JacksonKearl/testissues/issues) of the VS Code issue stream is available with details about how the bot classifies issues, including feature-area classifications and confidence ratings. Per-category confidence thresholds and feature-area ownership data is maintained in [.github/classifier.json](https://github.com/microsoft/vscode/blob/main/.github/classifier.json). \n\n💡 The bot is being run through a GitHub action that runs every 30 minutes. Give the bot the opportunity to classify an issue before doing it manually.\n\n### Inbox Tracking\n\nThe inbox tracker is responsible for the [global inbox](https://github.com/microsoft/vscode/issues?utf8=%E2%9C%93&q=is%3Aopen+no%3Aassignee+-label%3Afeature-request+-label%3Atestplan-item+-label%3Aplan-item) containing all **open issues and pull requests** that\n- are neither **feature requests** nor **test plan items** nor **plan items** and\n- have **no owner assignment**.\n\nThe **inbox tracker** may perform any step described in our [issue triaging documentation](https://github.com/microsoft/vscode/wiki/Issues-Triaging) but its main responsibility is to route issues to the actual feature area owner.\n\nFeature area owners track the **feature area inbox** containing all **open issues and pull requests** that\n- are personally assigned to them and are not assigned to any milestone\n- are labeled with their feature area label and are not assigned to any milestone.\nThis secondary triage may involve any of the steps described in our [issue triaging documentation](https://github.com/microsoft/vscode/wiki/Issues-Triaging) and results in a fully triaged or closed issue.\n\nThe [github triage extension](https://github.com/microsoft/vscode-github-triage-extension) can be used to assist with triaging — it provides a \"Command Palette\"-style list of triaging actions like assignment, labeling, and triggers for various bot actions." }, { "kind": 1, "language": "markdown", "value": "## All Inbox Items\n\nAll issues that have no assignee and that have neither **feature requests** nor **test plan items** nor **plan items**." }, { "kind": 2, "language": "github-issues", "value": "$inbox" } ] ================================================ FILE: .vscode/notebooks/my-endgame.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "#### Macros" }, { "kind": 2, "language": "github-issues", "value": "$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n$MILESTONE=milestone:\"March 2025\"\n\n$MINE=assignee:@me" }, { "kind": 1, "language": "markdown", "value": "# Preparation" }, { "kind": 1, "language": "markdown", "value": "## Open Pull Requests on the Milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:pr is:open" }, { "kind": 1, "language": "markdown", "value": "## Open Issues on the Milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:open -label:iteration-plan -label:endgame-plan -label:testplan-item" }, { "kind": 1, "language": "markdown", "value": "## Feature Requests Missing Labels" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate" }, { "kind": 1, "language": "markdown", "value": "## Test Plan Items" }, { "kind": 2, "language": "github-issues", "value": "$REPOS is:issue is:open author:@me label:testplan-item" }, { "kind": 1, "language": "markdown", "value": "## Verification Needed" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request label:verification-needed -label:verified -label:on-testplan" }, { "kind": 1, "language": "markdown", "value": "# Testing" }, { "kind": 1, "language": "markdown", "value": "## Test Plan Items" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MINE is:issue is:open label:testplan-item" }, { "kind": 1, "language": "markdown", "value": "## Verification Needed" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed -assignee:@me -label:verified -label:z-author-verified label:feature-request label:verification-needed -label:verification-steps-needed -label:unreleased -label:on-testplan" }, { "kind": 1, "language": "markdown", "value": "# Fixing" }, { "kind": 1, "language": "markdown", "value": "## Open Issues" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:open -label:endgame-plan -label:testplan-item -label:iteration-plan" }, { "kind": 1, "language": "markdown", "value": "## Open Bugs" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:open label:bug" }, { "kind": 1, "language": "markdown", "value": "# Verification" }, { "kind": 1, "language": "markdown", "value": "## My Issues (verification-steps-needed)" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue label:bug label:verification-steps-needed" }, { "kind": 1, "language": "markdown", "value": "## My Issues (verification-found)" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue label:bug label:verification-found" }, { "kind": 1, "language": "markdown", "value": "## Issues filed by me" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:triage-needed -label:verification-found -label:*not-reproducible" }, { "kind": 1, "language": "markdown", "value": "## Issues filed from outside team" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:*out-of-scope -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:andreamah -author:bamurtaugh -author:bpasero -author:chrisdias -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:ntrogh -author:hediet -author:isidorn -author:joaomoreno -author:joyceerhl -author:jrieken -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:tanhakabir -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger -author:karthiknadig -author:eleanorjboyd -author:Yoyokrazy -author:paulacamargo25 -author:ulugbekna -author:aiday-mar -author:daviddossett -author:bhavyaus -author:justschen -author:benibenj -author:luabud -author:anthonykim1 -author:joshspicer -author:osortega -author:legomushroom" }, { "kind": 1, "language": "markdown", "value": "## Issues filed by others" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed -author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -label:*not-reproducible -label:*out-of-scope" }, { "kind": 1, "language": "markdown", "value": "## Test steps needed from others" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed -label:verified" }, { "kind": 1, "language": "markdown", "value": "# Release Notes" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:on-release-notes\r\n$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:engineering -label:on-release-notes\r\n$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:plan-item -label:on-release-notes" } ] ================================================ FILE: .vscode/notebooks/my-work.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "##### `Config`: This should be changed every month/milestone" }, { "kind": 2, "language": "github-issues", "value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"March 2025\"\n" }, { "kind": 1, "language": "markdown", "value": "## Milestone Work" }, { "kind": 2, "language": "github-issues", "value": "$REPOS $MILESTONE assignee:@me is:open\n" }, { "kind": 1, "language": "markdown", "value": "## Bugs, Debt, Features..." }, { "kind": 1, "language": "markdown", "value": "#### My Bugs" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open label:bug\n" }, { "kind": 1, "language": "markdown", "value": "#### Debt & Engineering" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open label:debt,engineering\n" }, { "kind": 1, "language": "markdown", "value": "#### Performance 🐌 🔜 🏎" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open label:perf,perf-startup,perf-bloat,freeze-slow-crash-leak\n" }, { "kind": 1, "language": "markdown", "value": "#### Feature Requests" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open label:feature-request milestone:Backlog sort:reactions-+1-desc\n" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open milestone:\"Backlog Candidates\"\n" }, { "kind": 1, "language": "markdown", "value": "### Personal Inbox" }, { "kind": 1, "language": "markdown", "value": "#### Triage Needed" }, { "kind": 2, "language": "github-issues", "value": "$REPOS is:open assignee:@me label:triage-needed\n" }, { "kind": 1, "language": "markdown", "value": "\n#### Missing Type label" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering\n" }, { "kind": 1, "language": "markdown", "value": "#### Missing Area Label\n\nFeature area labels are light or strong blue (`1d76db` or `c5def5`) and they denote a specific feature or feature area, like `editor-clipboard` or `file-explorer`" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:code-lens -label:command-center -label:comments -label:config -label:context-keys -label:custom-editors -label:debug -label:debug-console -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-sticky-scroll-decorations -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet-parse -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extension-signature -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:icon-brand -label:icons-product -label:icons-widget -label:inlay-hints -label:inline-chat -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:javascript -label:json -label:json-sorting -label:keybindings -label:keybindings-editor -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:multi-monitor -label:native-file-dialog -label:network -label:notebook -label:notebook-accessibility -label:notebook-api -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-code-actions -label:notebook-commands -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-format -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-serialization -label:notebook-statusbar -label:notebook-sticky-scroll -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:panel-chat -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:quickpick-chat -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-desktop -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-search -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:system-context-menu -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:unc -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-documents -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-auxwindow -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-voice -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:error-list -label:winget -label:cross-file-editing -label:editor-refactor-preview" }, { "kind": 1, "language": "markdown", "value": "### Missing Milestone" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open type:issue no:milestone -label:info-needed -label:triage-needed\n" }, { "kind": 1, "language": "markdown", "value": "#### Not Actionable" }, { "kind": 2, "language": "github-issues", "value": "$REPOS assignee:@me is:open label:\"info-needed\"\n" }, { "kind": 1, "language": "markdown", "value": "### Pull Requests" }, { "kind": 1, "language": "markdown", "value": "✅ Approved" }, { "kind": 2, "language": "github-issues", "value": "$REPOS author:@me is:open is:pr review:approved\n" }, { "kind": 1, "language": "markdown", "value": "⌛ Pending Approval" }, { "kind": 2, "language": "github-issues", "value": "$REPOS author:@me is:open is:pr review:required\n" }, { "kind": 1, "language": "markdown", "value": "⚠️ Changes Requested" }, { "kind": 2, "language": "github-issues", "value": "$REPOS author:@me is:open is:pr review:changes_requested\n" } ] ================================================ FILE: .vscode/notebooks/papercuts.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "## Papercuts\n\nThis notebook serves as an ongoing collection of papercut issues that we encounter while dogfooding. With that in mind only promote issues that really turn you off, e.g. issues that make you want to stop using VS Code or its extensions. To mark an issue (bug, feature-request, etc.) as papercut add the labels: `papercut :drop_of_blood:`", "editable": true }, { "kind": 1, "language": "markdown", "value": "## All Papercuts\n\nThese are all papercut issues that we encounter while dogfooding vscode or extensions that we author.", "editable": true }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode is:open -label:notebook label:\"papercut :drop_of_blood:\"", "editable": true }, { "kind": 1, "language": "markdown", "value": "## Native Notebook", "editable": true }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode is:open label:notebook label:\"papercut :drop_of_blood:\"", "editable": true }, { "kind": 1, "language": "markdown", "value": "### My Papercuts", "editable": true }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode is:open assignee:@me label:\"papercut :drop_of_blood:\"", "editable": true } ] ================================================ FILE: .vscode/notebooks/verification.github-issues ================================================ [ { "kind": 1, "language": "markdown", "value": "### Bug Verification Queries\n\nBefore shipping we want to verify _all_ bugs. That means when a bug is fixed we check that the fix actually works. It's always best to start with bugs that you have filed and the proceed with bugs that have been filed from users outside the development team. " }, { "kind": 1, "language": "markdown", "value": "#### Config: update list of `repos` and the `milestone`" }, { "kind": 2, "language": "github-issues", "value": "$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n$milestone=milestone:\"November 2023\"\n$closedRecently=closed:>2023-09-29" }, { "kind": 1, "language": "markdown", "value": "### Bugs You Filed" }, { "kind": 2, "language": "github-issues", "value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate author:@me" }, { "kind": 1, "language": "markdown", "value": "### Bugs From Outside" }, { "kind": 2, "language": "github-issues", "value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand -author:rzhao271 -author:kieferrm -author:TylerLeonhardt -author:bamurtaugh -author:hediet -author:joyceerhl -author:rchiodo" }, { "kind": 1, "language": "markdown", "value": "### All" }, { "kind": 2, "language": "github-issues", "value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate" }, { "kind": 1, "language": "markdown", "value": "### Issues recently closed via PR without a milestone" }, { "kind": 2, "language": "github-issues", "value": "$repos is:closed linked:pr $closedRecently no:milestone -label:verified -label:*duplicate" } ] ================================================ FILE: .vscode/notebooks/vscode-dev.github-issues ================================================ [ { "kind": 2, "language": "github-issues", "value": "$milestone=milestone:\"August 2024\"" }, { "kind": 1, "language": "markdown", "value": "# vscode.dev repo" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-dev $milestone is:open" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-dev milestone:\"Backlog\" is:open" }, { "kind": 1, "language": "markdown", "value": "# VS Code repo" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode label:vscode.dev is:open" }, { "kind": 1, "language": "markdown", "value": "# GitHub Repositories repos" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-remote-repositories-github $milestone is:open" }, { "kind": 2, "language": "github-issues", "value": "repo:microsoft/vscode-remotehub $milestone is:open" } ] ================================================ FILE: .vscode/searches/ts36031.code-search ================================================ # Query: \\w+\\?\\.\\w+![(.[] # Flags: RegExp # ContextLines: 2 8 results - 4 files src/vs/base/browser/ui/tree/asyncDataTree.ts: 241 } : () => 'treeitem', 242 isChecked: options.accessibilityProvider!.isChecked ? (e) => { 243: return !!(options.accessibilityProvider?.isChecked!(e.element as T)); 244 } : undefined, 245 getAriaLabel(e) { src/vs/platform/list/browser/listService.ts: 463 464 if (typeof options?.openOnSingleClick !== 'boolean' && options?.configurationService) { 465: this.openOnSingleClick = options?.configurationService!.getValue(openModeSettingKey) !== 'doubleClick'; 466 this._register(options?.configurationService.onDidChangeConfiguration(() => { 467: this.openOnSingleClick = options?.configurationService!.getValue(openModeSettingKey) !== 'doubleClick'; 468 })); 469 } else { src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts: 1526 1527 await this._ensureActiveKernel(); 1528: await this._activeKernel?.cancelNotebookCell!(this._notebookViewModel!.uri, undefined); 1529 } 1530 1535 1536 await this._ensureActiveKernel(); 1537: await this._activeKernel?.executeNotebookCell!(this._notebookViewModel!.uri, undefined); 1538 } 1539 1553 1554 await this._ensureActiveKernel(); 1555: await this._activeKernel?.cancelNotebookCell!(this._notebookViewModel!.uri, cell.handle); 1556 } 1557 1567 1568 await this._ensureActiveKernel(); 1569: await this._activeKernel?.executeNotebookCell!(this._notebookViewModel!.uri, cell.handle); 1570 } 1571 src/vs/workbench/contrib/webview/electron-browser/iframeWebviewElement.ts: 89 .then(() => this._resourceRequestManager.ensureReady()) 90 .then(() => { 91: this.element?.contentWindow!.postMessage({ channel, args: data }, '*'); 92 }); 93 } ================================================ FILE: .vscode/settings.json ================================================ { "editor.insertSpaces": false, "files.trimTrailingWhitespace": true, "files.exclude": { ".git": true, ".build": true, ".profile-oss": true, "**/.DS_Store": true, ".vscode-test": true, "cli/target": true, "build/**/*.js.map": true, "build/**/*.js": { "when": "$(basename).ts" } }, "files.associations": { "cglicenses.json": "jsonc", "*.tst": "typescript" }, "search.exclude": { "**/node_modules": true, "cli/target/**": true, ".build/**": true, "out/**": true, "out-build/**": true, "out-vscode/**": true, "i18n/**": true, "extensions/**/dist/**": true, "extensions/**/out/**": true, "test/smoke/out/**": true, "test/automation/out/**": true, "test/integration/browser/out/**": true, "src/vs/base/test/common/filters.perf.data.js": true, "src/vs/base/test/node/uri.perf.data.txt": true, "src/vs/workbench/api/test/browser/extHostDocumentData.test.perf-data.ts": true, "src/vs/base/test/node/uri.test.data.txt": true, "src/vs/editor/test/node/diffing/fixtures/**": true, "build/loader.min": true }, "files.readonlyInclude": { "**/node_modules/**/*.*": true, "**/yarn.lock": true, "**/package-lock.json": true, "**/Cargo.lock": true, "build/**/*.js": true, "out/**": true, "out-build/**": true, "out-vscode/**": true, "out-vscode-reh/**": true, "extensions/**/dist/**": true, "extensions/**/out/**": true, "extensions/terminal-suggest/src/completions/upstream/**": true, "test/smoke/out/**": true, "test/automation/out/**": true, "test/integration/browser/out/**": true }, "files.readonlyExclude": { "build/builtin/*.js": true, "build/monaco/*.js": true, "build/npm/*.js": true, "build/*.js": true }, "lcov.path": [ "./.build/coverage/lcov.info", "./.build/coverage-single/lcov.info" ], "lcov.watch": [ { "pattern": "**/*.test.js", "command": "${workspaceFolder}/scripts/test.sh --coverage --run ${file}", "windows": { "command": "${workspaceFolder}\\scripts\\test.bat --coverage --run ${file}" } } ], "typescript.tsdk": "node_modules/typescript/lib", "npm.exclude": "**/extensions/**", "emmet.excludeLanguages": [], "typescript.preferences.importModuleSpecifier": "relative", "typescript.preferences.quoteStyle": "single", "json.schemas": [ { "fileMatch": [ "cgmanifest.json" ], "url": "https://json.schemastore.org/component-detection-manifest.json", }, { "fileMatch": [ "cglicenses.json" ], "url": "./.vscode/cglicenses.schema.json" } ], "git.ignoreLimitWarning": true, "git.branchProtection": [ "main", "distro", "release/*" ], "git.branchProtectionPrompt": "alwaysCommitToNewBranch", "git.branchRandomName.enable": true, "git.pullBeforeCheckout": true, "git.mergeEditor": true, "remote.extensionKind": { "msjsdiag.debugger-for-chrome": "workspace" }, "gulp.autoDetect": "off", "files.insertFinalNewline": true, "[plaintext]": { "files.insertFinalNewline": false }, "[typescript]": { "editor.defaultFormatter": "vscode.typescript-language-features", "editor.formatOnSave": true }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features", "editor.formatOnSave": true }, "[rust]": { "editor.defaultFormatter": "rust-lang.rust-analyzer", "editor.formatOnSave": true, }, "rust-analyzer.linkedProjects": [ "cli/Cargo.toml" ], "typescript.tsc.autoDetect": "off", "testing.autoRun.mode": "rerun", "conventionalCommits.scopes": [ "tree", "scm", "grid", "splitview", "table", "list", "git", "sash" ], "githubPullRequests.experimental.createView": true, "debug.javascript.terminalOptions": { "outFiles": [ "${workspaceFolder}/out/**/*.js", "${workspaceFolder}/build/**/*.js" ] }, "extension-test-runner.debugOptions": { "outFiles": [ "${workspaceFolder}/extensions/*/out/**/*.js", ] }, "githubPullRequests.assignCreated": "${user}", "githubPullRequests.defaultMergeMethod": "squash", "githubPullRequests.ignoredPullRequestBranches": [ "main" ], "application.experimental.rendererProfiling": true, "editor.experimental.asyncTokenization": true, "editor.experimental.asyncTokenizationVerification": true, "terminal.integrated.suggest.enabled": true, "typescript.preferences.autoImportFileExcludePatterns": [ "@xterm/xterm", "@xterm/headless", "node-pty", "vscode-notebook-renderer", "src/vs/workbench/workbench.web.main.internal.ts" ], "[github-issues]": { "editor.wordWrap": "on" }, "css.format.spaceAroundSelectorSeparator": true, "typescript.enablePromptUseWorkspaceTsdk": true, "eslint.useFlatConfig": true, "editor.occurrencesHighlightDelay": 0, "typescript.experimental.expandableHover": true, "git.diagnosticsCommitHook.Enabled": true, "git.diagnosticsCommitHook.Sources": { "*": "error", "ts": "warning", "eslint": "warning" } } ================================================ FILE: .vscode/shared.code-snippets ================================================ { // Each snippet is defined under a snippet name and has a scope, prefix, body and // description. The scope defines in watch languages the snippet is applicable. The prefix is what is // used to trigger the snippet and the body will be expanded and inserted.Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. // Placeholders with the same ids are connected. // Example: "MSFT Copyright Header": { "scope": "javascript,typescript,css,rust", "prefix": [ "header", "stub", "copyright" ], "body": [ "/*---------------------------------------------------------------------------------------------", " * Copyright (c) Microsoft Corporation. All rights reserved.", " * Licensed under the MIT License. See License.txt in the project root for license information.", " *--------------------------------------------------------------------------------------------*/", "", "$0" ], "description": "Insert Copyright Statement" }, "TS -> Inject Service": { "scope": "typescript", "description": "Constructor Injection Pattern", "prefix": "@inject", "body": "@$1 private readonly _$2: ${1},$0" }, "TS -> Event & Emitter": { "scope": "typescript", "prefix": "emitter", "description": "Add emitter and event properties", "body": [ "private readonly _onDid$1 = new Emitter<$2>();", "readonly onDid$1: Event<$2> = this._onDid$1.event;" ], } } ================================================ FILE: .vscode/tasks.json ================================================ { "version": "2.0.0", "tasks": [ { "type": "npm", "script": "watch-clientd", "label": "Core - Build", "isBackground": true, "presentation": { "reveal": "never", "group": "buildWatchers", "close": false }, "problemMatcher": { "owner": "typescript", "applyTo": "closedDocuments", "fileLocation": [ "absolute" ], "pattern": { "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", "file": 1, "location": 2, "message": 3 }, "background": { "beginsPattern": "Starting compilation...", "endsPattern": "Finished compilation with" } } }, { // Void added this "type": "npm", "script": "watchreactd", "label": "React - Build", "isBackground": true, "presentation": { "reveal": "never", "group": "buildWatchers", "close": false }, "problemMatcher": { "owner": "typescript", "applyTo": "closedDocuments", "fileLocation": [ "absolute" ], "pattern": { "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", "file": 1, "location": 2, "message": 3 }, "background": { "beginsPattern": "Starting compilation", "endsPattern": "Finished compilation" } } }, { "type": "npm", "script": "watch-extensionsd", "label": "Ext - Build", "isBackground": true, "presentation": { "reveal": "never", "group": "buildWatchers", "close": false }, "problemMatcher": { "owner": "typescript", "applyTo": "closedDocuments", "fileLocation": [ "absolute" ], "pattern": { "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", "file": 1, "location": 2, "message": 3 }, "background": { "beginsPattern": "Starting compilation", "endsPattern": "Finished compilation" } } }, { "label": "VS Code - Build", "dependsOn": [ "Core - Build", "React - Build", "Ext - Build" ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": [] }, { "type": "npm", "script": "kill-watch-clientd", "label": "Kill Core - Build", "group": "build", "presentation": { "reveal": "never", "group": "buildKillers", "close": true }, "problemMatcher": "$tsc" }, { "type": "npm", "script": "kill-watch-extensionsd", "label": "Kill Ext - Build", "group": "build", "presentation": { "reveal": "never", "group": "buildKillers", "close": true }, "problemMatcher": "$tsc" }, { "label": "Kill VS Code - Build", "dependsOn": [ "Kill Core - Build", "Kill Ext - Build" ], "group": "build", "problemMatcher": [] }, { "label": "Restart VS Code - Build", "dependsOn": [ "Kill VS Code - Build", "VS Code - Build" ], "group": "build", "dependsOrder": "sequence", "problemMatcher": [] }, { "label": "Kill VS Code - Build, Npm, VS Code - Build", "dependsOn": [ "Kill VS Code - Build", "npm: install", "VS Code - Build" ], "group": "build", "dependsOrder": "sequence", "problemMatcher": [] }, { "type": "npm", "script": "watch-webd", "label": "Web Ext - Build", "group": "build", "isBackground": true, "presentation": { "reveal": "never" }, "problemMatcher": { "owner": "typescript", "applyTo": "closedDocuments", "fileLocation": [ "absolute" ], "pattern": { "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", "file": 1, "location": 2, "message": 3 }, "background": { "beginsPattern": "Starting compilation", "endsPattern": "Finished compilation" } } }, { "type": "npm", "script": "kill-watch-webd", "label": "Kill Web Ext - Build", "group": "build", "presentation": { "reveal": "never" }, "problemMatcher": "$tsc" }, { "label": "Run tests", "type": "shell", "command": "./scripts/test.sh", "windows": { "command": ".\\scripts\\test.bat" }, "group": "test", "presentation": { "echo": true, "reveal": "always" } }, { "label": "Run Dev", "type": "shell", "command": "./scripts/code.sh", "windows": { "command": ".\\scripts\\code.bat" }, "problemMatcher": [] }, { "type": "npm", "script": "electron", "label": "Download electron" }, { "type": "gulp", "task": "hygiene", "problemMatcher": [] }, { "type": "shell", "command": "./scripts/code-server.sh", "windows": { "command": ".\\scripts\\code-server.bat" }, "args": ["--no-launch", "--connection-token", "dev-token", "--port", "8080"], "label": "Run code server", "isBackground": true, "problemMatcher": { "pattern": { "regexp": "" }, "background": { "beginsPattern": ".*node .*", "endsPattern": "Web UI available at .*" } }, "presentation": { "reveal": "never" } }, { "type": "shell", "command": "./scripts/code-web.sh", "windows": { "command": ".\\scripts\\code-web.bat" }, "args": ["--port", "8080", "--browser", "none"], "label": "Run code web", "isBackground": true, "problemMatcher": { "pattern": { "regexp": "" }, "background": { "beginsPattern": ".*node .*", "endsPattern": "Listening on .*" } }, "presentation": { "reveal": "never" } }, { "type": "npm", "script": "eslint", "problemMatcher": { "source": "eslint", "base": "$eslint-stylish" } }, { "type": "shell", "command": "node build/lib/preLaunch.js", "label": "Ensure Prelaunch Dependencies", "presentation": { "reveal": "silent", "close": true } }, { "type": "npm", "script": "tsec-compile-check", "problemMatcher": [ { "base": "$tsc", "applyTo": "allDocuments", "owner": "tsec" } ], "group": "build", "label": "npm: tsec-compile-check", "detail": "node_modules/tsec/bin/tsec -p src/tsconfig.json --noEmit" }, { // Used for monaco editor playground launch config "label": "Launch Http Server", "type": "shell", "command": "node_modules/.bin/ts-node -T ./scripts/playground-server", "isBackground": true, "problemMatcher": { "pattern": { "regexp": "" }, "background": { "activeOnStart": true, "beginsPattern": "never match", "endsPattern": ".*" } }, "dependsOn": [ "Core - Build" ] } ] } ================================================ FILE: .vscode-test.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check import { createRequire } from 'node:module'; import { fileURLToPath } from 'url'; import * as path from 'path'; import * as os from 'os'; const require = createRequire(import.meta.url); const __dirname = path.dirname(fileURLToPath(import.meta.url)); const { defineConfig } = require('@vscode/test-cli'); /** * A list of extension folders who have opted into tests, or configuration objects. * Edit me to add more! * * @type {Array & { label: string }>} */ const extensions = [ { label: 'markdown-language-features', workspaceFolder: `extensions/markdown-language-features/test-workspace`, mocha: { timeout: 60_000 } }, { label: 'ipynb', workspaceFolder: path.join(os.tmpdir(), `ipynb-${Math.floor(Math.random() * 100000)}`), mocha: { timeout: 60_000 } }, { label: 'notebook-renderers', workspaceFolder: path.join(os.tmpdir(), `nbout-${Math.floor(Math.random() * 100000)}`), mocha: { timeout: 60_000 } }, { label: 'vscode-colorize-tests', workspaceFolder: `extensions/vscode-colorize-tests/test`, mocha: { timeout: 60_000 } }, { label: 'terminal-suggest', workspaceFolder: path.join(os.tmpdir(), `terminal-suggest-${Math.floor(Math.random() * 100000)}`), mocha: { timeout: 60_000 } }, { label: 'vscode-colorize-perf-tests', workspaceFolder: `extensions/vscode-colorize-perf-tests/test`, mocha: { timeout: 6000_000 } }, { label: 'configuration-editing', workspaceFolder: path.join(os.tmpdir(), `confeditout-${Math.floor(Math.random() * 100000)}`), mocha: { timeout: 60_000 } }, { label: 'github-authentication', workspaceFolder: path.join(os.tmpdir(), `msft-auth-${Math.floor(Math.random() * 100000)}`), mocha: { timeout: 60_000 } }, { label: 'microsoft-authentication', mocha: { timeout: 60_000 } }, { label: 'vscode-api-tests-folder', extensionDevelopmentPath: `extensions/vscode-api-tests`, workspaceFolder: `extensions/vscode-api-tests/testWorkspace`, mocha: { timeout: 60_000 }, files: 'extensions/vscode-api-tests/out/singlefolder-tests/**/*.test.js', }, { label: 'vscode-api-tests-workspace', extensionDevelopmentPath: `extensions/vscode-api-tests`, workspaceFolder: `extensions/vscode-api-tests/testworkspace.code-workspace`, mocha: { timeout: 60_000 }, files: 'extensions/vscode-api-tests/out/workspace-tests/**/*.test.js', } ]; const defaultLaunchArgs = process.env.API_TESTS_EXTRA_ARGS?.split(' ') || [ '--disable-telemetry', '--skip-welcome', '--skip-release-notes', `--crash-reporter-directory=${__dirname}/.build/crashes`, `--logsPath=${__dirname}/.build/logs/integration-tests`, '--no-cached-data', '--disable-updates', '--use-inmemory-secretstorage', '--disable-extensions', '--disable-workspace-trust' ]; const config = defineConfig(extensions.map(extension => { /** @type {import('@vscode/test-cli').TestConfiguration} */ const config = { platform: 'desktop', files: `extensions/${extension.label}/out/**/*.test.js`, extensionDevelopmentPath: `extensions/${extension.label}`, ...extension, }; config.mocha ??= {}; if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { let suite = ''; if (process.env.VSCODE_BROWSER) { suite = `${process.env.VSCODE_BROWSER} Browser Integration ${config.label} tests`; } else if (process.env.REMOTE_VSCODE) { suite = `Remote Integration ${config.label} tests`; } else { suite = `Integration ${config.label} tests`; } config.mocha.reporter = 'mocha-multi-reporters'; config.mocha.reporterOptions = { reporterEnabled: 'spec, mocha-junit-reporter', mochaJunitReporterReporterOptions: { testsuitesTitle: `${suite} ${process.platform}`, mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) } }; } if (!config.platform || config.platform === 'desktop') { config.launchArgs = defaultLaunchArgs; config.useInstallation = { fromPath: process.env.INTEGRATION_TEST_ELECTRON_PATH || `${__dirname}/scripts/code.${process.platform === 'win32' ? 'bat' : 'sh'}`, }; config.env = { ...config.env, VSCODE_SKIP_PRELAUNCH: '1', }; } else { // web configs not supported, yet } return config; })); export default config; ================================================ FILE: CodeQL.yml ================================================ path_classifiers: test: # Classify all files in the top-level directories test/ and testsuites/ as test code. - test # Classify all files with suffix `.test` as test code. # Note: use only forward slash / as a path separator. # * Matches any sequence of characters except a forward slash. # ** Matches any sequence of characters, including a forward slash. # This wildcard must either be surrounded by forward slash symbols, or used as the first segment of a path. # It matches zero or more whole directory segments. There is no need to use a wildcard at the end of a directory path because all sub-directories are automatically matched. # That is, /anything/ matches the anything directory and all its subdirectories. # Always enclose the expression in double quotes if it includes *. - "**/*.test.ts" # The default behavior is to tag all files created during the # build as `generated`. Results are hidden for generated code. You can tag # further files as being generated by adding them to the `generated` section. generated: # generated code. - out - "out-build" - "out-vscode" - "**/out/**" - ".build/distro/cli-patches/index.js" # The default behavior is to tag library code as `library`. Results are hidden # for library code. You can tag further files as being library code by adding them # to the `library` section. library: - "**/node_modules/**" ================================================ FILE: HOW_TO_CONTRIBUTE.md ================================================ # Contributing to Void ### Welcome! 👋 This is the official guide on how to contribute to Void. We want to make it as easy as possible to contribute, so if you have any questions or comments, reach out via email or discord! There are a few ways to contribute: - 💫 Complete items on the [Roadmap](https://github.com/orgs/voideditor/projects/2). - 💡 Make suggestions in our [Discord](https://discord.gg/RSNjgaugJs). - 🪴 Start new Issues - see [Issues](https://github.com/voideditor/void/issues). ### Codebase Guide We [highly recommend reading this](https://github.com/voideditor/void/blob/main/VOID_CODEBASE_GUIDE.md) guide that we put together on Void's sourcecode if you'd like to add new features. The repo is not as intimidating as it first seems if you read the guide! Most of Void's code lives in the folder `src/vs/workbench/contrib/void/`. ## Editing Void's Code If you're making changes to Void's code as a contributor, you'll want to run a local version of Void to make sure your changes worked. Developer mode lets you do this. Here's how to use it. ### a. Mac - Prerequisites If you're using a Mac, you need Python and XCode. You probably have these by default. ### b. Windows - Prerequisites If you're using a Windows computer, first get [Visual Studio 2022](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community) (recommended) or [VS Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) (not recommended). If you already have both, you might need to run the next few steps on both of them. Go to the "Workloads" tab and select: - `Desktop development with C++` - `Node.js build tools` Go to the "Individual Components" tab and select: - `MSVC v143 - VS 2022 C++ x64/x86 Spectre-mitigated libs (Latest)` - `C++ ATL for latest build tools with Spectre Mitigations` - `C++ MFC for latest build tools with Spectre Mitigations` Finally, click Install. ### c. Linux - Prerequisites First, run `npm install -g node-gyp`. Then: - Debian (Ubuntu, etc): `sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev libkrb5-dev python-is-python3`. - Red Hat (Fedora, etc): `sudo dnf install @development-tools gcc gcc-c++ make libsecret-devel krb5-devel libX11-devel libxkbfile-devel`. - SUSE (openSUSE, etc): `sudo zypper install patterns-devel-C-C++-devel_C_C++ krb5-devel libsecret-devel libxkbfile-devel libX11-devel`. - Others: see [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute). ### Developer Mode Instructions Here's how to start changing Void's code. These steps cover everything from cloning Void, to opening a Developer Mode window where you can play around with your updates. 1. `git clone https://github.com/voideditor/void` to clone the repo. 2. `npm install` to install all dependencies. 3. Open Void or VSCode, and initialize Developer Mode (this can take ~5 min to finish, it's done when 2 of the 3 spinners turn to check marks): - Windows: Press Ctrl+Shift+B. - Mac: Press Cmd+Shift+B. - Linux: Press Ctrl+Shift+B. 4. Open the Void Developer Mode window: - Windows: `./scripts/code.bat`. - Mac: `./scripts/code.sh`. - Linux: `./scripts/code.sh`. 5. You're good to start editing Void's code! - You won't see your changes unless you press Ctrl+R (Cmd+R) inside the new window to reload. Alternatively, press Ctrl+Shift+P and `Reload Window`. - You might want to add the flags `--user-data-dir ./.tmp/user-data --extensions-dir ./.tmp/extensions` to the command in step 4, which lets you reset any IDE changes you made by deleting the `.tmp` folder. - You can kill any of the build scripts by pressing `Ctrl+D` in its terminal. If you press `Ctrl+C` the script will close but will keep running in the background. If you get any errors, scroll down for common fixes. #### Common Fixes - Make sure you followed the prerequisite steps above. - Make sure you have Node version `20.18.2` (the version in `.nvmrc`). - You can do this without changing your global Node version using [nvm](https://github.com/nvm-sh/nvm): run `nvm install`, followed by `nvm use` to install the version in `.nvmrc` locally. - Make sure the path to your Void folder does not have any spaces in it. - If you get `"TypeError: Failed to fetch dynamically imported module"`, make sure all imports end with `.js`. - If you get an error with React, try running `NODE_OPTIONS="--max-old-space-size=8192" npm run buildreact`. - If you see missing styles, wait a few seconds and then reload. - If you get errors like `npm error libtool: error: unrecognised option: '-static'`, when running ./scripts/code.sh, make sure you have GNU libtool instead of BSD libtool (BSD is the default in macos) - If you get errors like `The SUID sandbox helper binary was found, but is not configured correctly` when running ./scripts/code.sh, run `sudo chown root:root .build/electron/chrome-sandbox && sudo chmod 4755 .build/electron/chrome-sandbox` and then run `./scripts/code.sh` again. - If you have any other questions, feel free to [submit an issue](https://github.com/voideditor/void/issues/new). You can also refer to VSCode's complete [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) page. #### Building Void from Terminal To build Void from the terminal instead of from inside VSCode, follow the steps above, but instead of pressing Cmd+Shift+B, run `npm run watch`. The build is done when you see something like this: ``` [watch-extensions] [00:37:39] Finished compilation extensions with 0 errors after 19303 ms [watch-client ] [00:38:06] Finished compilation with 0 errors after 46248 ms [watch-client ] [00:38:07] Starting compilation... [watch-client ] [00:38:07] Finished compilation with 0 errors after 5 ms ``` ### Distributing Void's maintainers distribute Void on our website and in releases. Our build pipeline is a fork of VSCodium, and it works by running GitHub Actions which create the downloadables. The build repo with more instructions lives [here](https://github.com/voideditor/void-builder). If you want to completely control Void's build pipeline for your own internal usage, which comes with a lot of time cost (and is typically not recommended), see our [`void-builder`](https://github.com/voideditor/void-builder) repo which builds Void and contains a few important notes about auto-updating and rebasing. #### Building a Local Executible We don't usually recommend building a local executible of Void - typically you should follow the steps above to distribute a complete executible with the advantages of VSCodium baked-in, or you should just use Developer Mode to run Void locally which is much faster. If you're certain this is what you want, see details below.
Building Locally (not recommended) If you're certain you want to build a local executible of Void, follow these steps. It can take ~25 minutes. Make sure you've already entered Developer Mode with Void first, then run one of the following commands. This will create a folder named `VSCode-darwin-arm64` or similar outside of the void/ repo (see below). ##### Mac - `npm run gulp vscode-darwin-arm64` - most common (Apple Silicon) - `npm run gulp vscode-darwin-x64` (Intel) ##### Windows - `npm run gulp vscode-win32-x64` - most common - `npm run gulp vscode-win32-arm64` ##### Linux - `npm run gulp vscode-linux-x64` - most common - `npm run gulp vscode-linux-arm64` ##### Local Executible Output The local executible will be located in a folder outside of `void/`: ```bash workspace/ ├── void/ # Your Void fork └── VSCode-darwin-arm64/ # Generated output ```
## Pull Request Guidelines - Please submit a pull request once you've made a change. - No need to submit an Issue unless you're creating a new feature that might involve multiple PRs. - Please don't use AI to write your PR 🙂 ================================================ FILE: LICENSE-VS-Code.txt ================================================ Void is a fork of VS Code, which is licensed under the MIT License (below). Void's additions and modifications are licensed under the Apache 2.0 License (see LICENSE.txt). -------------------- MIT License Copyright (c) 2015 - present Microsoft Corporation 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. ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2025 Glass Devtools, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # Welcome to Void.
Void Welcome
Void is the open-source Cursor alternative. Use AI agents on your codebase, checkpoint and visualize changes, and bring any model or host locally. Void sends messages directly to providers without retaining your data. This repo contains the full sourcecode for Void. If you're new, welcome! - 🧭 [Website](https://voideditor.com) - 👋 [Discord](https://discord.gg/RSNjgaugJs) - 🚙 [Project Board](https://github.com/orgs/voideditor/projects/2) ## Note We've paused work on the Void IDE (this repo) to explore a few novel coding ideas. We want to focus on innovation over feature-parity. Void will continue running, but without maintenance some existing features might stop working over time. Depending on the direction of our new work, we might not resume Void as an IDE. We won't be actively reviewing Issues and PRs, but we will respond to all [email](mailto:hello@voideditor.com) inquiries on building and maintaining your own version of Void while we're paused. ## Reference Void is a fork of the [vscode](https://github.com/microsoft/vscode) repository. For a guide to the codebase, see [VOID_CODEBASE_GUIDE](https://github.com/voideditor/void/blob/main/VOID_CODEBASE_GUIDE.md). For a guide on how to develop your own version of Void, see [HOW_TO_CONTRIBUTE](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md) and [void-builder](https://github.com/voideditor/void-builder). ## Support You can always reach us in our Discord server or contact us via email: hello@voideditor.com. ================================================ FILE: ThirdPartyNotices.txt ================================================ NOTICES This repository incorporates material as listed below or described in the code. --------------------------------------------------------- @fig/autocomplete-shared 1.1.2 https://github.com/withfig/autocomplete-tools MIT License Copyright (c) 2021 Hercules Labs Inc. (Fig) 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. --------------------------------------------------------- --------------------------------------------------------- @iktakahiro/markdown-it-katex 4.0.2 - MIT https://github.com/mjbvz/markdown-it-katex The MIT License (MIT) Copyright (c) 2016 Waylon Flinn 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. --- The MIT License (MIT) Copyright (c) 2018 Takahiro Ethan Ikeuchi @iktakahiro 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. --------------------------------------------------------- --------------------------------------------------------- amazon-q-developer-cli f66e0b0e917ab185eef528dc36eca56b78ca8b5d https://github.com/aws/amazon-q-developer-cli MIT License Copyright (c) 2024 Amazon.com, Inc. or its affiliates. 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. --------------------------------------------------------- --------------------------------------------------------- atom/language-clojure 0.22.8 - MIT https://github.com/atom/language-clojure Copyright (c) 2014 GitHub Inc. 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. This package was derived from a TextMate bundle located at https://github.com/mmcgrana/textmate-clojure and distributed under the following license, located in `LICENSE.md`: The MIT License (MIT) Copyright (c) 2010- Mark McGranaghan 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. --------------------------------------------------------- --------------------------------------------------------- atom/language-coffee-script 0.49.3 - MIT https://github.com/atom/language-coffee-script The MIT License (MIT) Copyright (c) 2014 GitHub Inc. 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. This package was derived from a TextMate bundle located at https://github.com/jashkenas/coffee-script-tmbundle and distributed under the following license, located in `LICENSE`: Copyright (c) 2009-2014 Jeremy Ashkenas 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. --------------------------------------------------------- --------------------------------------------------------- atom/language-sass 0.61.4 - MIT https://github.com/atom/language-sass The MIT License (MIT) Copyright (c) 2014 GitHub Inc. 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. This package was derived from a TextMate bundle located at https://github.com/alexsancho/Sass.tmbundle and distributed under the following license, located in `LICENSE.md`: Copyright (c) 2012 Alex Sancho, http://alexsancho.name/ 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. --------------------------------------------------------- --------------------------------------------------------- atom/language-xml 0.35.2 - MIT https://github.com/atom/language-xml The MIT License (MIT) Copyright (c) 2014 GitHub Inc. 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. This package was derived from a TextMate bundle located at https://github.com/textmate/xml.tmbundle and distributed under the following license, located in `README.mdown`: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. --------------------------------------------------------- --------------------------------------------------------- autocomplete 2.684.0 - MIT https://github.com/withfig/autocomplete MIT License Copyright (c) 2021 Hercules Labs Inc. (Fig) 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. --------------------------------------------------------- --------------------------------------------------------- cacheable-request 7.0.4 - MIT Copyright (c) cacheable-request authors MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- Colorsublime-Themes 0.1.0 https://github.com/Colorsublime/Colorsublime-Themes Copyright (c) 2015 Colorsublime.com 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. --------------------------------------------------------- --------------------------------------------------------- daaain/Handlebars 1.8.0 - MIT https://github.com/daaain/Handlebars -- Credits Adapted from the great sublime-text-handlebars package by Nicholas Westlake. Thanks a lot to all the generous contributors (in alphabetical order): @bittersweetryan, @bradcliffe, @calumbrodie, @duncanbeevers, @hlvnst, @jonschlinkert, @Krutius, @samselikoff, @utkarshkukreti, @zeppelin -- License (The MIT License) Copyright (c) daaain/Handlebars project authors 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. --------------------------------------------------------- --------------------------------------------------------- dart-lang/dart-syntax-highlight 0.0.0 - BSD https://github.com/dart-lang/dart-syntax-highlight Copyright 2020, the Dart project authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------- --------------------------------------------------------- davidrios/pug-tmbundle 0.0.0 - MIT https://github.com/davidrios/pug-tmbundle The MIT License (MIT) Copyright (c) 2016 David Rios 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. --------------------------------------------------------- --------------------------------------------------------- definitelytyped - MIT https://github.com/DefinitelyTyped/DefinitelyTyped This project is licensed under the MIT license. Copyrights are respective of each contributor listed at the beginning of each definition file. 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. --------------------------------------------------------- --------------------------------------------------------- Document Object Model 4.0.0 - W3C License https://www.w3.org/DOM/ W3C License This work is being provided by the copyright holders under the following license. By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications: * The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. * Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included. * Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived from Document Object Model. Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang)." Disclaimers THIS WORK IS PROVIDED "AS IS AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders. --------------------------------------------------------- --------------------------------------------------------- dompurify 3.1.7 - Apache 2.0 https://github.com/cure53/DOMPurify DOMPurify Copyright 2025 Dr.-Ing. Mario Heiderich, Cure53 DOMPurify is free software; you can redistribute it and/or modify it under the terms of either: a) the Apache License Version 2.0, or b) the Mozilla Public License Version 2.0 ----------------------------------------------------------------------------- Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. --------------------------------------------------------- --------------------------------------------------------- dotnet/csharp-tmLanguage 0.1.0 - MIT https://github.com/dotnet/csharp-tmLanguage MIT License Copyright (c) 2016 .NET Foundation 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. --------------------------------------------------------- --------------------------------------------------------- dotnet/razor 1.0.0 - MIT https://github.com/dotnet/razor MIT License Copyright (c) .NET Foundation and Contributors All Rights Reserved 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. --------------------------------------------------------- --------------------------------------------------------- expand-abbreviation 0.5.8 - MIT https://github.com/emmetio/expand-abbreviation MIT License Copyright (c) 2017 Emmet.io 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. --------------------------------------------------------- --------------------------------------------------------- fadeevab/make.tmbundle 0.0.0 - TextMate Bundle License https://github.com/fadeevab/make.tmbundle Copyright (c) textmate-make.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- fish-shell 3.7.1 https://github.com/fish-shell/fish-shell Fish is a smart and user-friendly command line shell. Copyright (C) 2005-2009 Axel Liljencrantz Copyright (C) 2009- fish-shell contributors fish is free software. Most of fish is licensed under the GNU General Public License version 2, and you can redistribute it and/or modify it under the terms of the GNU GPL as published by the Free Software Foundation. fish also includes software licensed under the Python Software Foundation License version 2, the MIT license, and the GNU Library General Public License version 2. Full licensing information is contained in doc_src/license.rst. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. --------------------------------------------------------- --------------------------------------------------------- go-syntax 0.7.9 - MIT https://github.com/worlpaker/go-syntax MIT License Copyright (c) 2023 Furkan Ozalp 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. --------------------------------------------------------- --------------------------------------------------------- HTML 5.1 W3C Working Draft 08 October 2015 - W3C Document License http://www.w3.org/TR/2015/WD-html51-20151008/ Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.) THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders. --------------------------------------------------------- --------------------------------------------------------- Ionic documentation 1.2.4 - Apache-2.0 https://github.com/ionic-team/ionic-site Copyright Drifty Co. http://drifty.com/. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS --------------------------------------------------------- --------------------------------------------------------- ionide/ionide-fsgrammar 0.0.0 - MIT https://github.com/ionide/ionide-fsgrammar The MIT License (MIT) Copyright (c) 2015 Krzysztof Cieslak 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. --------------------------------------------------------- --------------------------------------------------------- James-Yu/LaTeX-Workshop 8.19.1 - MIT https://github.com/James-Yu/LaTeX-Workshop The MIT License (MIT) Copyright (c) 2016 James Yu 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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-c-syntax 1.13.2 - MIT https://github.com/jeff-hykin/better-c-syntax MIT License Copyright (c) 2019 Jeff Hykin 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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-cpp-syntax 1.17.4 - MIT https://github.com/jeff-hykin/better-cpp-syntax MIT License,,Copyright (c) 2019 Jeff Hykin,,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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-objc-syntax 0.2.0 - MIT https://github.com/jeff-hykin/better-objc-syntax MIT License Copyright (c) 2019 Jeff Hykin 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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-objcpp-syntax 0.1.0 - MIT https://github.com/jeff-hykin/better-objcpp-syntax MIT License Copyright (c) 2019 Jeff Hykin 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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-shell-syntax 1.8.7 - MIT https://github.com/jeff-hykin/better-shell-syntax MIT License Copyright (c) 2019 Jeff Hykin 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. --------------------------------------------------------- --------------------------------------------------------- jeff-hykin/better-snippet-syntax 1.0.2 - MIT https://github.com/jeff-hykin/better-snippet-syntax MIT License Copyright (c) 2019 Jeff Hykin 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. --------------------------------------------------------- --------------------------------------------------------- jlelong/vscode-latex-basics 1.9.0 - MIT https://github.com/jlelong/vscode-latex-basics Copyright (c) vscode-latex-basics authors If not otherwise specified (see below), files in this repository fall under the MIT License The file syntaxes/LaTeX.tmLanguage.json is based on https://github.com/textmate/latex.tmbundle/blob/master/Syntaxes/LaTeX.plist but has been largely modified. The original file falls under the following license Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. The file syntaxes/markdown-latex-combined.tmLanguage.json is generated from the Markdown grammar included in VSCode and falls under the license described in markdown-latex-combined-license.txt. The file syntaxes/cpp-grammar-bailout.tmLanguage.json is generated from https://github.com/jeff-hykin/better-cpp-syntax and falls under the license described in cpp-bailout-license.txt. --------------------------------------------------------- --------------------------------------------------------- js-beautify 1.6.8 - MIT https://github.com/beautify-web/js-beautify The MIT License (MIT) Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. 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. --------------------------------------------------------- --------------------------------------------------------- jtbandes/swift-tmlanguage - MIT https://github.com/jtbandes/swift-tmlanguage The MIT License (MIT) Copyright 2023 Jacob Bandes-Storch 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. --------------------------------------------------------- --------------------------------------------------------- JuliaEditorSupport/atom-language-julia 0.23.0 - MIT https://github.com/JuliaEditorSupport/atom-language-julia The atom-language-julia package is licensed under the MIT "Expat" License: > Copyright (c) 2015 > > 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. --------------------------------------------------------- --------------------------------------------------------- Jxck/assert 1.0.0 - MIT https://github.com/Jxck/assert The MIT License (MIT) Copyright (c) 2011 Jxck Originally from node.js (http://nodejs.org) Copyright Joyent, Inc. 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. --------------------------------------------------------- --------------------------------------------------------- language-docker 0.0.0 - Apache-2.0 https://github.com/moby/moby Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS Copyright 2013-2018 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- language-less 0.6.1 - MIT https://github.com/radium-v/Better-Less MIT License Copyright (c) 2017 John Kreitlow 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. --------------------------------------------------------- --------------------------------------------------------- language-php 0.49.0 - MIT https://github.com/KapitanOczywisty/language-php The MIT License (MIT) Copyright (c) 2014 GitHub Inc. 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. This package was derived from a TextMate bundle located at https://github.com/textmate/php.tmbundle and distributed under the following license, located in `README.mdown`: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. --------------------------------------------------------- --------------------------------------------------------- MagicStack/MagicPython 1.1.1 - MIT https://github.com/MagicStack/MagicPython The MIT License Copyright (c) 2015-present MagicStack Inc. http://magic.io 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. --------------------------------------------------------- --------------------------------------------------------- marked 14.0.0 - MIT https://github.com/markedjs/marked information ## Contribution License Agreement If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. `` ## Marked Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/) Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/) 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. ## Markdown Copyright © 2004, John Gruber http://daringfireball.net/ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. --------------------------------------------------------- --------------------------------------------------------- microsoft/TypeScript-TmLanguage 0.0.1 - MIT https://github.com/microsoft/TypeScript-TmLanguage Copyright (c) Microsoft Corporation All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- microsoft/vscode-css 0.0.0 - MIT License https://github.com/microsoft/vscode-css MIT License Copyright (c) Microsoft Corporation. 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. -------------------------------------------------------------------- This package was derived from a TextMate bundle located at https://github.com/textmate/css.tmbundle and distributed under the following license, located in `README.mdown`: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. --------------------------------------------------------- --------------------------------------------------------- microsoft/vscode-JSON.tmLanguage 0.0.0 - MIT https://github.com/microsoft/vscode-JSON.tmLanguage vscode-JSON.tmLanguage Copyright (c) Microsoft Corporation All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- microsoft/vscode-markdown-tm-grammar 1.0.0 - MIT https://github.com/microsoft/vscode-markdown-tm-grammar The MIT License (MIT) Copyright (c) Microsoft 2018 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. --------------------------------------------------------- --------------------------------------------------------- microsoft/vscode-mssql 1.29.0 - MIT https://github.com/microsoft/vscode-mssql ------------------------------------------ START OF LICENSE ----------------------------------------- vscode-mssql Copyright (c) Microsoft Corporation All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Copyright (c) 2016 Microsoft The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------- END OF LICENSE ----------------------------------------- --------------------------------------------------------- --------------------------------------------------------- mmims/language-batchfile 0.7.6 - MIT https://github.com/mmims/language-batchfile The MIT License (MIT) Copyright (c) 2021 Michael Mims 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. --------------------------------------------------------- --------------------------------------------------------- NVIDIA/cuda-cpp-grammar 0.0.0 - MIT https://github.com/NVIDIA/cuda-cpp-grammar The MIT License (MIT) Copyright 2021 NVIDIA Corporation 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. --------------------------------------------------------- --------------------------------------------------------- PowerShell/EditorSyntax 1.0.0 - MIT https://github.com/PowerShell/EditorSyntax Copyright (c) Microsoft Corporation All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- RedCMD/YAML-Syntax-Highlighter 1.3.2 - MIT https://github.com/RedCMD/YAML-Syntax-Highlighter MIT License Copyright 2024 RedCMD 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. --------------------------------------------------------- --------------------------------------------------------- redhat-developer/vscode-java 1.26.0 - MIT https://github.com/redhat-developer/vscode-java The MIT License (MIT) Copyright (c) 2014 GitHub Inc. 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. -------------------------------------------------------------------- This package was derived from a TextMate bundle located at https://github.com/textmate/java.tmbundle and distributed under the following license, located in `README.mdown`: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. --------------------------------------------------------- --------------------------------------------------------- REditorSupport/vscode-R 2.8.4 - MIT https://github.com/REditorSupport/vscode-R MIT License Copyright (c) 2022 REditorSupport 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. --------------------------------------------------------- --------------------------------------------------------- rust-syntax 0.6.1 - MIT https://github.com/dustypomerleau/rust-syntax MIT License Copyright (c) 2020 Dustin Pomerleau 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. --------------------------------------------------------- --------------------------------------------------------- semver 5.5.0 - The ISC License https://github.com/npm/node-semver The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- seti-ui 0.1.0 https://github.com/jesseweed/seti-ui Copyright (c) 2014 Jesse Weed 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. --------------------------------------------------------- --------------------------------------------------------- shaders-tmLanguage 0.1.0 - MIT https://github.com/tgjones/shaders-tmLanguage MIT License Copyright (c) 2017 Tim Jones 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. --------------------------------------------------------- --------------------------------------------------------- Shopify/ruby-lsp 0.0.0 - MIT License https://github.com/Shopify/ruby-lsp The MIT License (MIT) Copyright (c) 2022-present, Shopify Inc. 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. ================================================================================ The following files and related configuration in package.json are based on a sequence of adaptions: grammars/ruby.cson.json, grammars/erb.cson.json, languages/erb.json. Copyright (c) 2016 Peng Lv Copyright (c) 2017-2019 Stafford Brunk https://github.com/rubyide/vscode-ruby Released under the MIT license https://github.com/rubyide/vscode-ruby/blob/main/LICENSE.txt Copyright (c) 2014 GitHub Inc. https://github.com/atom/language-ruby Released under the MIT license https://github.com/atom/language-ruby/blob/master/LICENSE.md https://github.com/textmate/ruby.tmbundle https://github.com/textmate/ruby.tmbundle#license --------------------------------------------------------- --------------------------------------------------------- sumneko/lua.tmbundle 1.0.0 - TextMate Bundle License https://github.com/sumneko/lua.tmbundle Copyright (c) sumneko-lua.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/asp.vb.net.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/asp.vb.net.tmbundle Copyright (c) textmate-asp.vb.net.tmbundle project authors If not otherwise specified (see below), files in this folder fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/c.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/c.tmbundle Copyright (c) textmate-c.tmbundle authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/diff.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/diff.tmbundle Copyright (c) textmate-diff.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/git.tmbundle 0.0.0 - MIT https://github.com/textmate/git.tmbundle The MIT License (MIT) Copyright (c) 2008 Tim Harper 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. --------------------------------------------------------- --------------------------------------------------------- textmate/groovy.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/groovy.tmbundle Copyright (c) textmate-groovy.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/html.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/html.tmbundle Copyright (c) textmate-html.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/ini.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/ini.tmbundle Copyright (c) textmate-ini.tmbundle project authors If not otherwise specified (see below), files in this folder fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/javascript.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/javascript.tmbundle Copyright (c) textmate-javascript.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/markdown.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/markdown.tmbundle Copyright (c) markdown.tmbundle authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- textmate/perl.tmbundle 0.0.0 - TextMate Bundle License https://github.com/textmate/perl.tmbundle Copyright (c) textmate-perl.tmbundle project authors If not otherwise specified (see below), files in this repository fall under the following license: Permission to copy, use, modify, sell and distribute this software is granted. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt". --------------------------------------------------------- --------------------------------------------------------- trond-snekvik/vscode-rst 1.5.3 - MIT https://github.com/trond-snekvik/vscode-rst The MIT License (MIT) Copyright 2021 Trond Snekvik 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. --------------------------------------------------------- --------------------------------------------------------- TypeScript-TmLanguage 0.1.8 - MIT TypeScript-TmLanguage 1.0.0 - MIT https://github.com/microsoft/TypeScript-TmLanguage Copyright (c) Microsoft Corporation All rights reserved. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- Unicode 12.0.0 - UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE https://home.unicode.org/ Unicode Data Files include all data files under the directories https://www.unicode.org/Public/, https://www.unicode.org/reports/, https://cldr.unicode.org, https://github.com/unicode-org/icu, and https://www.unicode.org/utility/trac/browser/. Unicode Data Files do not include PDF online code charts under the directory https://www.unicode.org/Public/. Software includes any source code published in the Unicode Standard or under the directories https://www.unicode.org/Public/, https://www.unicode.org/reports/, https://cldr.unicode.org, https://github.com/unicode-org/icu, and https://www.unicode.org/utility/trac/browser/. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE Copyright (c) 1991-2017 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. --------------------------------------------------------- --------------------------------------------------------- vscode-codicons 0.0.14 - MIT and Creative Commons Attribution 4.0 https://github.com/microsoft/vscode-codicons Attribution 4.0 International ======================================================================= Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. Using Creative Commons Public Licenses Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason--for example, because of any applicable exception or limitation to copyright--then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More_considerations for the public: wiki.creativecommons.org/Considerations_for_licensees ======================================================================= Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. Section 1 -- Definitions. a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. Section 2 -- Scope. a. License grant. 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: a. reproduce and Share the Licensed Material, in whole or in part; and b. produce, reproduce, and Share Adapted Material. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 3. Term. The term of this Public License is specified in Section 6(a). 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a) (4) never produces Adapted Material. 5. Downstream recipients. a. Offer from the Licensor -- Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. b. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). b. Other rights. 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 2. Patent and trademark rights are not licensed under this Public License. 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. Section 3 -- License Conditions. Your exercise of the Licensed Rights is expressly made subject to the following conditions. a. Attribution. 1. If You Share the Licensed Material (including in modified form), You must: a. retain the following if it is supplied by the Licensor with the Licensed Material: i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); ii. a copyright notice; iii. a notice that refers to this Public License; iv. a notice that refers to the disclaimer of warranties; v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; b. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and c. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. Section 4 -- Sui Generis Database Rights. Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. Section 5 -- Disclaimer of Warranties and Limitation of Liability. a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. Section 6 -- Term and Termination. a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 2. upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. Section 7 -- Other Terms and Conditions. a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. Section 8 -- Interpretation. a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. ======================================================================= Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the "Licensor." The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. --------------------------------------------------------- --------------------------------------------------------- vscode-logfile-highlighter 3.3.4 - MIT https://github.com/emilast/vscode-logfile-highlighter The MIT License (MIT) Copyright (c) 2015 emilast 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. --------------------------------------------------------- --------------------------------------------------------- vscode-swift 0.0.1 - MIT https://github.com/owensd/vscode-swift The MIT License (MIT) Copyright (c) 2015 David Owens II 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. --------------------------------------------------------- --------------------------------------------------------- vscode-win32-app-container-tokens https://github.com/microsoft/vscode-win32-app-container-tokens MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- walles/git-commit-message-plus 1.0.0 - MIT https://github.com/walles/git-commit-message-plus The MIT License (MIT) Copyright (c) 2023 Johan Walles 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. --------------------------------------------------------- --------------------------------------------------------- Web Background Synchronization - Apache-2.0 https://github.com/WICG/background-sync Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- zsh 5.9 https://github.com/zsh-users/zsh Unless otherwise noted in the header of specific files, files in this distribution have the licence shown below. However, note that certain shell functions are licensed under versions of the GNU General Public Licence. Anyone distributing the shell as a binary including those files needs to take account of this. Search shell functions for "Copyright" for specific copyright information. None of the core functions are affected by this, so those files may simply be omitted. -- The Z Shell is copyright (c) 1992-2017 Paul Falstad, Richard Coleman, Zoltán Hidvégi, Andrew Main, Peter Stephenson, Sven Wischnowsky, and others. All rights reserved. Individual authors, whether or not specifically named, retain copyright in all changes; in what follows, they are referred to as `the Zsh Development Group'. This is for convenience only and this body has no legal status. The Z shell is distributed under the following licence; any provisions made in individual files take precedence. Permission is hereby granted, without written agreement and without licence or royalty fees, to use, copy, modify, and distribute this software and to distribute modified versions of this software for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. In no event shall the Zsh Development Group be liable to any party for direct, indirect, special, incidental, or consequential damages arising out of the use of this software and its documentation, even if the Zsh Development Group have been advised of the possibility of such damage. The Zsh Development Group specifically disclaim any warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The software provided hereunder is on an "as is" basis, and the Zsh Development Group have no obligation to provide maintenance, support, updates, enhancements, or modifications. --------------------------------------------------------- ================================================ FILE: VOID_CODEBASE_GUIDE.md ================================================ # Void Codebase Guide The Void codebase is not as intimidating as it seems! Most of Void's code lives in the folder `src/vs/workbench/contrib/void/`. The purpose of this document is to explain how Void's codebase works. If you want build instructions instead, see [Contributing](https://github.com/voideditor/void/blob/main/HOW_TO_CONTRIBUTE.md). ## Void Codebase Guide ### VSCode Rundown Here's a VSCode rundown if you're just getting started with Void. You can also see Microsoft's [wiki](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) for some pictures. VSCode is an Electron app. Electron runs two processes: a **main** process (for internals) and a **browser** process (browser means HTML in general, not just "web browser").

Credit - https://github.com/microsoft/vscode/wiki/Source-Code-Organization

- Code in a `browser/` folder always lives on the browser process, and it can use `window` and other browser items. - Code in an `electron-main/` folder always lives on the main process, and it can import `node_modules`. - Code in `common/` can be used by either process, but doesn't get any special imports. - The browser environment is not allowed to import `node_modules`. We came up with two workarounds: 1. Bundle the raw node_module code to the browser - we're doing this for React. 2. Implement the code on `electron-main/` and set up a channel between main/browser - we're doing this for sendLLMMessage. ### Terminology Here's some terminology you might want to know about when working inside VSCode: - An **Editor** is the thing that you type your code in. If you have 10 tabs open, that's just one editor! Editors contain tabs (or "models"). - A **Model** is an internal representation of a file's contents. It's shared between editors (for example, if you press `Cmd+\` to make a new editor, then the model of a file like `A.ts` is shared between them. Two editors, one model. That's how changes sync.). - Each model has a **URI** it represents, like `/Users/.../my_file.txt`. (A URI or "resource" is generally just a path). - The **Workbench** is the wrapper that contains all the editors, the terminal, the file system tree, etc. - Usually you use the `ITextModel` type for models and the `ICodeEditor` type for editors. There aren't that many other types.

Credit - https://code.visualstudio.com/docs/getstarted/userinterface

- VSCode is organized into "**Services**". A service is just a class that mounts a single time (in computer science theory this is called a "singleton"). You can register services with `registerSingleton` so that you can easily use them in any constructor with `@`. See _dummyContrib for an example we put together on how to register them. The registration is the same every time. - "**Actions**" are functions you register on VSCode so that either you or the user can call them later. They're also called "**Commands**". - You can run actions as a user by pressing Cmd+Shift+P (opens the command pallete), or you can run them internally by using the commandService to call them by ID. We use actions to register keybinding listeners like Cmd+L, Cmd+K, etc. The nice thing about actions is the user can change the keybindings. ### Internal LLM Message Pipeline Here's a picture of all the dependencies that are relevent between the time you first send a message through Void's sidebar, and the time a request is sent to your provider. Sending LLM messages from the main process avoids CSP issues with local providers and lets us use node_modules more easily.
**Notes:** `modelCapabilities` is an important file that must be updated when new models come out! ### Apply Void has two types of Apply: **Fast Apply** (uses Search/Replace, see below), and **Slow Apply** (rewrites whole file). When you click Apply and Fast Apply is enabled, we prompt the LLM to output Search/Replace block(s) like this: ``` <<<<<<< ORIGINAL // original code goes here ======= // replaced code goes here >>>>>>> UPDATED ``` This is what allows Void to quickly apply code even on 1000-line files. It's the same as asking the LLM to press Ctrl+F and enter in a search/replace query. ### Apply Inner Workings The `editCodeService` file runs Apply. The same exact code is also used when the LLM calls the Edit tool, and when you submit Cmd+K. Just different versions of Fast/Slow Apply mode. Here is some important terminology: - A **DiffZone** is a {startLine, endLine} region of text where we compute and show red/green areas, or **Diffs**. When any changes are made to a file, we loop through all the DiffAreas on that file and refresh its Diffs. - A **DiffArea** is a generalization that just tracks line numbers like a DiffZone. - The only type of DiffArea that can "stream" is a DiffZone. Each DiffZone has an llmCancelToken if it's streaming. How Apply works: - When you click Apply, we create a **DiffZone** over that the full file so that any changes that the LLM makes will show up in red/green. We then stream the change. - When an LLM calls Edit, it's really calling Apply. - When you submit Cmd+K, it's the same as Apply except we create a smaller DiffZone (not on the whole file). ### Writing Files Inner Workings When Void wants to change your code, it just writes to a text model. This means all you need to know to write to a file is its URI - you don't have to load it, save it, etc. There are some annoying background URI/model things to think about to get this to work, but we handled them all in `voidModelService`. ### Void Settings Inner Workings We have a service `voidSettingsService` that stores all your Void settings (providers, models, global Void settings, etc). Imagine this as an implicit dependency for any of the core Void services:
Here's a guide to some of the terminology we're using: - **FeatureName**: Autocomplete | Chat | CtrlK | Apply - **ModelSelection**: a {providerName, modelName} pair. - **ProviderName**: The name of a provider: `'ollama'`, `'openAI'`, etc. - **ModelName**: The name of a model (string type, eg `'gpt-4o'`). - **RefreshProvider**: a provider that we ping repeatedly to update the models list. - **ChatMode** = normal | gather | agent ### Approval State `editCodeService`'s data structures contain all the information about changes that the user needs to review. However, they don't store that information in a useful format. We wrote the following service to get a more useful derived state:
### Build process If you want to know how our build pipeline works, see our build repo [here](https://github.com/voideditor/void-builder). ## VSCode Codebase Guide For additional references, the Void team put together this list of links to get up and running with VSCode.
#### Links for Beginners - [VSCode UI guide](https://code.visualstudio.com/docs/getstarted/userinterface) - covers auxbar, panels, etc. - [UX guide](https://code.visualstudio.com/api/ux-guidelines/overview) - covers Containers, Views, Items, etc. #### Links for Contributors - [How VSCode's sourcecode is organized](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) - this explains where the entry point files are, what `browser/` and `common/` mean, etc. This is the most important read on this whole list! We recommend reading the whole thing. - [Built-in VSCode styles](https://code.visualstudio.com/api/references/theme-color) - CSS variables that are built into VSCode. Use `var(--vscode-{theme but replacing . with -})`. You can also see their [Webview theming guide](https://code.visualstudio.com/api/extension-guides/webview#theming-webview-content). #### Misc - [Every command](https://code.visualstudio.com/api/references/commands) built-in to VSCode - not used often, but here for reference. - Note: VSCode's repo is the source code for the Monaco editor! An "editor" is a Monaco editor, and it shares the code for ITextModel, etc. #### VSCode's Extension API Void is no longer an extension, so these links are no longer required, but they might be useful if we ever build an extension again. - [Files you need in an extension](https://code.visualstudio.com/api/get-started/extension-anatomy). - [An extension's `package.json` schema](https://code.visualstudio.com/api/references/extension-manifest). - ["Contributes" Guide](https://code.visualstudio.com/api/references/contribution-points) - the `"contributes"` part of `package.json` is how an extension mounts. - [The Full VSCode Extension API](https://code.visualstudio.com/api/references/vscode-api) - look on the right side for organization. The [bottom](https://code.visualstudio.com/api/references/vscode-api#api-patterns) of the page is easy to miss but is useful - cancellation tokens, events, disposables. - [Activation events](https://code.visualstudio.com/api/references/activation-events) you can define in `package.json` (not the most useful).
================================================ FILE: build/.cachesalt ================================================ 2024-12-11T00:28:56.838Z ================================================ FILE: build/.gitattributes ================================================ * text eol=lf *.exe binary *.dll binary ================================================ FILE: build/.gitignore ================================================ *.js.map ================================================ FILE: build/.moduleignore ================================================ # cleanup rules for node modules, .gitignore style # native node modules nan/** */node_modules/nan/** fsevents/binding.gyp fsevents/fsevents.cc fsevents/build/** fsevents/src/** fsevents/test/** !fsevents/**/*.node @vscode/spdlog/binding.gyp @vscode/spdlog/build/** @vscode/spdlog/deps/** @vscode/spdlog/src/** @vscode/spdlog/test/** @vscode/spdlog/*.yml !@vscode/spdlog/build/Release/*.node @vscode/deviceid/binding.gyp @vscode/deviceid/build/** @vscode/deviceid/deps/** @vscode/deviceid/src/** @vscode/deviceid/test/** @vscode/deviceid/*.yml !@vscode/deviceid/build/Release/*.node @vscode/sqlite3/binding.gyp @vscode/sqlite3/benchmark/** @vscode/sqlite3/cloudformation/** @vscode/sqlite3/deps/** @vscode/sqlite3/test/** @vscode/sqlite3/build/** @vscode/sqlite3/src/** !@vscode/sqlite3/build/Release/*.node @vscode/windows-mutex/binding.gyp @vscode/windows-mutex/build/** @vscode/windows-mutex/src/** !@vscode/windows-mutex/**/*.node @vscode/windows-process-tree/binding.gyp @vscode/windows-process-tree/build/** @vscode/windows-process-tree/src/** @vscode/windows-process-tree/tsconfig.json @vscode/windows-process-tree/tslint.json !@vscode/windows-process-tree/**/*.node @vscode/windows-registry/binding.gyp @vscode/windows-registry/src/** @vscode/windows-registry/build/** !@vscode/windows-registry/build/Release/*.node @vscode/tree-sitter-wasm/wasm/tree-sitter-*.wasm !@vscode/tree-sitter-wasm/wasm/tree-sitter-typescript.wasm !@vscode/tree-sitter-wasm/wasm/tree-sitter-regex.wasm !@vscode/tree-sitter-wasm/wasm/tree-sitter-ini.wasm !@vscode/tree-sitter-wasm/wasm/tree-sitter-css.wasm native-keymap/binding.gyp native-keymap/build/** native-keymap/src/** native-keymap/deps/** !native-keymap/build/Release/*.node native-is-elevated/binding.gyp native-is-elevated/build/** native-is-elevated/src/** native-is-elevated/deps/** !native-is-elevated/build/Release/*.node native-watchdog/binding.gyp native-watchdog/build/** native-watchdog/src/** !native-watchdog/build/Release/*.node @vscode/vsce-sign/** !@vscode/vsce-sign/src/main.d.ts !@vscode/vsce-sign/src/main.js !@vscode/vsce-sign/package.json !@vscode/vsce-sign/bin/** windows-foreground-love/binding.gyp windows-foreground-love/build/** windows-foreground-love/src/** !windows-foreground-love/**/*.node kerberos/binding.gyp kerberos/build/** kerberos/src/** kerberos/node_modules/** !kerberos/**/*.node node-pty/binding.gyp node-pty/build/** node-pty/src/** node-pty/lib/*.test.js node-pty/tools/** node-pty/deps/** node-pty/scripts/** node-pty/third_party/** !node-pty/build/Release/spawn-helper !node-pty/build/Release/*.exe !node-pty/build/Release/*.dll !node-pty/build/Release/*.node !node-pty/build/Release/conpty/conpty.dll !node-pty/build/Release/conpty/OpenConsole.exe @parcel/watcher/binding.gyp @parcel/watcher/build/** @parcel/watcher/prebuilds/** @parcel/watcher/src/** !@parcel/watcher/build/Release/*.node vsda/** !vsda/index.js !vsda/index.d.ts !vsda/package.json !vsda/build/Release/vsda.node !vsda/rust/web/** !vsda/rust/bundler/** @vscode/policy-watcher/build/** @vscode/policy-watcher/.husky/** @vscode/policy-watcher/src/** @vscode/policy-watcher/binding.gyp @vscode/policy-watcher/README.md @vscode/policy-watcher/index.d.ts !@vscode/policy-watcher/build/Release/vscode-policy-watcher.node @vscode/windows-ca-certs/**/* !@vscode/windows-ca-certs/package.json !@vscode/windows-ca-certs/**/*.node @vscode/node-addon-api/**/* node-addon-api/**/* prebuild-install/**/* # other node modules **/docs/** **/example/** **/examples/** **/test/** **/tests/** **/History.md **/CHANGELOG.md **/README.md **/readme.md **/readme.markdown **/CODE_OF_CONDUCT.md **/SUPPORT.md **/CONTRIBUTING.md **/*.ts # Exclude TS files that aren't needed by TS extension typescript/lib/tsc.js typescript/lib/typescriptServices.js typescript/lib/tsserverlibrary.js # We still need to include stdlib d.ts !typescript/lib/lib*.d.ts jschardet/index.js jschardet/src/** jschardet/dist/jschardet.js es6-promise/lib/** vscode-textmate/webpack.config.js zone.js/dist/** !zone.js/dist/zone-node.js # https://github.com/xtermjs/xterm.js/issues/3137 @xterm/xterm/src/** @xterm/xterm/tsconfig.all.json # https://github.com/xtermjs/xterm.js/issues/3138 @xterm/xterm-addon-*/src/** @xterm/xterm-addon-*/fixtures/** @xterm/xterm-addon-*/out/** @xterm/xterm-addon-*/out-test/** ================================================ FILE: build/.moduleignore.darwin ================================================ @vscode/windows-mutex/index.js @vscode/windows-mutex/**/*.node @vscode/windows-mutex/*.md @vscode/windows-mutex/package.json @vscode/windows-process-tree/lib/** @vscode/windows-process-tree/**/*.node @vscode/windows-process-tree/LICENSE @vscode/windows-process-tree/package.json @vscode/windows-process-tree/*.md @vscode/windows-registry/dist/** @vscode/windows-registry/**/*.node @vscode/windows-registry/*.md @vscode/windows-registry/*.txt @vscode/windows-registry/package.json !@vscode/windows-registry/dist/index.d.ts ================================================ FILE: build/.moduleignore.linux ================================================ @vscode/windows-mutex/index.js @vscode/windows-mutex/**/*.node @vscode/windows-mutex/*.md @vscode/windows-mutex/package.json @vscode/windows-process-tree/lib/** @vscode/windows-process-tree/**/*.node @vscode/windows-process-tree/LICENSE @vscode/windows-process-tree/package.json @vscode/windows-process-tree/*.md @vscode/windows-registry/dist/** @vscode/windows-registry/**/*.node @vscode/windows-registry/*.md @vscode/windows-registry/*.txt @vscode/windows-registry/package.json !@vscode/windows-registry/dist/index.d.ts ================================================ FILE: build/.moduleignore.win32 ================================================ ================================================ FILE: build/.npmrc ================================================ disturl="https://nodejs.org/dist" runtime="node" build_from_source="true" legacy-peer-deps="true" force_process_config="true" timeout=180000 ================================================ FILE: build/.webignore ================================================ # cleanup rules for web node modules, .gitignore style **/*.txt **/*.json **/*.md **/*.d.ts **/*.js.map **/LICENSE **/CONTRIBUTORS **/docs/** **/example/** **/examples/** jschardet/index.js jschardet/src/** jschardet/dist/jschardet.js vscode-textmate/webpack.config.js @xterm/xterm/src/** @xterm/addon-clipboard/src/** @xterm/addon-clipboard/out/** @xterm/addon-image/src/** @xterm/addon-image/out/** @xterm/addon-ligatures/src/** @xterm/addon-ligatures/out/** @xterm/addon-search/src/** @xterm/addon-search/out/** @xterm/addon-search/fixtures/** @xterm/addon-unicode11/src/** @xterm/addon-unicode11/out/** @xterm/addon-webgl/src/** @xterm/addon-webgl/out/** # This makes sure the model is included in the package !@vscode/vscode-languagedetection/model/** !@vscode/tree-sitter-wasm/wasm/** # Ensure only the required telemetry pieces are loaded in web to reduce bundle size @microsoft/1ds-core-js/** @microsoft/1ds-post-js/** @microsoft/applicationinsights-core-js/** @microsoft/applicationinsights-shims/** !@microsoft/1ds-core-js/dist/ms.core.min.js !@microsoft/1ds-core-js/bundle/ms.core.min.js !@microsoft/1ds-post-js/dist/ms.post.min.js !@microsoft/1ds-post-js/bundle/ms.post.min.js !@microsoft/applicationinsights-core-js/browser/applicationinsights-core-js.min.js !@microsoft/applicationinsights-shims/dist/umd/applicationinsights-shims.min.js vsda/** !vsda/rust/web/** ================================================ FILE: build/azure-pipelines/alpine/cli-build-alpine.yml ================================================ parameters: - name: VSCODE_BUILD_ALPINE type: boolean default: false - name: VSCODE_BUILD_ALPINE_ARM64 type: boolean default: false - name: VSCODE_QUALITY type: string - name: VSCODE_CHECK_ONLY type: boolean default: false steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml@self - script: | set -e npm ci workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies - task: Npm@1 displayName: Download openssl prebuilt inputs: command: custom customCommand: pack @vscode-internal/openssl-prebuilt@0.0.11 customRegistry: useFeed customFeed: "Monaco/openssl-prebuilt" workingDir: $(Build.ArtifactStagingDirectory) - script: | set -e mkdir $(Build.ArtifactStagingDirectory)/openssl tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt # inspired by: https://github.com/emk/rust-musl-builder/blob/main/Dockerfile - bash: | set -e sudo apt-get update sudo apt-get install -yq build-essential musl-dev musl-tools linux-libc-dev pkgconf xutils-dev lld sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++" || echo "link exists" displayName: Install musl build dependencies - template: ../cli/install-rust-posix.yml@self parameters: targets: - ${{ if eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true) }}: - aarch64-unknown-linux-musl - ${{ if eq(parameters.VSCODE_BUILD_ALPINE, true) }}: - x86_64-unknown-linux-musl - ${{ if eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_CLI_TARGET: aarch64-unknown-linux-musl VSCODE_CLI_ARTIFACT: vscode_cli_alpine_arm64_cli VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux-musl/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux-musl/include OPENSSL_STATIC: "1" - ${{ if eq(parameters.VSCODE_BUILD_ALPINE, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_CLI_TARGET: x86_64-unknown-linux-musl VSCODE_CLI_ARTIFACT: vscode_cli_alpine_x64_cli VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux-musl/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux-musl/include OPENSSL_STATIC: "1" - ${{ if not(parameters.VSCODE_CHECK_ONLY) }}: - ${{ if eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/vscode_cli_alpine_arm64_cli.tar.gz artifactName: vscode_cli_alpine_arm64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Alpine arm64 CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish vscode_cli_alpine_arm64_cli artifact - ${{ if eq(parameters.VSCODE_BUILD_ALPINE, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/vscode_cli_alpine_x64_cli.tar.gz artifactName: vscode_cli_alpine_x64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Alpine x64 CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish vscode_cli_alpine_x64_cli artifact ================================================ FILE: build/azure-pipelines/alpine/product-build-alpine.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - task: DownloadPipelineArtifact@2 inputs: artifact: Compilation path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js alpine $VSCODE_ARCH > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - task: Docker@1 inputs: azureSubscriptionEndpoint: vscode azureContainerRegistry: vscodehub.azurecr.io command: "Run an image" imageName: "vscode-linux-build-agent:alpine-$(VSCODE_ARCH)" containerCommand: uname displayName: "Pull image" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: sudo apt-get update && sudo apt-get install -y libkrb5-dev displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: npm_config_arch: $(NPM_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: node build/azure-pipelines/distro/mixin-npm displayName: Mixin distro node modules condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: ../common/install-builtin-extensions.yml@self - script: | set -e TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") # TODO@joaomoreno npm run gulp vscode-reh-$TARGET-min-ci (cd .. && mv vscode-reh-$TARGET vscode-server-$TARGET) # TODO@joaomoreno ARCHIVE_PATH=".build/linux/server/vscode-server-$TARGET.tar.gz" DIR_PATH="$(realpath ../vscode-server-$TARGET)" mkdir -p $(dirname $ARCHIVE_PATH) tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-$TARGET echo "##vso[task.setvariable variable=SERVER_DIR_PATH]$DIR_PATH" echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - script: | set -e TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") npm run gulp vscode-reh-web-$TARGET-min-ci (cd .. && mv vscode-reh-web-$TARGET vscode-server-$TARGET-web) # TODO@joaomoreno ARCHIVE_PATH=".build/linux/web/vscode-server-$TARGET-web.tar.gz" DIR_PATH="$(realpath ../vscode-server-$TARGET-web)" mkdir -p $(dirname $ARCHIVE_PATH) tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-$TARGET-web echo "##vso[task.setvariable variable=WEB_DIR_PATH]$DIR_PATH" echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) displayName: Generate artifact prefix - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SERVER_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_server_alpine_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(SERVER_DIR_PATH) sbomPackageName: "VS Code Alpine $(VSCODE_ARCH) Server" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish server archive condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_alpine_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(WEB_DIR_PATH) sbomPackageName: "VS Code Alpine $(VSCODE_ARCH) Web" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish web server archive condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) # same as above, keep legacy name - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SERVER_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_server_linux_alpine_archive-unsigned sbomEnabled: false displayName: Publish x64 server archive condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) # same as above, keep legacy name - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_linux_alpine_archive-unsigned sbomEnabled: false displayName: Publish x64 web server archive condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) ================================================ FILE: build/azure-pipelines/cli/cli-apply-patches.yml ================================================ steps: - template: ../distro/download-distro.yml@self - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - script: node .build/distro/cli-patches/index.js displayName: Apply distro patches ================================================ FILE: build/azure-pipelines/cli/cli-compile.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_CLI_TARGET type: string - name: VSCODE_CLI_ARTIFACT type: string - name: VSCODE_CLI_ENV type: object default: {} - name: VSCODE_CHECK_ONLY type: boolean default: false steps: - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - pwsh: Write-Host "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/product.json" displayName: Set product.json path - ${{ else }}: - pwsh: Write-Host "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/.build/distro/mixin/${{ parameters.VSCODE_QUALITY }}/product.json" displayName: Set product.json path - ${{ else }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: echo "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/product.json" displayName: Set product.json path - ${{ else }}: - script: echo "##vso[task.setvariable variable=VSCODE_CLI_PRODUCT_JSON]$(Build.SourcesDirectory)/.build/distro/mixin/${{ parameters.VSCODE_QUALITY }}/product.json" displayName: Set product.json path - ${{ if parameters.VSCODE_CHECK_ONLY }}: - script: cargo clippy --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code displayName: Lint ${{ parameters.VSCODE_CLI_TARGET }} workingDirectory: $(Build.SourcesDirectory)/cli env: CARGO_NET_GIT_FETCH_WITH_CLI: true ${{ each pair in parameters.VSCODE_CLI_ENV }}: ${{ pair.key }}: ${{ pair.value }} - ${{ else }}: - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-linux-') }}: - script: | set -e if [ -n "$SYSROOT_ARCH" ]; then export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots node -e '(async () => { const { getVSCodeSysroot } = require("../build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' if [ "$SYSROOT_ARCH" == "arm64" ]; then export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc" export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" export CC_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" export PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu/pkgconfig:$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/share/pkgconfig" export PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" export OBJDUMP="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/bin/objdump" elif [ "$SYSROOT_ARCH" == "amd64" ]; then export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc" export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -C link-arg=-L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu" export CC_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" export PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu/pkgconfig:$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/share/pkgconfig" export PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" export OBJDUMP="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/bin/objdump" elif [ "$SYSROOT_ARCH" == "armhf" ]; then export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc" export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" export CC_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc --sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" export PKG_CONFIG_LIBDIR_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-rpi-linux-gnueabihf/pkgconfig:$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/share/pkgconfig" export PKG_CONFIG_SYSROOT_DIR_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" export OBJDUMP="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/bin/objdump" fi fi cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code # verify glibc requirement if [ -n "$SYSROOT_ARCH" ]; then glibc_version="2.28" while IFS= read -r line; do if [[ $line == *"GLIBC_"* ]]; then version=$(echo "$line" | awk '{print $5}' | tr -d '()') version=${version#*_} if [[ $(printf "%s\n%s" "$version" "$glibc_version" | sort -V | tail -n1) == "$version" ]]; then glibc_version=$version fi fi done < <("$OBJDUMP" -T "$PWD/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code") if [[ "$glibc_version" != "2.28" ]]; then echo "Error: binary has dependency on GLIBC > 2.28, found $glibc_version" exit 1 fi fi displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }} workingDirectory: $(Build.SourcesDirectory)/cli env: CARGO_NET_GIT_FETCH_WITH_CLI: true VSCODE_CLI_COMMIT: $(Build.SourceVersion) GITHUB_TOKEN: "$(github-distro-mixin-password)" ${{ each pair in parameters.VSCODE_CLI_ENV }}: ${{ pair.key }}: ${{ pair.value }} - ${{ else }}: - script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }} workingDirectory: $(Build.SourcesDirectory)/cli env: CARGO_NET_GIT_FETCH_WITH_CLI: true VSCODE_CLI_COMMIT: $(Build.SourceVersion) ${{ each pair in parameters.VSCODE_CLI_ENV }}: ${{ pair.key }}: ${{ pair.value }} - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}: - task: PublishSymbols@2 inputs: IndexSources: false SymbolsFolder: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release SearchPattern: 'code.pdb' SymbolServerType: TeamServices SymbolsProduct: 'code' ArtifactServices.Symbol.AccountName: microsoft ArtifactServices.Symbol.PAT: $(System.AccessToken) ArtifactServices.Symbol.UseAAD: false displayName: Publish Symbols - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $AppProductJson = Get-Content -Raw -Path "$env:VSCODE_CLI_PRODUCT_JSON" | ConvertFrom-Json $env:VSCODE_CLI_APPLICATION_NAME = $AppProductJson.applicationName Write-Host "##vso[task.setvariable variable=VSCODE_CLI_APPLICATION_NAME]$env:VSCODE_CLI_APPLICATION_NAME" New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)/cli" Move-Item -Path $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code.exe -Destination "$(Build.ArtifactStagingDirectory)/cli/${env:VSCODE_CLI_APPLICATION_NAME}.exe" displayName: Stage CLI - task: ArchiveFiles@2 displayName: Archive CLI inputs: rootFolderOrFile: $(Build.ArtifactStagingDirectory)/cli/$(VSCODE_CLI_APPLICATION_NAME).exe includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.zip - ${{ else }}: - script: | set -e VSCODE_CLI_APPLICATION_NAME=$(node -p "require(\"$VSCODE_CLI_PRODUCT_JSON\").applicationName") echo "##vso[task.setvariable variable=VSCODE_CLI_APPLICATION_NAME]$VSCODE_CLI_APPLICATION_NAME" mkdir -p $(Build.ArtifactStagingDirectory)/cli mv $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code $(Build.ArtifactStagingDirectory)/cli/$VSCODE_CLI_APPLICATION_NAME displayName: Stage CLI - task: ArchiveFiles@2 displayName: Archive CLI inputs: rootFolderOrFile: $(Build.ArtifactStagingDirectory)/cli/$(VSCODE_CLI_APPLICATION_NAME) includeRootFolder: false ${{ if contains(parameters.VSCODE_CLI_TARGET, '-darwin') }}: archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.zip ${{ else }}: archiveType: tar tarCompression: gz archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.tar.gz ================================================ FILE: build/azure-pipelines/cli/cli-darwin-sign.yml ================================================ parameters: - name: VSCODE_CLI_ARTIFACTS type: object default: [] steps: - task: UseDotNet@2 inputs: version: 6.x - task: EsrpCodeSigning@5 inputs: UseMSIAuthentication: true ConnectedServiceName: vscode-esrp AppRegistrationClientId: $(ESRP_CLIENT_ID) AppRegistrationTenantId: $(ESRP_TENANT_ID) AuthAKVName: vscode-esrp AuthSignCertName: esrp-sign FolderPath: . Pattern: noop displayName: 'Install ESRP Tooling' - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: - task: DownloadPipelineArtifact@2 displayName: Download ${{ target }} inputs: artifact: ${{ target }} path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }} - task: ExtractFiles@1 displayName: Extract artifact inputs: archiveFilePatterns: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/*.zip destinationFolder: $(Build.ArtifactStagingDirectory)/sign/${{ target }} - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll sign-darwin $(Build.ArtifactStagingDirectory)/pkg "*.zip" env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll notarize-darwin $(Build.ArtifactStagingDirectory)/pkg "*.zip" env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Notarize - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: - script: | set -e ASSET_ID=$(echo "${{ target }}" | sed "s/unsigned_//") mv $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/${{ target }}.zip $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/$ASSET_ID.zip echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID" displayName: Set asset id variable - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/$(ASSET_ID).zip artifactName: $(ASSET_ID) sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/sign/${{ target }} sbomPackageName: "VS Code macOS ${{ target }} CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish signed artifact with ID $(ASSET_ID) ================================================ FILE: build/azure-pipelines/cli/cli-win32-sign.yml ================================================ parameters: - name: VSCODE_CLI_ARTIFACTS type: object default: [] steps: - task: UseDotNet@2 inputs: version: 6.x - task: EsrpCodeSigning@5 inputs: UseMSIAuthentication: true ConnectedServiceName: vscode-esrp AppRegistrationClientId: $(ESRP_CLIENT_ID) AppRegistrationTenantId: $(ESRP_TENANT_ID) AuthAKVName: vscode-esrp AuthSignCertName: esrp-sign FolderPath: . Pattern: noop displayName: 'Install ESRP Tooling' - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $EsrpCodeSigningTool = (gci -directory -filter EsrpCodeSigning_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName $Version = (gci -directory $EsrpCodeSigningTool | Select-Object -last 1).FullName echo "##vso[task.setvariable variable=EsrpCliDllPath]$Version\net6.0\esrpcli.dll" displayName: Find ESRP CLI - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: - task: DownloadPipelineArtifact@2 displayName: Download artifact inputs: artifact: ${{ target }} path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }} - task: ExtractFiles@1 displayName: Extract artifact inputs: archiveFilePatterns: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/*.zip destinationFolder: $(Build.ArtifactStagingDirectory)/sign/${{ target }} - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows $(Build.ArtifactStagingDirectory)/sign "*.exe" env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: - powershell: | $ASSET_ID = "${{ target }}".replace("unsigned_", ""); echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID" displayName: Set asset id variable - task: ArchiveFiles@2 displayName: Archive signed files inputs: rootFolderOrFile: $(Build.ArtifactStagingDirectory)/sign/${{ target }} includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(ASSET_ID).zip - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/$(ASSET_ID).zip artifactName: $(ASSET_ID) sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/sign/${{ target }} sbomPackageName: "VS Code Windows ${{ target }} CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish signed artifact with ID $(ASSET_ID) ================================================ FILE: build/azure-pipelines/cli/install-rust-posix.yml ================================================ parameters: - name: channel type: string default: 1.85 - name: targets default: [] type: object # Todo: use 1ES pipeline once extension is installed in ADO steps: - task: RustInstaller@1 inputs: rustVersion: ms-${{ parameters.channel }} cratesIoFeedOverride: $(CARGO_REGISTRY) additionalTargets: ${{ join(' ', parameters.targets) }} toolchainFeed: https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/nuget/v3/index.json default: true addToPath: true displayName: Install MSFT Rust condition: and(succeeded(), ne(variables['CARGO_REGISTRY'], 'none')) - script: | set -e curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal --default-toolchain $RUSTUP_TOOLCHAIN echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" env: RUSTUP_TOOLCHAIN: ${{ parameters.channel }} displayName: Install OSS Rust condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - script: | set -e rustup default $RUSTUP_TOOLCHAIN rustup update $RUSTUP_TOOLCHAIN rustup component add clippy env: RUSTUP_TOOLCHAIN: ${{ parameters.channel }} displayName: "Set Rust version" condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - ${{ each target in parameters.targets }}: - script: rustup target add ${{ target }} displayName: "Adding Rust target '${{ target }}'" condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - script: | set -e rustc --version cargo --version displayName: "Check Rust versions" ================================================ FILE: build/azure-pipelines/cli/install-rust-win32.yml ================================================ parameters: - name: channel type: string default: 1.85 - name: targets default: [] type: object # Todo: use 1ES pipeline once extension is installed in ADO steps: - task: RustInstaller@1 inputs: rustVersion: ms-${{ parameters.channel }} cratesIoFeedOverride: $(CARGO_REGISTRY) additionalTargets: ${{ join(' ', parameters.targets) }} toolchainFeed: https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/nuget/v3/index.json default: true addToPath: true displayName: Install MSFT Rust condition: and(succeeded(), ne(variables['CARGO_REGISTRY'], 'none')) - powershell: | . build/azure-pipelines/win32/exec.ps1 Invoke-WebRequest -Uri "https://win.rustup.rs" -Outfile $(Build.ArtifactStagingDirectory)/rustup-init.exe exec { $(Build.ArtifactStagingDirectory)/rustup-init.exe -y --profile minimal --default-toolchain $env:RUSTUP_TOOLCHAIN --default-host x86_64-pc-windows-msvc } echo "##vso[task.prependpath]$env:USERPROFILE\.cargo\bin" env: RUSTUP_TOOLCHAIN: ${{ parameters.channel }} displayName: Install OSS Rust condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - powershell: | . build/azure-pipelines/win32/exec.ps1 exec { rustup default $RUSTUP_TOOLCHAIN } exec { rustup update $RUSTUP_TOOLCHAIN } env: RUSTUP_TOOLCHAIN: ${{ parameters.channel }} displayName: "Set Rust version" condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - ${{ each target in parameters.targets }}: - script: rustup target add ${{ target }} displayName: "Adding Rust target '${{ target }}'" condition: and(succeeded(), eq(variables['CARGO_REGISTRY'], 'none')) - powershell: | . build/azure-pipelines/win32/exec.ps1 exec { rustc --version } exec { cargo --version } displayName: "Check Rust versions" ================================================ FILE: build/azure-pipelines/cli/test.yml ================================================ steps: - template: ./install-rust-posix.yml@self - script: cargo clippy -- -D warnings workingDirectory: cli displayName: Clippy lint - script: cargo test workingDirectory: cli displayName: Run unit tests ================================================ FILE: build/azure-pipelines/common/computeBuiltInDepsCacheKey.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const crypto_1 = __importDefault(require("crypto")); const productjson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../../../product.json'), 'utf8')); const shasum = crypto_1.default.createHash('sha256'); for (const ext of productjson.builtInExtensions) { shasum.update(`${ext.name}@${ext.version}`); } process.stdout.write(shasum.digest('hex')); //# sourceMappingURL=computeBuiltInDepsCacheKey.js.map ================================================ FILE: build/azure-pipelines/common/computeBuiltInDepsCacheKey.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../../product.json'), 'utf8')); const shasum = crypto.createHash('sha256'); for (const ext of productjson.builtInExtensions) { shasum.update(`${ext.name}@${ext.version}`); } process.stdout.write(shasum.digest('hex')); ================================================ FILE: build/azure-pipelines/common/computeNodeModulesCacheKey.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const crypto_1 = __importDefault(require("crypto")); const { dirs } = require('../../npm/dirs'); const ROOT = path_1.default.join(__dirname, '../../../'); const shasum = crypto_1.default.createHash('sha256'); shasum.update(fs_1.default.readFileSync(path_1.default.join(ROOT, 'build/.cachesalt'))); shasum.update(fs_1.default.readFileSync(path_1.default.join(ROOT, '.npmrc'))); shasum.update(fs_1.default.readFileSync(path_1.default.join(ROOT, 'build', '.npmrc'))); shasum.update(fs_1.default.readFileSync(path_1.default.join(ROOT, 'remote', '.npmrc'))); // Add `package.json` and `package-lock.json` files for (const dir of dirs) { const packageJsonPath = path_1.default.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { dependencies: packageJson.dependencies, devDependencies: packageJson.devDependencies, optionalDependencies: packageJson.optionalDependencies, resolutions: packageJson.resolutions, distro: packageJson.distro }; shasum.update(JSON.stringify(relevantPackageJsonSections)); const packageLockPath = path_1.default.join(ROOT, dir, 'package-lock.json'); shasum.update(fs_1.default.readFileSync(packageLockPath)); } // Add any other command line arguments for (let i = 2; i < process.argv.length; i++) { shasum.update(process.argv[i]); } process.stdout.write(shasum.digest('hex')); //# sourceMappingURL=computeNodeModulesCacheKey.js.map ================================================ FILE: build/azure-pipelines/common/computeNodeModulesCacheKey.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; const { dirs } = require('../../npm/dirs'); const ROOT = path.join(__dirname, '../../../'); const shasum = crypto.createHash('sha256'); shasum.update(fs.readFileSync(path.join(ROOT, 'build/.cachesalt'))); shasum.update(fs.readFileSync(path.join(ROOT, '.npmrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'build', '.npmrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'remote', '.npmrc'))); // Add `package.json` and `package-lock.json` files for (const dir of dirs) { const packageJsonPath = path.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { dependencies: packageJson.dependencies, devDependencies: packageJson.devDependencies, optionalDependencies: packageJson.optionalDependencies, resolutions: packageJson.resolutions, distro: packageJson.distro }; shasum.update(JSON.stringify(relevantPackageJsonSections)); const packageLockPath = path.join(ROOT, dir, 'package-lock.json'); shasum.update(fs.readFileSync(packageLockPath)); } // Add any other command line arguments for (let i = 2; i < process.argv.length; i++) { shasum.update(process.argv[i]); } process.stdout.write(shasum.digest('hex')); ================================================ FILE: build/azure-pipelines/common/createBuild.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const identity_1 = require("@azure/identity"); const cosmos_1 = require("@azure/cosmos"); const retry_1 = require("./retry"); if (process.argv.length !== 3) { console.error('Usage: node createBuild.js VERSION'); process.exit(-1); } function getEnv(name) { const result = process.env[name]; if (typeof result === 'undefined') { throw new Error('Missing env: ' + name); } return result; } async function main() { const [, , _version] = process.argv; const quality = getEnv('VSCODE_QUALITY'); const commit = getEnv('BUILD_SOURCEVERSION'); const queuedBy = getEnv('BUILD_QUEUEDBY'); const sourceBranch = getEnv('BUILD_SOURCEBRANCH'); const version = _version + (quality === 'stable' ? '' : `-${quality}`); console.log('Creating build...'); console.log('Quality:', quality); console.log('Version:', version); console.log('Commit:', commit); const build = { id: commit, timestamp: (new Date()).getTime(), version, isReleased: false, private: process.env['VSCODE_PRIVATE_BUILD']?.toLowerCase() === 'true', sourceBranch, queuedBy, assets: [], updates: {} }; const aadCredentials = new identity_1.ClientAssertionCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], () => Promise.resolve(process.env['AZURE_ID_TOKEN'])); const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], aadCredentials }); const scripts = client.database('builds').container(quality).scripts; await (0, retry_1.retry)(() => scripts.storedProcedure('createBuild').execute('', [{ ...build, _partitionKey: '' }])); } main().then(() => { console.log('Build successfully created'); process.exit(0); }, err => { console.error(err); process.exit(1); }); //# sourceMappingURL=createBuild.js.map ================================================ FILE: build/azure-pipelines/common/createBuild.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ClientAssertionCredential } from '@azure/identity'; import { CosmosClient } from '@azure/cosmos'; import { retry } from './retry'; if (process.argv.length !== 3) { console.error('Usage: node createBuild.js VERSION'); process.exit(-1); } function getEnv(name: string): string { const result = process.env[name]; if (typeof result === 'undefined') { throw new Error('Missing env: ' + name); } return result; } async function main(): Promise { const [, , _version] = process.argv; const quality = getEnv('VSCODE_QUALITY'); const commit = getEnv('BUILD_SOURCEVERSION'); const queuedBy = getEnv('BUILD_QUEUEDBY'); const sourceBranch = getEnv('BUILD_SOURCEBRANCH'); const version = _version + (quality === 'stable' ? '' : `-${quality}`); console.log('Creating build...'); console.log('Quality:', quality); console.log('Version:', version); console.log('Commit:', commit); const build = { id: commit, timestamp: (new Date()).getTime(), version, isReleased: false, private: process.env['VSCODE_PRIVATE_BUILD']?.toLowerCase() === 'true', sourceBranch, queuedBy, assets: [], updates: {} }; const aadCredentials = new ClientAssertionCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, () => Promise.resolve(process.env['AZURE_ID_TOKEN']!)); const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, aadCredentials }); const scripts = client.database('builds').container(quality).scripts; await retry(() => scripts.storedProcedure('createBuild').execute('', [{ ...build, _partitionKey: '' }])); } main().then(() => { console.log('Build successfully created'); process.exit(0); }, err => { console.error(err); process.exit(1); }); ================================================ FILE: build/azure-pipelines/common/extract-telemetry.sh ================================================ #!/usr/bin/env bash set -e cd $BUILD_STAGINGDIRECTORY mkdir extraction cd extraction git clone --depth 1 https://github.com/microsoft/vscode-extension-telemetry.git git clone --depth 1 https://github.com/microsoft/vscode-chrome-debug-core.git git clone --depth 1 https://github.com/microsoft/vscode-node-debug2.git git clone --depth 1 https://github.com/microsoft/vscode-node-debug.git git clone --depth 1 https://github.com/microsoft/vscode-html-languageservice.git git clone --depth 1 https://github.com/microsoft/vscode-json-languageservice.git node $BUILD_SOURCESDIRECTORY/node_modules/.bin/vscode-telemetry-extractor --sourceDir $BUILD_SOURCESDIRECTORY --excludedDir $BUILD_SOURCESDIRECTORY/extensions --outputDir . --applyEndpoints node $BUILD_SOURCESDIRECTORY/node_modules/.bin/vscode-telemetry-extractor --config $BUILD_SOURCESDIRECTORY/build/azure-pipelines/common/telemetry-config.json -o . mkdir -p $BUILD_SOURCESDIRECTORY/.build/telemetry mv declarations-resolved.json $BUILD_SOURCESDIRECTORY/.build/telemetry/telemetry-core.json mv config-resolved.json $BUILD_SOURCESDIRECTORY/.build/telemetry/telemetry-extensions.json cd .. rm -rf extraction ================================================ FILE: build/azure-pipelines/common/getPublishAuthTokens.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.getAccessToken = getAccessToken; const msal_node_1 = require("@azure/msal-node"); function e(name) { const result = process.env[name]; if (typeof result !== 'string') { throw new Error(`Missing env: ${name}`); } return result; } async function getAccessToken(endpoint, tenantId, clientId, idToken) { const app = new msal_node_1.ConfidentialClientApplication({ auth: { clientId, authority: `https://login.microsoftonline.com/${tenantId}`, clientAssertion: idToken } }); const result = await app.acquireTokenByClientCredential({ scopes: [`${endpoint}.default`] }); if (!result) { throw new Error('Failed to get access token'); } return { token: result.accessToken, expiresOnTimestamp: result.expiresOn.getTime(), refreshAfterTimestamp: result.refreshOn?.getTime() }; } async function main() { const cosmosDBAccessToken = await getAccessToken(e('AZURE_DOCUMENTDB_ENDPOINT'), e('AZURE_TENANT_ID'), e('AZURE_CLIENT_ID'), e('AZURE_ID_TOKEN')); const blobServiceAccessToken = await getAccessToken(`https://${e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')}.blob.core.windows.net/`, process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_ID_TOKEN']); console.log(JSON.stringify({ cosmosDBAccessToken, blobServiceAccessToken })); } if (require.main === module) { main().then(() => { process.exit(0); }, err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=getPublishAuthTokens.js.map ================================================ FILE: build/azure-pipelines/common/getPublishAuthTokens.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { AccessToken } from '@azure/core-auth'; import { ConfidentialClientApplication } from '@azure/msal-node'; function e(name: string): string { const result = process.env[name]; if (typeof result !== 'string') { throw new Error(`Missing env: ${name}`); } return result; } export async function getAccessToken(endpoint: string, tenantId: string, clientId: string, idToken: string): Promise { const app = new ConfidentialClientApplication({ auth: { clientId, authority: `https://login.microsoftonline.com/${tenantId}`, clientAssertion: idToken } }); const result = await app.acquireTokenByClientCredential({ scopes: [`${endpoint}.default`] }); if (!result) { throw new Error('Failed to get access token'); } return { token: result.accessToken, expiresOnTimestamp: result.expiresOn!.getTime(), refreshAfterTimestamp: result.refreshOn?.getTime() }; } async function main() { const cosmosDBAccessToken = await getAccessToken(e('AZURE_DOCUMENTDB_ENDPOINT')!, e('AZURE_TENANT_ID')!, e('AZURE_CLIENT_ID')!, e('AZURE_ID_TOKEN')!); const blobServiceAccessToken = await getAccessToken(`https://${e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')}.blob.core.windows.net/`, process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_ID_TOKEN']!); console.log(JSON.stringify({ cosmosDBAccessToken, blobServiceAccessToken })); } if (require.main === module) { main().then(() => { process.exit(0); }, err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/azure-pipelines/common/install-builtin-extensions.yml ================================================ steps: - pwsh: mkdir .build -ea 0 condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Create .build folder - script: mkdir -p .build condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) displayName: Create .build folder - script: node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare built-in extensions cache key - task: Cache@2 inputs: key: '"builtin-extensions" | .build/builtindepshash' path: .build/builtInExtensions cacheHitVar: BUILTIN_EXTENSIONS_RESTORED displayName: Restore built-in extensions cache - script: node build/lib/builtInExtensions.js env: GITHUB_TOKEN: "$(github-distro-mixin-password)" condition: and(succeeded(), ne(variables.BUILTIN_EXTENSIONS_RESTORED, 'true')) displayName: Download built-in extensions ================================================ FILE: build/azure-pipelines/common/installPlaywright.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ process.env.DEBUG = 'pw:install'; // enable logging for this (https://github.com/microsoft/playwright/issues/17394) const { installDefaultBrowsersForNpmInstall } = require('playwright-core/lib/server'); async function install() { await installDefaultBrowsersForNpmInstall(); } install(); //# sourceMappingURL=installPlaywright.js.map ================================================ FILE: build/azure-pipelines/common/listNodeModules.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); if (process.argv.length !== 3) { console.error('Usage: node listNodeModules.js OUTPUT_FILE'); process.exit(-1); } const ROOT = path_1.default.join(__dirname, '../../../'); function findNodeModulesFiles(location, inNodeModules, result) { const entries = fs_1.default.readdirSync(path_1.default.join(ROOT, location)); for (const entry of entries) { const entryPath = `${location}/${entry}`; if (/(^\/out)|(^\/src$)|(^\/.git$)|(^\/.build$)/.test(entryPath)) { continue; } let stat; try { stat = fs_1.default.statSync(path_1.default.join(ROOT, entryPath)); } catch (err) { continue; } if (stat.isDirectory()) { findNodeModulesFiles(entryPath, inNodeModules || (entry === 'node_modules'), result); } else { if (inNodeModules) { result.push(entryPath.substr(1)); } } } } const result = []; findNodeModulesFiles('', false, result); fs_1.default.writeFileSync(process.argv[2], result.join('\n') + '\n'); //# sourceMappingURL=listNodeModules.js.map ================================================ FILE: build/azure-pipelines/common/listNodeModules.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; if (process.argv.length !== 3) { console.error('Usage: node listNodeModules.js OUTPUT_FILE'); process.exit(-1); } const ROOT = path.join(__dirname, '../../../'); function findNodeModulesFiles(location: string, inNodeModules: boolean, result: string[]) { const entries = fs.readdirSync(path.join(ROOT, location)); for (const entry of entries) { const entryPath = `${location}/${entry}`; if (/(^\/out)|(^\/src$)|(^\/.git$)|(^\/.build$)/.test(entryPath)) { continue; } let stat: fs.Stats; try { stat = fs.statSync(path.join(ROOT, entryPath)); } catch (err) { continue; } if (stat.isDirectory()) { findNodeModulesFiles(entryPath, inNodeModules || (entry === 'node_modules'), result); } else { if (inNodeModules) { result.push(entryPath.substr(1)); } } } } const result: string[] = []; findNodeModulesFiles('', false, result); fs.writeFileSync(process.argv[2], result.join('\n') + '\n'); ================================================ FILE: build/azure-pipelines/common/publish.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const stream_1 = require("stream"); const promises_1 = require("node:stream/promises"); const yauzl_1 = __importDefault(require("yauzl")); const crypto_1 = __importDefault(require("crypto")); const retry_1 = require("./retry"); const cosmos_1 = require("@azure/cosmos"); const child_process_1 = __importDefault(require("child_process")); const os_1 = __importDefault(require("os")); const node_worker_threads_1 = require("node:worker_threads"); const msal_node_1 = require("@azure/msal-node"); const storage_blob_1 = require("@azure/storage-blob"); const jws_1 = __importDefault(require("jws")); const node_timers_1 = require("node:timers"); function e(name) { const result = process.env[name]; if (typeof result !== 'string') { throw new Error(`Missing env: ${name}`); } return result; } function hashStream(hashName, stream) { return new Promise((c, e) => { const shasum = crypto_1.default.createHash(hashName); stream .on('data', shasum.update.bind(shasum)) .on('error', e) .on('close', () => c(shasum.digest())); }); } var StatusCode; (function (StatusCode) { StatusCode["Pass"] = "pass"; StatusCode["Aborted"] = "aborted"; StatusCode["Inprogress"] = "inprogress"; StatusCode["FailCanRetry"] = "failCanRetry"; StatusCode["FailDoNotRetry"] = "failDoNotRetry"; StatusCode["PendingAnalysis"] = "pendingAnalysis"; StatusCode["Cancelled"] = "cancelled"; })(StatusCode || (StatusCode = {})); function getCertificateBuffer(input) { return Buffer.from(input.replace(/-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----|\n/g, ''), 'base64'); } function getThumbprint(input, algorithm) { const buffer = getCertificateBuffer(input); return crypto_1.default.createHash(algorithm).update(buffer).digest(); } function getKeyFromPFX(pfx) { const pfxCertificatePath = path_1.default.join(os_1.default.tmpdir(), 'cert.pfx'); const pemKeyPath = path_1.default.join(os_1.default.tmpdir(), 'key.pem'); try { const pfxCertificate = Buffer.from(pfx, 'base64'); fs_1.default.writeFileSync(pfxCertificatePath, pfxCertificate); child_process_1.default.execSync(`openssl pkcs12 -in "${pfxCertificatePath}" -nocerts -nodes -out "${pemKeyPath}" -passin pass:`); const raw = fs_1.default.readFileSync(pemKeyPath, 'utf-8'); const result = raw.match(/-----BEGIN PRIVATE KEY-----[\s\S]+?-----END PRIVATE KEY-----/g)[0]; return result; } finally { fs_1.default.rmSync(pfxCertificatePath, { force: true }); fs_1.default.rmSync(pemKeyPath, { force: true }); } } function getCertificatesFromPFX(pfx) { const pfxCertificatePath = path_1.default.join(os_1.default.tmpdir(), 'cert.pfx'); const pemCertificatePath = path_1.default.join(os_1.default.tmpdir(), 'cert.pem'); try { const pfxCertificate = Buffer.from(pfx, 'base64'); fs_1.default.writeFileSync(pfxCertificatePath, pfxCertificate); child_process_1.default.execSync(`openssl pkcs12 -in "${pfxCertificatePath}" -nokeys -out "${pemCertificatePath}" -passin pass:`); const raw = fs_1.default.readFileSync(pemCertificatePath, 'utf-8'); const matches = raw.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g); return matches ? matches.reverse() : []; } finally { fs_1.default.rmSync(pfxCertificatePath, { force: true }); fs_1.default.rmSync(pemCertificatePath, { force: true }); } } class ESRPReleaseService { log; clientId; accessToken; requestSigningCertificates; requestSigningKey; containerClient; stagingSasToken; static async create(log, tenantId, clientId, authCertificatePfx, requestSigningCertificatePfx, containerClient, stagingSasToken) { const authKey = getKeyFromPFX(authCertificatePfx); const authCertificate = getCertificatesFromPFX(authCertificatePfx)[0]; const requestSigningKey = getKeyFromPFX(requestSigningCertificatePfx); const requestSigningCertificates = getCertificatesFromPFX(requestSigningCertificatePfx); const app = new msal_node_1.ConfidentialClientApplication({ auth: { clientId, authority: `https://login.microsoftonline.com/${tenantId}`, clientCertificate: { thumbprintSha256: getThumbprint(authCertificate, 'sha256').toString('hex'), privateKey: authKey, x5c: authCertificate } } }); const response = await app.acquireTokenByClientCredential({ scopes: ['https://api.esrp.microsoft.com/.default'] }); return new ESRPReleaseService(log, clientId, response.accessToken, requestSigningCertificates, requestSigningKey, containerClient, stagingSasToken); } static API_URL = 'https://api.esrp.microsoft.com/api/v3/releaseservices/clients/'; constructor(log, clientId, accessToken, requestSigningCertificates, requestSigningKey, containerClient, stagingSasToken) { this.log = log; this.clientId = clientId; this.accessToken = accessToken; this.requestSigningCertificates = requestSigningCertificates; this.requestSigningKey = requestSigningKey; this.containerClient = containerClient; this.stagingSasToken = stagingSasToken; } async createRelease(version, filePath, friendlyFileName) { const correlationId = crypto_1.default.randomUUID(); const blobClient = this.containerClient.getBlockBlobClient(correlationId); this.log(`Uploading ${filePath} to ${blobClient.url}`); await blobClient.uploadFile(filePath); this.log('Uploaded blob successfully'); try { this.log(`Submitting release for ${version}: ${filePath}`); const submitReleaseResult = await this.submitRelease(version, filePath, friendlyFileName, correlationId, blobClient); this.log(`Successfully submitted release ${submitReleaseResult.operationId}. Polling for completion...`); // Poll every 5 seconds, wait 60 minutes max -> poll 60/5*60=720 times for (let i = 0; i < 720; i++) { await new Promise(c => setTimeout(c, 5000)); const releaseStatus = await this.getReleaseStatus(submitReleaseResult.operationId); if (releaseStatus.status === 'pass') { break; } else if (releaseStatus.status === 'aborted') { this.log(JSON.stringify(releaseStatus)); throw new Error(`Release was aborted`); } else if (releaseStatus.status !== 'inprogress') { this.log(JSON.stringify(releaseStatus)); throw new Error(`Unknown error when polling for release`); } } const releaseDetails = await this.getReleaseDetails(submitReleaseResult.operationId); if (releaseDetails.status !== 'pass') { throw new Error(`Timed out waiting for release: ${JSON.stringify(releaseDetails)}`); } this.log('Successfully created release:', releaseDetails.files[0].fileDownloadDetails[0].downloadUrl); return releaseDetails.files[0].fileDownloadDetails[0].downloadUrl; } finally { this.log(`Deleting blob ${blobClient.url}`); await blobClient.delete(); this.log('Deleted blob successfully'); } } async submitRelease(version, filePath, friendlyFileName, correlationId, blobClient) { const size = fs_1.default.statSync(filePath).size; const hash = await hashStream('sha256', fs_1.default.createReadStream(filePath)); const blobUrl = `${blobClient.url}?${this.stagingSasToken}`; const message = { customerCorrelationId: correlationId, esrpCorrelationId: correlationId, driEmail: ['joao.moreno@microsoft.com'], createdBy: { userPrincipalName: 'jomo@microsoft.com' }, owners: [{ owner: { userPrincipalName: 'jomo@microsoft.com' } }], approvers: [{ approver: { userPrincipalName: 'jomo@microsoft.com' }, isAutoApproved: true, isMandatory: false }], releaseInfo: { title: 'VS Code', properties: { 'ReleaseContentType': 'InstallPackage' }, minimumNumberOfApprovers: 1 }, productInfo: { name: 'VS Code', version, description: 'VS Code' }, accessPermissionsInfo: { mainPublisher: 'VSCode', channelDownloadEntityDetails: { AllDownloadEntities: ['VSCode'] } }, routingInfo: { intent: 'filedownloadlinkgeneration' }, files: [{ name: path_1.default.basename(filePath), friendlyFileName, tenantFileLocation: blobUrl, tenantFileLocationType: 'AzureBlob', sourceLocation: { type: 'azureBlob', blobUrl }, hashType: 'sha256', hash: Array.from(hash), sizeInBytes: size }] }; message.jwsToken = await this.generateJwsToken(message); const res = await fetch(`${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.accessToken}` }, body: JSON.stringify(message) }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to submit release: ${res.statusText}\n${text}`); } return await res.json(); } async getReleaseStatus(releaseId) { const url = `${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations/grs/${releaseId}`; const res = await fetch(url, { headers: { 'Authorization': `Bearer ${this.accessToken}` } }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to get release status: ${res.statusText}\n${text}`); } return await res.json(); } async getReleaseDetails(releaseId) { const url = `${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations/grd/${releaseId}`; const res = await fetch(url, { headers: { 'Authorization': `Bearer ${this.accessToken}` } }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to get release status: ${res.statusText}\n${text}`); } return await res.json(); } async generateJwsToken(message) { return jws_1.default.sign({ header: { alg: 'RS256', crit: ['exp', 'x5t'], // Release service uses ticks, not seconds :roll_eyes: (https://stackoverflow.com/a/7968483) exp: ((Date.now() + (6 * 60 * 1000)) * 10000) + 621355968000000000, // Release service uses hex format, not base64url :roll_eyes: x5t: getThumbprint(this.requestSigningCertificates[0], 'sha1').toString('hex'), // Release service uses a '.' separated string, not an array of strings :roll_eyes: x5c: this.requestSigningCertificates.map(c => getCertificateBuffer(c).toString('base64url')).join('.'), }, payload: message, privateKey: this.requestSigningKey, }); } } class State { statePath; set = new Set(); constructor() { const pipelineWorkspacePath = e('PIPELINE_WORKSPACE'); const previousState = fs_1.default.readdirSync(pipelineWorkspacePath) .map(name => /^artifacts_processed_(\d+)$/.exec(name)) .filter((match) => !!match) .map(match => ({ name: match[0], attempt: Number(match[1]) })) .sort((a, b) => b.attempt - a.attempt)[0]; if (previousState) { const previousStatePath = path_1.default.join(pipelineWorkspacePath, previousState.name, previousState.name + '.txt'); fs_1.default.readFileSync(previousStatePath, 'utf8').split(/\n/).filter(name => !!name).forEach(name => this.set.add(name)); } const stageAttempt = e('SYSTEM_STAGEATTEMPT'); this.statePath = path_1.default.join(pipelineWorkspacePath, `artifacts_processed_${stageAttempt}`, `artifacts_processed_${stageAttempt}.txt`); fs_1.default.mkdirSync(path_1.default.dirname(this.statePath), { recursive: true }); fs_1.default.writeFileSync(this.statePath, [...this.set.values()].map(name => `${name}\n`).join('')); } get size() { return this.set.size; } has(name) { return this.set.has(name); } add(name) { this.set.add(name); fs_1.default.appendFileSync(this.statePath, `${name}\n`); } [Symbol.iterator]() { return this.set[Symbol.iterator](); } } const azdoFetchOptions = { headers: { // Pretend we're a web browser to avoid download rate limits 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Referer': 'https://dev.azure.com', Authorization: `Bearer ${e('SYSTEM_ACCESSTOKEN')}` } }; async function requestAZDOAPI(path) { const abortController = new AbortController(); const timeout = setTimeout(() => abortController.abort(), 2 * 60 * 1000); try { const res = await fetch(`${e('BUILDS_API_URL')}${path}?api-version=6.0`, { ...azdoFetchOptions, signal: abortController.signal }); if (!res.ok) { throw new Error(`Unexpected status code: ${res.status}`); } return await res.json(); } finally { clearTimeout(timeout); } } async function getPipelineArtifacts() { const result = await requestAZDOAPI('artifacts'); return result.value.filter(a => /^vscode_/.test(a.name) && !/sbom$/.test(a.name)); } async function getPipelineTimeline() { return await requestAZDOAPI('timeline'); } async function downloadArtifact(artifact, downloadPath) { const abortController = new AbortController(); const timeout = setTimeout(() => abortController.abort(), 4 * 60 * 1000); try { const res = await fetch(artifact.resource.downloadUrl, { ...azdoFetchOptions, signal: abortController.signal }); if (!res.ok) { throw new Error(`Unexpected status code: ${res.status}`); } await (0, promises_1.pipeline)(stream_1.Readable.fromWeb(res.body), fs_1.default.createWriteStream(downloadPath)); } finally { clearTimeout(timeout); } } async function unzip(packagePath, outputPath) { return new Promise((resolve, reject) => { yauzl_1.default.open(packagePath, { lazyEntries: true, autoClose: true }, (err, zipfile) => { if (err) { return reject(err); } const result = []; zipfile.on('entry', entry => { if (/\/$/.test(entry.fileName)) { zipfile.readEntry(); } else { zipfile.openReadStream(entry, (err, istream) => { if (err) { return reject(err); } const filePath = path_1.default.join(outputPath, entry.fileName); fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true }); const ostream = fs_1.default.createWriteStream(filePath); ostream.on('finish', () => { result.push(filePath); zipfile.readEntry(); }); istream?.on('error', err => reject(err)); istream.pipe(ostream); }); } }); zipfile.on('close', () => resolve(result)); zipfile.readEntry(); }); }); } // Contains all of the logic for mapping details to our actual product names in CosmosDB function getPlatform(product, os, arch, type) { switch (os) { case 'win32': switch (product) { case 'client': { switch (type) { case 'archive': return `win32-${arch}-archive`; case 'setup': return `win32-${arch}`; case 'user-setup': return `win32-${arch}-user`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } } case 'server': return `server-win32-${arch}`; case 'web': return `server-win32-${arch}-web`; case 'cli': return `cli-win32-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'alpine': switch (product) { case 'server': return `server-alpine-${arch}`; case 'web': return `server-alpine-${arch}-web`; case 'cli': return `cli-alpine-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'linux': switch (type) { case 'snap': return `linux-snap-${arch}`; case 'archive-unsigned': switch (product) { case 'client': return `linux-${arch}`; case 'server': return `server-linux-${arch}`; case 'web': if (arch === 'standalone') { return 'web-standalone'; } return `server-linux-${arch}-web`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'deb-package': return `linux-deb-${arch}`; case 'rpm-package': return `linux-rpm-${arch}`; case 'cli': return `cli-linux-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'darwin': switch (product) { case 'client': if (arch === 'x64') { return 'darwin'; } return `darwin-${arch}`; case 'server': if (arch === 'x64') { return 'server-darwin'; } return `server-darwin-${arch}`; case 'web': if (arch === 'x64') { return 'server-darwin-web'; } return `server-darwin-${arch}-web`; case 'cli': return `cli-darwin-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } } // Contains all of the logic for mapping types to our actual types in CosmosDB function getRealType(type) { switch (type) { case 'user-setup': return 'setup'; case 'deb-package': case 'rpm-package': return 'package'; default: return type; } } async function withLease(client, fn) { const lease = client.getBlobLeaseClient(); for (let i = 0; i < 360; i++) { // Try to get lease for 30 minutes try { await client.uploadData(new ArrayBuffer()); // blob needs to exist for lease to be acquired await lease.acquireLease(60); try { const abortController = new AbortController(); const refresher = new Promise((c, e) => { abortController.signal.onabort = () => { (0, node_timers_1.clearInterval)(interval); c(); }; const interval = (0, node_timers_1.setInterval)(() => { lease.renewLease().catch(err => { (0, node_timers_1.clearInterval)(interval); e(new Error('Failed to renew lease ' + err)); }); }, 30_000); }); const result = await Promise.race([fn(), refresher]); abortController.abort(); return result; } finally { await lease.releaseLease(); } } catch (err) { if (err.statusCode !== 409 && err.statusCode !== 412) { throw err; } await new Promise(c => setTimeout(c, 5000)); } } throw new Error('Failed to acquire lease on blob after 30 minutes'); } async function processArtifact(artifact, filePath) { const log = (...args) => console.log(`[${artifact.name}]`, ...args); const match = /^vscode_(?[^_]+)_(?[^_]+)(?:_legacy)?_(?[^_]+)_(?[^_]+)$/.exec(artifact.name); if (!match) { throw new Error(`Invalid artifact name: ${artifact.name}`); } const { cosmosDBAccessToken, blobServiceAccessToken } = JSON.parse(e('PUBLISH_AUTH_TOKENS')); const quality = e('VSCODE_QUALITY'); const version = e('BUILD_SOURCEVERSION'); const friendlyFileName = `${quality}/${version}/${path_1.default.basename(filePath)}`; const blobServiceClient = new storage_blob_1.BlobServiceClient(`https://${e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')}.blob.core.windows.net/`, { getToken: async () => blobServiceAccessToken }); const leasesContainerClient = blobServiceClient.getContainerClient('leases'); await leasesContainerClient.createIfNotExists(); const leaseBlobClient = leasesContainerClient.getBlockBlobClient(friendlyFileName); log(`Acquiring lease for: ${friendlyFileName}`); await withLease(leaseBlobClient, async () => { log(`Successfully acquired lease for: ${friendlyFileName}`); const url = `${e('PRSS_CDN_URL')}/${friendlyFileName}`; const res = await (0, retry_1.retry)(() => fetch(url)); if (res.status === 200) { log(`Already released and provisioned: ${url}`); } else { const stagingContainerClient = blobServiceClient.getContainerClient('staging'); await stagingContainerClient.createIfNotExists(); const now = new Date().valueOf(); const oneHour = 60 * 60 * 1000; const oneHourAgo = new Date(now - oneHour); const oneHourFromNow = new Date(now + oneHour); const userDelegationKey = await blobServiceClient.getUserDelegationKey(oneHourAgo, oneHourFromNow); const sasOptions = { containerName: 'staging', permissions: storage_blob_1.ContainerSASPermissions.from({ read: true }), startsOn: oneHourAgo, expiresOn: oneHourFromNow }; const stagingSasToken = (0, storage_blob_1.generateBlobSASQueryParameters)(sasOptions, userDelegationKey, e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')).toString(); const releaseService = await ESRPReleaseService.create(log, e('RELEASE_TENANT_ID'), e('RELEASE_CLIENT_ID'), e('RELEASE_AUTH_CERT'), e('RELEASE_REQUEST_SIGNING_CERT'), stagingContainerClient, stagingSasToken); await releaseService.createRelease(version, filePath, friendlyFileName); } const { product, os, arch, unprocessedType } = match.groups; const platform = getPlatform(product, os, arch, unprocessedType); const type = getRealType(unprocessedType); const size = fs_1.default.statSync(filePath).size; const stream = fs_1.default.createReadStream(filePath); const [hash, sha256hash] = await Promise.all([hashStream('sha1', stream), hashStream('sha256', stream)]); // CodeQL [SM04514] Using SHA1 only for legacy reasons, we are actually only respecting SHA256 const asset = { platform, type, url, hash: hash.toString('hex'), sha256hash: sha256hash.toString('hex'), size, supportsFastUpdate: true }; log('Creating asset...'); const result = await (0, retry_1.retry)(async (attempt) => { log(`Creating asset in Cosmos DB (attempt ${attempt})...`); const client = new cosmos_1.CosmosClient({ endpoint: e('AZURE_DOCUMENTDB_ENDPOINT'), tokenProvider: () => Promise.resolve(`type=aad&ver=1.0&sig=${cosmosDBAccessToken.token}`) }); const scripts = client.database('builds').container(quality).scripts; const { resource: result } = await scripts.storedProcedure('createAsset').execute('', [version, asset, true]); return result; }); if (result === 'already exists') { log('Asset already exists!'); } else { log('Asset successfully created: ', JSON.stringify(asset, undefined, 2)); } }); log(`Successfully released lease for: ${friendlyFileName}`); } // It is VERY important that we don't download artifacts too much too fast from AZDO. // AZDO throttles us SEVERELY if we do. Not just that, but they also close open // sockets, so the whole things turns to a grinding halt. So, downloading and extracting // happens serially in the main thread, making the downloads are spaced out // properly. For each extracted artifact, we spawn a worker thread to upload it to // the CDN and finally update the build in Cosmos DB. async function main() { if (!node_worker_threads_1.isMainThread) { const { artifact, artifactFilePath } = node_worker_threads_1.workerData; await processArtifact(artifact, artifactFilePath); return; } const done = new State(); const processing = new Set(); for (const name of done) { console.log(`\u2705 ${name}`); } const stages = new Set(['Compile']); if (e('VSCODE_BUILD_STAGE_LINUX') === 'True' || e('VSCODE_BUILD_STAGE_ALPINE') === 'True' || e('VSCODE_BUILD_STAGE_MACOS') === 'True' || e('VSCODE_BUILD_STAGE_WINDOWS') === 'True') { stages.add('CompileCLI'); } if (e('VSCODE_BUILD_STAGE_WINDOWS') === 'True') { stages.add('Windows'); } if (e('VSCODE_BUILD_STAGE_LINUX') === 'True') { stages.add('Linux'); } if (e('VSCODE_BUILD_STAGE_ALPINE') === 'True') { stages.add('Alpine'); } if (e('VSCODE_BUILD_STAGE_MACOS') === 'True') { stages.add('macOS'); } if (e('VSCODE_BUILD_STAGE_WEB') === 'True') { stages.add('Web'); } let resultPromise = Promise.resolve([]); const operations = []; while (true) { const [timeline, artifacts] = await Promise.all([(0, retry_1.retry)(() => getPipelineTimeline()), (0, retry_1.retry)(() => getPipelineArtifacts())]); const stagesCompleted = new Set(timeline.records.filter(r => r.type === 'Stage' && r.state === 'completed' && stages.has(r.name)).map(r => r.name)); const stagesInProgress = [...stages].filter(s => !stagesCompleted.has(s)); const artifactsInProgress = artifacts.filter(a => processing.has(a.name)); if (stagesInProgress.length === 0 && artifacts.length === done.size + processing.size) { break; } else if (stagesInProgress.length > 0) { console.log('Stages in progress:', stagesInProgress.join(', ')); } else if (artifactsInProgress.length > 0) { console.log('Artifacts in progress:', artifactsInProgress.map(a => a.name).join(', ')); } else { console.log(`Waiting for a total of ${artifacts.length}, ${done.size} done, ${processing.size} in progress...`); } for (const artifact of artifacts) { if (done.has(artifact.name) || processing.has(artifact.name)) { continue; } console.log(`[${artifact.name}] Found new artifact`); const artifactZipPath = path_1.default.join(e('AGENT_TEMPDIRECTORY'), `${artifact.name}.zip`); await (0, retry_1.retry)(async (attempt) => { const start = Date.now(); console.log(`[${artifact.name}] Downloading (attempt ${attempt})...`); await downloadArtifact(artifact, artifactZipPath); const archiveSize = fs_1.default.statSync(artifactZipPath).size; const downloadDurationS = (Date.now() - start) / 1000; const downloadSpeedKBS = Math.round((archiveSize / 1024) / downloadDurationS); console.log(`[${artifact.name}] Successfully downloaded after ${Math.floor(downloadDurationS)} seconds(${downloadSpeedKBS} KB/s).`); }); const artifactFilePaths = await unzip(artifactZipPath, e('AGENT_TEMPDIRECTORY')); const artifactFilePath = artifactFilePaths.filter(p => !/_manifest/.test(p))[0]; processing.add(artifact.name); const promise = new Promise((resolve, reject) => { const worker = new node_worker_threads_1.Worker(__filename, { workerData: { artifact, artifactFilePath } }); worker.on('error', reject); worker.on('exit', code => { if (code === 0) { resolve(); } else { reject(new Error(`[${artifact.name}] Worker stopped with exit code ${code}`)); } }); }); const operation = promise.then(() => { processing.delete(artifact.name); done.add(artifact.name); console.log(`\u2705 ${artifact.name} `); }); operations.push({ name: artifact.name, operation }); resultPromise = Promise.allSettled(operations.map(o => o.operation)); } await new Promise(c => setTimeout(c, 10_000)); } console.log(`Found all ${done.size + processing.size} artifacts, waiting for ${processing.size} artifacts to finish publishing...`); const artifactsInProgress = operations.filter(o => processing.has(o.name)); if (artifactsInProgress.length > 0) { console.log('Artifacts in progress:', artifactsInProgress.map(a => a.name).join(', ')); } const results = await resultPromise; for (let i = 0; i < operations.length; i++) { const result = results[i]; if (result.status === 'rejected') { console.error(`[${operations[i].name}]`, result.reason); } } if (results.some(r => r.status === 'rejected')) { throw new Error('Some artifacts failed to publish'); } console.log(`All ${done.size} artifacts published!`); } if (require.main === module) { main().then(() => { process.exit(0); }, err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=publish.js.map ================================================ FILE: build/azure-pipelines/common/publish.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import { Readable } from 'stream'; import type { ReadableStream } from 'stream/web'; import { pipeline } from 'node:stream/promises'; import yauzl from 'yauzl'; import crypto from 'crypto'; import { retry } from './retry'; import { CosmosClient } from '@azure/cosmos'; import cp from 'child_process'; import os from 'os'; import { Worker, isMainThread, workerData } from 'node:worker_threads'; import { ConfidentialClientApplication } from '@azure/msal-node'; import { BlobClient, BlobServiceClient, BlockBlobClient, ContainerClient, ContainerSASPermissions, generateBlobSASQueryParameters } from '@azure/storage-blob'; import jws from 'jws'; import { clearInterval, setInterval } from 'node:timers'; function e(name: string): string { const result = process.env[name]; if (typeof result !== 'string') { throw new Error(`Missing env: ${name}`); } return result; } function hashStream(hashName: string, stream: Readable): Promise { return new Promise((c, e) => { const shasum = crypto.createHash(hashName); stream .on('data', shasum.update.bind(shasum)) .on('error', e) .on('close', () => c(shasum.digest())); }); } interface ReleaseSubmitResponse { operationId: string; esrpCorrelationId: string; code?: string; message?: string; target?: string; innerError?: any; } interface ReleaseActivityInfo { activityId: string; activityType: string; name: string; status: string; errorCode: number; errorMessages: string[]; beginTime?: Date; endTime?: Date; lastModifiedAt?: Date; } interface InnerServiceError { code: string; details: { [key: string]: string }; innerError?: InnerServiceError; } interface ReleaseError { errorCode: number; errorMessages: string[]; } const enum StatusCode { Pass = 'pass', Aborted = 'aborted', Inprogress = 'inprogress', FailCanRetry = 'failCanRetry', FailDoNotRetry = 'failDoNotRetry', PendingAnalysis = 'pendingAnalysis', Cancelled = 'cancelled' } interface ReleaseResultMessage { activities: ReleaseActivityInfo[]; childWorkflowType: string; clientId: string; customerCorrelationId: string; errorInfo: InnerServiceError; groupId: string; lastModifiedAt: Date; operationId: string; releaseError: ReleaseError; requestSubmittedAt: Date; routedRegion: string; status: StatusCode; totalFileCount: number; totalReleaseSize: number; version: string; } interface ReleaseFileInfo { name?: string; hash?: number[]; sourceLocation?: FileLocation; sizeInBytes?: number; hashType?: FileHashType; fileId?: any; distributionRelativePath?: string; partNumber?: string; friendlyFileName?: string; tenantFileLocationType?: string; tenantFileLocation?: string; signedEngineeringCopyLocation?: string; encryptedDistributionBlobLocation?: string; preEncryptedDistributionBlobLocation?: string; secondaryDistributionHashRequired?: boolean; secondaryDistributionHashType?: FileHashType; lastModifiedAt?: Date; cultureCodes?: string[]; displayFileInDownloadCenter?: boolean; isPrimaryFileInDownloadCenter?: boolean; fileDownloadDetails?: FileDownloadDetails[]; } interface ReleaseDetailsFileInfo extends ReleaseFileInfo { } interface ReleaseDetailsMessage extends ReleaseResultMessage { clusterRegion: string; correlationVector: string; releaseCompletedAt?: Date; releaseInfo: ReleaseInfo; productInfo: ProductInfo; createdBy: UserInfo; owners: OwnerInfo[]; accessPermissionsInfo: AccessPermissionsInfo; files: ReleaseDetailsFileInfo[]; comments: string[]; cancellationReason: string; downloadCenterInfo: DownloadCenterInfo; } interface ProductInfo { name?: string; version?: string; description?: string; } interface ReleaseInfo { title?: string; minimumNumberOfApprovers: number; properties?: { [key: string]: string }; isRevision?: boolean; revisionNumber?: string; } type FileLocationType = 'azureBlob'; interface FileLocation { type: FileLocationType; blobUrl: string; uncPath?: string; url?: string; } type FileHashType = 'sha256' | 'sha1'; interface FileDownloadDetails { portalName: string; downloadUrl: string; } interface RoutingInfo { intent?: string; contentType?: string; contentOrigin?: string; productState?: string; audience?: string; } interface ReleaseFileInfo { name?: string; hash?: number[]; sourceLocation?: FileLocation; sizeInBytes?: number; hashType?: FileHashType; fileId?: any; distributionRelativePath?: string; partNumber?: string; friendlyFileName?: string; tenantFileLocationType?: string; tenantFileLocation?: string; signedEngineeringCopyLocation?: string; encryptedDistributionBlobLocation?: string; preEncryptedDistributionBlobLocation?: string; secondaryDistributionHashRequired?: boolean; secondaryDistributionHashType?: FileHashType; lastModifiedAt?: Date; cultureCodes?: string[]; displayFileInDownloadCenter?: boolean; isPrimaryFileInDownloadCenter?: boolean; fileDownloadDetails?: FileDownloadDetails[]; } interface UserInfo { userPrincipalName?: string; } interface OwnerInfo { owner: UserInfo; } interface ApproverInfo { approver: UserInfo; isAutoApproved: boolean; isMandatory: boolean; } interface AccessPermissionsInfo { mainPublisher?: string; releasePublishers?: string[]; channelDownloadEntityDetails?: { [key: string]: string[] }; } interface DownloadCenterLocaleInfo { cultureCode?: string; downloadTitle?: string; shortName?: string; shortDescription?: string; longDescription?: string; instructions?: string; additionalInfo?: string; keywords?: string[]; version?: string; relatedLinks?: { [key: string]: URL }; } interface DownloadCenterInfo { downloadCenterId: number; publishToDownloadCenter?: boolean; publishingGroup?: string; operatingSystems?: string[]; relatedReleases?: string[]; kbNumbers?: string[]; sbNumbers?: string[]; locales?: DownloadCenterLocaleInfo[]; additionalProperties?: { [key: string]: string }; } interface ReleaseRequestMessage { driEmail: string[]; groupId?: string; customerCorrelationId: string; esrpCorrelationId: string; contextData?: { [key: string]: string }; releaseInfo: ReleaseInfo; productInfo: ProductInfo; files: ReleaseFileInfo[]; routingInfo?: RoutingInfo; createdBy: UserInfo; owners: OwnerInfo[]; approvers: ApproverInfo[]; accessPermissionsInfo: AccessPermissionsInfo; jwsToken?: string; publisherId?: string; downloadCenterInfo?: DownloadCenterInfo; } function getCertificateBuffer(input: string) { return Buffer.from(input.replace(/-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----|\n/g, ''), 'base64'); } function getThumbprint(input: string, algorithm: string): Buffer { const buffer = getCertificateBuffer(input); return crypto.createHash(algorithm).update(buffer).digest(); } function getKeyFromPFX(pfx: string): string { const pfxCertificatePath = path.join(os.tmpdir(), 'cert.pfx'); const pemKeyPath = path.join(os.tmpdir(), 'key.pem'); try { const pfxCertificate = Buffer.from(pfx, 'base64'); fs.writeFileSync(pfxCertificatePath, pfxCertificate); cp.execSync(`openssl pkcs12 -in "${pfxCertificatePath}" -nocerts -nodes -out "${pemKeyPath}" -passin pass:`); const raw = fs.readFileSync(pemKeyPath, 'utf-8'); const result = raw.match(/-----BEGIN PRIVATE KEY-----[\s\S]+?-----END PRIVATE KEY-----/g)![0]; return result; } finally { fs.rmSync(pfxCertificatePath, { force: true }); fs.rmSync(pemKeyPath, { force: true }); } } function getCertificatesFromPFX(pfx: string): string[] { const pfxCertificatePath = path.join(os.tmpdir(), 'cert.pfx'); const pemCertificatePath = path.join(os.tmpdir(), 'cert.pem'); try { const pfxCertificate = Buffer.from(pfx, 'base64'); fs.writeFileSync(pfxCertificatePath, pfxCertificate); cp.execSync(`openssl pkcs12 -in "${pfxCertificatePath}" -nokeys -out "${pemCertificatePath}" -passin pass:`); const raw = fs.readFileSync(pemCertificatePath, 'utf-8'); const matches = raw.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g); return matches ? matches.reverse() : []; } finally { fs.rmSync(pfxCertificatePath, { force: true }); fs.rmSync(pemCertificatePath, { force: true }); } } class ESRPReleaseService { static async create( log: (...args: any[]) => void, tenantId: string, clientId: string, authCertificatePfx: string, requestSigningCertificatePfx: string, containerClient: ContainerClient, stagingSasToken: string ) { const authKey = getKeyFromPFX(authCertificatePfx); const authCertificate = getCertificatesFromPFX(authCertificatePfx)[0]; const requestSigningKey = getKeyFromPFX(requestSigningCertificatePfx); const requestSigningCertificates = getCertificatesFromPFX(requestSigningCertificatePfx); const app = new ConfidentialClientApplication({ auth: { clientId, authority: `https://login.microsoftonline.com/${tenantId}`, clientCertificate: { thumbprintSha256: getThumbprint(authCertificate, 'sha256').toString('hex'), privateKey: authKey, x5c: authCertificate } } }); const response = await app.acquireTokenByClientCredential({ scopes: ['https://api.esrp.microsoft.com/.default'] }); return new ESRPReleaseService(log, clientId, response!.accessToken, requestSigningCertificates, requestSigningKey, containerClient, stagingSasToken); } private static API_URL = 'https://api.esrp.microsoft.com/api/v3/releaseservices/clients/'; private constructor( private readonly log: (...args: any[]) => void, private readonly clientId: string, private readonly accessToken: string, private readonly requestSigningCertificates: string[], private readonly requestSigningKey: string, private readonly containerClient: ContainerClient, private readonly stagingSasToken: string ) { } async createRelease(version: string, filePath: string, friendlyFileName: string) { const correlationId = crypto.randomUUID(); const blobClient = this.containerClient.getBlockBlobClient(correlationId); this.log(`Uploading ${filePath} to ${blobClient.url}`); await blobClient.uploadFile(filePath); this.log('Uploaded blob successfully'); try { this.log(`Submitting release for ${version}: ${filePath}`); const submitReleaseResult = await this.submitRelease(version, filePath, friendlyFileName, correlationId, blobClient); this.log(`Successfully submitted release ${submitReleaseResult.operationId}. Polling for completion...`); // Poll every 5 seconds, wait 60 minutes max -> poll 60/5*60=720 times for (let i = 0; i < 720; i++) { await new Promise(c => setTimeout(c, 5000)); const releaseStatus = await this.getReleaseStatus(submitReleaseResult.operationId); if (releaseStatus.status === 'pass') { break; } else if (releaseStatus.status === 'aborted') { this.log(JSON.stringify(releaseStatus)); throw new Error(`Release was aborted`); } else if (releaseStatus.status !== 'inprogress') { this.log(JSON.stringify(releaseStatus)); throw new Error(`Unknown error when polling for release`); } } const releaseDetails = await this.getReleaseDetails(submitReleaseResult.operationId); if (releaseDetails.status !== 'pass') { throw new Error(`Timed out waiting for release: ${JSON.stringify(releaseDetails)}`); } this.log('Successfully created release:', releaseDetails.files[0].fileDownloadDetails![0].downloadUrl); return releaseDetails.files[0].fileDownloadDetails![0].downloadUrl; } finally { this.log(`Deleting blob ${blobClient.url}`); await blobClient.delete(); this.log('Deleted blob successfully'); } } private async submitRelease( version: string, filePath: string, friendlyFileName: string, correlationId: string, blobClient: BlobClient ): Promise { const size = fs.statSync(filePath).size; const hash = await hashStream('sha256', fs.createReadStream(filePath)); const blobUrl = `${blobClient.url}?${this.stagingSasToken}`; const message: ReleaseRequestMessage = { customerCorrelationId: correlationId, esrpCorrelationId: correlationId, driEmail: ['joao.moreno@microsoft.com'], createdBy: { userPrincipalName: 'jomo@microsoft.com' }, owners: [{ owner: { userPrincipalName: 'jomo@microsoft.com' } }], approvers: [{ approver: { userPrincipalName: 'jomo@microsoft.com' }, isAutoApproved: true, isMandatory: false }], releaseInfo: { title: 'VS Code', properties: { 'ReleaseContentType': 'InstallPackage' }, minimumNumberOfApprovers: 1 }, productInfo: { name: 'VS Code', version, description: 'VS Code' }, accessPermissionsInfo: { mainPublisher: 'VSCode', channelDownloadEntityDetails: { AllDownloadEntities: ['VSCode'] } }, routingInfo: { intent: 'filedownloadlinkgeneration' }, files: [{ name: path.basename(filePath), friendlyFileName, tenantFileLocation: blobUrl, tenantFileLocationType: 'AzureBlob', sourceLocation: { type: 'azureBlob', blobUrl }, hashType: 'sha256', hash: Array.from(hash), sizeInBytes: size }] }; message.jwsToken = await this.generateJwsToken(message); const res = await fetch(`${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.accessToken}` }, body: JSON.stringify(message) }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to submit release: ${res.statusText}\n${text}`); } return await res.json() as ReleaseSubmitResponse; } private async getReleaseStatus(releaseId: string): Promise { const url = `${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations/grs/${releaseId}`; const res = await fetch(url, { headers: { 'Authorization': `Bearer ${this.accessToken}` } }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to get release status: ${res.statusText}\n${text}`); } return await res.json() as ReleaseResultMessage; } private async getReleaseDetails(releaseId: string): Promise { const url = `${ESRPReleaseService.API_URL}${this.clientId}/workflows/release/operations/grd/${releaseId}`; const res = await fetch(url, { headers: { 'Authorization': `Bearer ${this.accessToken}` } }); if (!res.ok) { const text = await res.text(); throw new Error(`Failed to get release status: ${res.statusText}\n${text}`); } return await res.json() as ReleaseDetailsMessage; } private async generateJwsToken(message: ReleaseRequestMessage): Promise { return jws.sign({ header: { alg: 'RS256', crit: ['exp', 'x5t'], // Release service uses ticks, not seconds :roll_eyes: (https://stackoverflow.com/a/7968483) exp: ((Date.now() + (6 * 60 * 1000)) * 10000) + 621355968000000000, // Release service uses hex format, not base64url :roll_eyes: x5t: getThumbprint(this.requestSigningCertificates[0], 'sha1').toString('hex'), // Release service uses a '.' separated string, not an array of strings :roll_eyes: x5c: this.requestSigningCertificates.map(c => getCertificateBuffer(c).toString('base64url')).join('.') as any, }, payload: message, privateKey: this.requestSigningKey, }); } } class State { private statePath: string; private set = new Set(); constructor() { const pipelineWorkspacePath = e('PIPELINE_WORKSPACE'); const previousState = fs.readdirSync(pipelineWorkspacePath) .map(name => /^artifacts_processed_(\d+)$/.exec(name)) .filter((match): match is RegExpExecArray => !!match) .map(match => ({ name: match![0], attempt: Number(match![1]) })) .sort((a, b) => b.attempt - a.attempt)[0]; if (previousState) { const previousStatePath = path.join(pipelineWorkspacePath, previousState.name, previousState.name + '.txt'); fs.readFileSync(previousStatePath, 'utf8').split(/\n/).filter(name => !!name).forEach(name => this.set.add(name)); } const stageAttempt = e('SYSTEM_STAGEATTEMPT'); this.statePath = path.join(pipelineWorkspacePath, `artifacts_processed_${stageAttempt}`, `artifacts_processed_${stageAttempt}.txt`); fs.mkdirSync(path.dirname(this.statePath), { recursive: true }); fs.writeFileSync(this.statePath, [...this.set.values()].map(name => `${name}\n`).join('')); } get size(): number { return this.set.size; } has(name: string): boolean { return this.set.has(name); } add(name: string): void { this.set.add(name); fs.appendFileSync(this.statePath, `${name}\n`); } [Symbol.iterator](): IterableIterator { return this.set[Symbol.iterator](); } } const azdoFetchOptions = { headers: { // Pretend we're a web browser to avoid download rate limits 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Referer': 'https://dev.azure.com', Authorization: `Bearer ${e('SYSTEM_ACCESSTOKEN')}` } }; async function requestAZDOAPI(path: string): Promise { const abortController = new AbortController(); const timeout = setTimeout(() => abortController.abort(), 2 * 60 * 1000); try { const res = await fetch(`${e('BUILDS_API_URL')}${path}?api-version=6.0`, { ...azdoFetchOptions, signal: abortController.signal }); if (!res.ok) { throw new Error(`Unexpected status code: ${res.status}`); } return await res.json(); } finally { clearTimeout(timeout); } } interface Artifact { readonly name: string; readonly resource: { readonly downloadUrl: string; readonly properties: { readonly artifactsize: number; }; }; } async function getPipelineArtifacts(): Promise { const result = await requestAZDOAPI<{ readonly value: Artifact[] }>('artifacts'); return result.value.filter(a => /^vscode_/.test(a.name) && !/sbom$/.test(a.name)); } interface Timeline { readonly records: { readonly name: string; readonly type: string; readonly state: string; }[]; } async function getPipelineTimeline(): Promise { return await requestAZDOAPI('timeline'); } async function downloadArtifact(artifact: Artifact, downloadPath: string): Promise { const abortController = new AbortController(); const timeout = setTimeout(() => abortController.abort(), 4 * 60 * 1000); try { const res = await fetch(artifact.resource.downloadUrl, { ...azdoFetchOptions, signal: abortController.signal }); if (!res.ok) { throw new Error(`Unexpected status code: ${res.status}`); } await pipeline(Readable.fromWeb(res.body as ReadableStream), fs.createWriteStream(downloadPath)); } finally { clearTimeout(timeout); } } async function unzip(packagePath: string, outputPath: string): Promise { return new Promise((resolve, reject) => { yauzl.open(packagePath, { lazyEntries: true, autoClose: true }, (err, zipfile) => { if (err) { return reject(err); } const result: string[] = []; zipfile!.on('entry', entry => { if (/\/$/.test(entry.fileName)) { zipfile!.readEntry(); } else { zipfile!.openReadStream(entry, (err, istream) => { if (err) { return reject(err); } const filePath = path.join(outputPath, entry.fileName); fs.mkdirSync(path.dirname(filePath), { recursive: true }); const ostream = fs.createWriteStream(filePath); ostream.on('finish', () => { result.push(filePath); zipfile!.readEntry(); }); istream?.on('error', err => reject(err)); istream!.pipe(ostream); }); } }); zipfile!.on('close', () => resolve(result)); zipfile!.readEntry(); }); }); } interface Asset { platform: string; type: string; url: string; mooncakeUrl?: string; prssUrl?: string; hash: string; sha256hash: string; size: number; supportsFastUpdate?: boolean; } // Contains all of the logic for mapping details to our actual product names in CosmosDB function getPlatform(product: string, os: string, arch: string, type: string): string { switch (os) { case 'win32': switch (product) { case 'client': { switch (type) { case 'archive': return `win32-${arch}-archive`; case 'setup': return `win32-${arch}`; case 'user-setup': return `win32-${arch}-user`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } } case 'server': return `server-win32-${arch}`; case 'web': return `server-win32-${arch}-web`; case 'cli': return `cli-win32-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'alpine': switch (product) { case 'server': return `server-alpine-${arch}`; case 'web': return `server-alpine-${arch}-web`; case 'cli': return `cli-alpine-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'linux': switch (type) { case 'snap': return `linux-snap-${arch}`; case 'archive-unsigned': switch (product) { case 'client': return `linux-${arch}`; case 'server': return `server-linux-${arch}`; case 'web': if (arch === 'standalone') { return 'web-standalone'; } return `server-linux-${arch}-web`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'deb-package': return `linux-deb-${arch}`; case 'rpm-package': return `linux-rpm-${arch}`; case 'cli': return `cli-linux-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } case 'darwin': switch (product) { case 'client': if (arch === 'x64') { return 'darwin'; } return `darwin-${arch}`; case 'server': if (arch === 'x64') { return 'server-darwin'; } return `server-darwin-${arch}`; case 'web': if (arch === 'x64') { return 'server-darwin-web'; } return `server-darwin-${arch}-web`; case 'cli': return `cli-darwin-${arch}`; default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } default: throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`); } } // Contains all of the logic for mapping types to our actual types in CosmosDB function getRealType(type: string) { switch (type) { case 'user-setup': return 'setup'; case 'deb-package': case 'rpm-package': return 'package'; default: return type; } } async function withLease(client: BlockBlobClient, fn: () => Promise) { const lease = client.getBlobLeaseClient(); for (let i = 0; i < 360; i++) { // Try to get lease for 30 minutes try { await client.uploadData(new ArrayBuffer()); // blob needs to exist for lease to be acquired await lease.acquireLease(60); try { const abortController = new AbortController(); const refresher = new Promise((c, e) => { abortController.signal.onabort = () => { clearInterval(interval); c(); }; const interval = setInterval(() => { lease.renewLease().catch(err => { clearInterval(interval); e(new Error('Failed to renew lease ' + err)); }); }, 30_000); }); const result = await Promise.race([fn(), refresher]); abortController.abort(); return result; } finally { await lease.releaseLease(); } } catch (err) { if (err.statusCode !== 409 && err.statusCode !== 412) { throw err; } await new Promise(c => setTimeout(c, 5000)); } } throw new Error('Failed to acquire lease on blob after 30 minutes'); } async function processArtifact( artifact: Artifact, filePath: string ) { const log = (...args: any[]) => console.log(`[${artifact.name}]`, ...args); const match = /^vscode_(?[^_]+)_(?[^_]+)(?:_legacy)?_(?[^_]+)_(?[^_]+)$/.exec(artifact.name); if (!match) { throw new Error(`Invalid artifact name: ${artifact.name}`); } const { cosmosDBAccessToken, blobServiceAccessToken } = JSON.parse(e('PUBLISH_AUTH_TOKENS')); const quality = e('VSCODE_QUALITY'); const version = e('BUILD_SOURCEVERSION'); const friendlyFileName = `${quality}/${version}/${path.basename(filePath)}`; const blobServiceClient = new BlobServiceClient(`https://${e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')}.blob.core.windows.net/`, { getToken: async () => blobServiceAccessToken }); const leasesContainerClient = blobServiceClient.getContainerClient('leases'); await leasesContainerClient.createIfNotExists(); const leaseBlobClient = leasesContainerClient.getBlockBlobClient(friendlyFileName); log(`Acquiring lease for: ${friendlyFileName}`); await withLease(leaseBlobClient, async () => { log(`Successfully acquired lease for: ${friendlyFileName}`); const url = `${e('PRSS_CDN_URL')}/${friendlyFileName}`; const res = await retry(() => fetch(url)); if (res.status === 200) { log(`Already released and provisioned: ${url}`); } else { const stagingContainerClient = blobServiceClient.getContainerClient('staging'); await stagingContainerClient.createIfNotExists(); const now = new Date().valueOf(); const oneHour = 60 * 60 * 1000; const oneHourAgo = new Date(now - oneHour); const oneHourFromNow = new Date(now + oneHour); const userDelegationKey = await blobServiceClient.getUserDelegationKey(oneHourAgo, oneHourFromNow); const sasOptions = { containerName: 'staging', permissions: ContainerSASPermissions.from({ read: true }), startsOn: oneHourAgo, expiresOn: oneHourFromNow }; const stagingSasToken = generateBlobSASQueryParameters(sasOptions, userDelegationKey, e('VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME')).toString(); const releaseService = await ESRPReleaseService.create( log, e('RELEASE_TENANT_ID'), e('RELEASE_CLIENT_ID'), e('RELEASE_AUTH_CERT'), e('RELEASE_REQUEST_SIGNING_CERT'), stagingContainerClient, stagingSasToken ); await releaseService.createRelease(version, filePath, friendlyFileName); } const { product, os, arch, unprocessedType } = match.groups!; const platform = getPlatform(product, os, arch, unprocessedType); const type = getRealType(unprocessedType); const size = fs.statSync(filePath).size; const stream = fs.createReadStream(filePath); const [hash, sha256hash] = await Promise.all([hashStream('sha1', stream), hashStream('sha256', stream)]); // CodeQL [SM04514] Using SHA1 only for legacy reasons, we are actually only respecting SHA256 const asset: Asset = { platform, type, url, hash: hash.toString('hex'), sha256hash: sha256hash.toString('hex'), size, supportsFastUpdate: true }; log('Creating asset...'); const result = await retry(async (attempt) => { log(`Creating asset in Cosmos DB (attempt ${attempt})...`); const client = new CosmosClient({ endpoint: e('AZURE_DOCUMENTDB_ENDPOINT')!, tokenProvider: () => Promise.resolve(`type=aad&ver=1.0&sig=${cosmosDBAccessToken.token}`) }); const scripts = client.database('builds').container(quality).scripts; const { resource: result } = await scripts.storedProcedure('createAsset').execute<'ok' | 'already exists'>('', [version, asset, true]); return result; }); if (result === 'already exists') { log('Asset already exists!'); } else { log('Asset successfully created: ', JSON.stringify(asset, undefined, 2)); } }); log(`Successfully released lease for: ${friendlyFileName}`); } // It is VERY important that we don't download artifacts too much too fast from AZDO. // AZDO throttles us SEVERELY if we do. Not just that, but they also close open // sockets, so the whole things turns to a grinding halt. So, downloading and extracting // happens serially in the main thread, making the downloads are spaced out // properly. For each extracted artifact, we spawn a worker thread to upload it to // the CDN and finally update the build in Cosmos DB. async function main() { if (!isMainThread) { const { artifact, artifactFilePath } = workerData; await processArtifact(artifact, artifactFilePath); return; } const done = new State(); const processing = new Set(); for (const name of done) { console.log(`\u2705 ${name}`); } const stages = new Set(['Compile']); if ( e('VSCODE_BUILD_STAGE_LINUX') === 'True' || e('VSCODE_BUILD_STAGE_ALPINE') === 'True' || e('VSCODE_BUILD_STAGE_MACOS') === 'True' || e('VSCODE_BUILD_STAGE_WINDOWS') === 'True' ) { stages.add('CompileCLI'); } if (e('VSCODE_BUILD_STAGE_WINDOWS') === 'True') { stages.add('Windows'); } if (e('VSCODE_BUILD_STAGE_LINUX') === 'True') { stages.add('Linux'); } if (e('VSCODE_BUILD_STAGE_ALPINE') === 'True') { stages.add('Alpine'); } if (e('VSCODE_BUILD_STAGE_MACOS') === 'True') { stages.add('macOS'); } if (e('VSCODE_BUILD_STAGE_WEB') === 'True') { stages.add('Web'); } let resultPromise = Promise.resolve[]>([]); const operations: { name: string; operation: Promise }[] = []; while (true) { const [timeline, artifacts] = await Promise.all([retry(() => getPipelineTimeline()), retry(() => getPipelineArtifacts())]); const stagesCompleted = new Set(timeline.records.filter(r => r.type === 'Stage' && r.state === 'completed' && stages.has(r.name)).map(r => r.name)); const stagesInProgress = [...stages].filter(s => !stagesCompleted.has(s)); const artifactsInProgress = artifacts.filter(a => processing.has(a.name)); if (stagesInProgress.length === 0 && artifacts.length === done.size + processing.size) { break; } else if (stagesInProgress.length > 0) { console.log('Stages in progress:', stagesInProgress.join(', ')); } else if (artifactsInProgress.length > 0) { console.log('Artifacts in progress:', artifactsInProgress.map(a => a.name).join(', ')); } else { console.log(`Waiting for a total of ${artifacts.length}, ${done.size} done, ${processing.size} in progress...`); } for (const artifact of artifacts) { if (done.has(artifact.name) || processing.has(artifact.name)) { continue; } console.log(`[${artifact.name}] Found new artifact`); const artifactZipPath = path.join(e('AGENT_TEMPDIRECTORY'), `${artifact.name}.zip`); await retry(async (attempt) => { const start = Date.now(); console.log(`[${artifact.name}] Downloading (attempt ${attempt})...`); await downloadArtifact(artifact, artifactZipPath); const archiveSize = fs.statSync(artifactZipPath).size; const downloadDurationS = (Date.now() - start) / 1000; const downloadSpeedKBS = Math.round((archiveSize / 1024) / downloadDurationS); console.log(`[${artifact.name}] Successfully downloaded after ${Math.floor(downloadDurationS)} seconds(${downloadSpeedKBS} KB/s).`); }); const artifactFilePaths = await unzip(artifactZipPath, e('AGENT_TEMPDIRECTORY')); const artifactFilePath = artifactFilePaths.filter(p => !/_manifest/.test(p))[0]; processing.add(artifact.name); const promise = new Promise((resolve, reject) => { const worker = new Worker(__filename, { workerData: { artifact, artifactFilePath } }); worker.on('error', reject); worker.on('exit', code => { if (code === 0) { resolve(); } else { reject(new Error(`[${artifact.name}] Worker stopped with exit code ${code}`)); } }); }); const operation = promise.then(() => { processing.delete(artifact.name); done.add(artifact.name); console.log(`\u2705 ${artifact.name} `); }); operations.push({ name: artifact.name, operation }); resultPromise = Promise.allSettled(operations.map(o => o.operation)); } await new Promise(c => setTimeout(c, 10_000)); } console.log(`Found all ${done.size + processing.size} artifacts, waiting for ${processing.size} artifacts to finish publishing...`); const artifactsInProgress = operations.filter(o => processing.has(o.name)); if (artifactsInProgress.length > 0) { console.log('Artifacts in progress:', artifactsInProgress.map(a => a.name).join(', ')); } const results = await resultPromise; for (let i = 0; i < operations.length; i++) { const result = results[i]; if (result.status === 'rejected') { console.error(`[${operations[i].name}]`, result.reason); } } if (results.some(r => r.status === 'rejected')) { throw new Error('Some artifacts failed to publish'); } console.log(`All ${done.size} artifacts published!`); } if (require.main === module) { main().then(() => { process.exit(0); }, err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/azure-pipelines/common/releaseBuild.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const identity_1 = require("@azure/identity"); const cosmos_1 = require("@azure/cosmos"); const retry_1 = require("./retry"); function getEnv(name) { const result = process.env[name]; if (typeof result === 'undefined') { throw new Error('Missing env: ' + name); } return result; } function createDefaultConfig(quality) { return { id: quality, frozen: false }; } async function getConfig(client, quality) { const query = `SELECT TOP 1 * FROM c WHERE c.id = "${quality}"`; const res = await client.database('builds').container('config').items.query(query).fetchAll(); if (res.resources.length === 0) { return createDefaultConfig(quality); } return res.resources[0]; } async function main(force) { const commit = getEnv('BUILD_SOURCEVERSION'); const quality = getEnv('VSCODE_QUALITY'); const aadCredentials = new identity_1.ClientAssertionCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], () => Promise.resolve(process.env['AZURE_ID_TOKEN'])); const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], aadCredentials }); if (!force) { const config = await getConfig(client, quality); console.log('Quality config:', config); if (config.frozen) { console.log(`Skipping release because quality ${quality} is frozen.`); return; } } console.log(`Releasing build ${commit}...`); const scripts = client.database('builds').container(quality).scripts; await (0, retry_1.retry)(() => scripts.storedProcedure('releaseBuild').execute('', [commit])); } const [, , force] = process.argv; console.log(process.argv); main(/^true$/i.test(force)).then(() => { console.log('Build successfully released'); process.exit(0); }, err => { console.error(err); process.exit(1); }); //# sourceMappingURL=releaseBuild.js.map ================================================ FILE: build/azure-pipelines/common/releaseBuild.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ClientAssertionCredential } from '@azure/identity'; import { CosmosClient } from '@azure/cosmos'; import { retry } from './retry'; function getEnv(name: string): string { const result = process.env[name]; if (typeof result === 'undefined') { throw new Error('Missing env: ' + name); } return result; } interface Config { id: string; frozen: boolean; } function createDefaultConfig(quality: string): Config { return { id: quality, frozen: false }; } async function getConfig(client: CosmosClient, quality: string): Promise { const query = `SELECT TOP 1 * FROM c WHERE c.id = "${quality}"`; const res = await client.database('builds').container('config').items.query(query).fetchAll(); if (res.resources.length === 0) { return createDefaultConfig(quality); } return res.resources[0] as Config; } async function main(force: boolean): Promise { const commit = getEnv('BUILD_SOURCEVERSION'); const quality = getEnv('VSCODE_QUALITY'); const aadCredentials = new ClientAssertionCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, () => Promise.resolve(process.env['AZURE_ID_TOKEN']!)); const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, aadCredentials }); if (!force) { const config = await getConfig(client, quality); console.log('Quality config:', config); if (config.frozen) { console.log(`Skipping release because quality ${quality} is frozen.`); return; } } console.log(`Releasing build ${commit}...`); const scripts = client.database('builds').container(quality).scripts; await retry(() => scripts.storedProcedure('releaseBuild').execute('', [commit])); } const [, , force] = process.argv; console.log(process.argv); main(/^true$/i.test(force)).then(() => { console.log('Build successfully released'); process.exit(0); }, err => { console.error(err); process.exit(1); }); ================================================ FILE: build/azure-pipelines/common/retry.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.retry = retry; async function retry(fn) { let lastError; for (let run = 1; run <= 10; run++) { try { return await fn(run); } catch (err) { if (!/fetch failed|terminated|aborted|timeout|TimeoutError|Timeout Error|RestError|Client network socket disconnected|socket hang up|ECONNRESET|CredentialUnavailableError|endpoints_resolution_error|Audience validation failed|end of central directory record signature not found/i.test(err.message)) { throw err; } lastError = err; // maximum delay is 10th retry: ~3 seconds const millis = Math.floor((Math.random() * 200) + (50 * Math.pow(1.5, run))); await new Promise(c => setTimeout(c, millis)); } } console.error(`Too many retries, aborting.`); throw lastError; } //# sourceMappingURL=retry.js.map ================================================ FILE: build/azure-pipelines/common/retry.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export async function retry(fn: (attempt: number) => Promise): Promise { let lastError: Error | undefined; for (let run = 1; run <= 10; run++) { try { return await fn(run); } catch (err) { if (!/fetch failed|terminated|aborted|timeout|TimeoutError|Timeout Error|RestError|Client network socket disconnected|socket hang up|ECONNRESET|CredentialUnavailableError|endpoints_resolution_error|Audience validation failed|end of central directory record signature not found/i.test(err.message)) { throw err; } lastError = err; // maximum delay is 10th retry: ~3 seconds const millis = Math.floor((Math.random() * 200) + (50 * Math.pow(1.5, run))); await new Promise(c => setTimeout(c, millis)); } } console.error(`Too many retries, aborting.`); throw lastError; } ================================================ FILE: build/azure-pipelines/common/sign-win32.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const sign_1 = require("./sign"); const path_1 = __importDefault(require("path")); (0, sign_1.main)([ process.env['EsrpCliDllPath'], 'sign-windows', path_1.default.dirname(process.argv[2]), path_1.default.basename(process.argv[2]) ]); //# sourceMappingURL=sign-win32.js.map ================================================ FILE: build/azure-pipelines/common/sign-win32.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { main } from './sign'; import path from 'path'; main([ process.env['EsrpCliDllPath']!, 'sign-windows', path.dirname(process.argv[2]), path.basename(process.argv[2]) ]); ================================================ FILE: build/azure-pipelines/common/sign.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Temp = void 0; exports.main = main; const child_process_1 = __importDefault(require("child_process")); const fs_1 = __importDefault(require("fs")); const crypto_1 = __importDefault(require("crypto")); const path_1 = __importDefault(require("path")); const os_1 = __importDefault(require("os")); class Temp { _files = []; tmpNameSync() { const file = path_1.default.join(os_1.default.tmpdir(), crypto_1.default.randomBytes(20).toString('hex')); this._files.push(file); return file; } dispose() { for (const file of this._files) { try { fs_1.default.unlinkSync(file); } catch (err) { // noop } } } } exports.Temp = Temp; function getParams(type) { switch (type) { case 'sign-windows': return [ { keyCode: 'CP-230012', operationSetCode: 'SigntoolSign', parameters: [ { parameterName: 'OpusName', parameterValue: 'VS Code' }, { parameterName: 'OpusInfo', parameterValue: 'https://code.visualstudio.com/' }, { parameterName: 'Append', parameterValue: '/as' }, { parameterName: 'FileDigest', parameterValue: '/fd "SHA256"' }, { parameterName: 'PageHash', parameterValue: '/NPH' }, { parameterName: 'TimeStamp', parameterValue: '/tr "http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer" /td sha256' } ], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-230012', operationSetCode: 'SigntoolVerify', parameters: [ { parameterName: 'VerifyAll', parameterValue: '/all' } ], toolName: 'sign', toolVersion: '1.0' } ]; case 'sign-windows-appx': return [ { keyCode: 'CP-229979', operationSetCode: 'SigntoolSign', parameters: [ { parameterName: 'OpusName', parameterValue: 'VS Code' }, { parameterName: 'OpusInfo', parameterValue: 'https://code.visualstudio.com/' }, { parameterName: 'FileDigest', parameterValue: '/fd "SHA256"' }, { parameterName: 'PageHash', parameterValue: '/NPH' }, { parameterName: 'TimeStamp', parameterValue: '/tr "http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer" /td sha256' } ], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-229979', operationSetCode: 'SigntoolVerify', parameters: [], toolName: 'sign', toolVersion: '1.0' } ]; case 'sign-pgp': return [{ keyCode: 'CP-450779-Pgp', operationSetCode: 'LinuxSign', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; case 'sign-darwin': return [{ keyCode: 'CP-401337-Apple', operationSetCode: 'MacAppDeveloperSign', parameters: [{ parameterName: 'Hardening', parameterValue: '--options=runtime' }], toolName: 'sign', toolVersion: '1.0' }]; case 'notarize-darwin': return [{ keyCode: 'CP-401337-Apple', operationSetCode: 'MacAppNotarize', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; case 'nuget': return [{ keyCode: 'CP-401405', operationSetCode: 'NuGetSign', parameters: [], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-401405', operationSetCode: 'NuGetVerify', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; default: throw new Error(`Sign type ${type} not found`); } } function main([esrpCliPath, type, folderPath, pattern]) { const tmp = new Temp(); process.on('exit', () => tmp.dispose()); const key = crypto_1.default.randomBytes(32); const iv = crypto_1.default.randomBytes(16); const cipher = crypto_1.default.createCipheriv('aes-256-cbc', key, iv); const encryptedToken = cipher.update(process.env['SYSTEM_ACCESSTOKEN'].trim(), 'utf8', 'hex') + cipher.final('hex'); const encryptionDetailsPath = tmp.tmpNameSync(); fs_1.default.writeFileSync(encryptionDetailsPath, JSON.stringify({ key: key.toString('hex'), iv: iv.toString('hex') })); const encryptedTokenPath = tmp.tmpNameSync(); fs_1.default.writeFileSync(encryptedTokenPath, encryptedToken); const patternPath = tmp.tmpNameSync(); fs_1.default.writeFileSync(patternPath, pattern); const paramsPath = tmp.tmpNameSync(); fs_1.default.writeFileSync(paramsPath, JSON.stringify(getParams(type))); const dotnetVersion = child_process_1.default.execSync('dotnet --version', { encoding: 'utf8' }).trim(); const adoTaskVersion = path_1.default.basename(path_1.default.dirname(path_1.default.dirname(esrpCliPath))); const federatedTokenData = { jobId: process.env['SYSTEM_JOBID'], planId: process.env['SYSTEM_PLANID'], projectId: process.env['SYSTEM_TEAMPROJECTID'], hub: process.env['SYSTEM_HOSTTYPE'], uri: process.env['SYSTEM_COLLECTIONURI'], managedIdentityId: process.env['VSCODE_ESRP_CLIENT_ID'], managedIdentityTenantId: process.env['VSCODE_ESRP_TENANT_ID'], serviceConnectionId: process.env['VSCODE_ESRP_SERVICE_CONNECTION_ID'], tempDirectory: os_1.default.tmpdir(), systemAccessToken: encryptedTokenPath, encryptionKey: encryptionDetailsPath }; const args = [ esrpCliPath, 'vsts.sign', '-a', process.env['ESRP_CLIENT_ID'], '-d', process.env['ESRP_TENANT_ID'], '-k', JSON.stringify({ akv: 'vscode-esrp' }), '-z', JSON.stringify({ akv: 'vscode-esrp', cert: 'esrp-sign' }), '-f', folderPath, '-p', patternPath, '-u', 'false', '-x', 'regularSigning', '-b', 'input.json', '-l', 'AzSecPack_PublisherPolicyProd.xml', '-y', 'inlineSignParams', '-j', paramsPath, '-c', '9997', '-t', '120', '-g', '10', '-v', 'Tls12', '-s', 'https://api.esrp.microsoft.com/api/v1', '-m', '0', '-o', 'Microsoft', '-i', 'https://www.microsoft.com', '-n', '5', '-r', 'true', '-w', dotnetVersion, '-skipAdoReportAttachment', 'false', '-pendingAnalysisWaitTimeoutMinutes', '5', '-adoTaskVersion', adoTaskVersion, '-resourceUri', 'https://msazurecloud.onmicrosoft.com/api.esrp.microsoft.com', '-esrpClientId', process.env['ESRP_CLIENT_ID'], '-useMSIAuthentication', 'true', '-federatedTokenData', JSON.stringify(federatedTokenData) ]; try { child_process_1.default.execFileSync('dotnet', args, { stdio: 'inherit' }); } catch (err) { console.error('ESRP failed'); console.error(err); process.exit(1); } } if (require.main === module) { main(process.argv.slice(2)); process.exit(0); } //# sourceMappingURL=sign.js.map ================================================ FILE: build/azure-pipelines/common/sign.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import cp from 'child_process'; import fs from 'fs'; import crypto from 'crypto'; import path from 'path'; import os from 'os'; export class Temp { private _files: string[] = []; tmpNameSync(): string { const file = path.join(os.tmpdir(), crypto.randomBytes(20).toString('hex')); this._files.push(file); return file; } dispose(): void { for (const file of this._files) { try { fs.unlinkSync(file); } catch (err) { // noop } } } } interface Params { readonly keyCode: string; readonly operationSetCode: string; readonly parameters: { readonly parameterName: string; readonly parameterValue: string; }[]; readonly toolName: string; readonly toolVersion: string; } function getParams(type: string): Params[] { switch (type) { case 'sign-windows': return [ { keyCode: 'CP-230012', operationSetCode: 'SigntoolSign', parameters: [ { parameterName: 'OpusName', parameterValue: 'VS Code' }, { parameterName: 'OpusInfo', parameterValue: 'https://code.visualstudio.com/' }, { parameterName: 'Append', parameterValue: '/as' }, { parameterName: 'FileDigest', parameterValue: '/fd "SHA256"' }, { parameterName: 'PageHash', parameterValue: '/NPH' }, { parameterName: 'TimeStamp', parameterValue: '/tr "http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer" /td sha256' } ], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-230012', operationSetCode: 'SigntoolVerify', parameters: [ { parameterName: 'VerifyAll', parameterValue: '/all' } ], toolName: 'sign', toolVersion: '1.0' } ]; case 'sign-windows-appx': return [ { keyCode: 'CP-229979', operationSetCode: 'SigntoolSign', parameters: [ { parameterName: 'OpusName', parameterValue: 'VS Code' }, { parameterName: 'OpusInfo', parameterValue: 'https://code.visualstudio.com/' }, { parameterName: 'FileDigest', parameterValue: '/fd "SHA256"' }, { parameterName: 'PageHash', parameterValue: '/NPH' }, { parameterName: 'TimeStamp', parameterValue: '/tr "http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer" /td sha256' } ], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-229979', operationSetCode: 'SigntoolVerify', parameters: [], toolName: 'sign', toolVersion: '1.0' } ]; case 'sign-pgp': return [{ keyCode: 'CP-450779-Pgp', operationSetCode: 'LinuxSign', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; case 'sign-darwin': return [{ keyCode: 'CP-401337-Apple', operationSetCode: 'MacAppDeveloperSign', parameters: [{ parameterName: 'Hardening', parameterValue: '--options=runtime' }], toolName: 'sign', toolVersion: '1.0' }]; case 'notarize-darwin': return [{ keyCode: 'CP-401337-Apple', operationSetCode: 'MacAppNotarize', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; case 'nuget': return [{ keyCode: 'CP-401405', operationSetCode: 'NuGetSign', parameters: [], toolName: 'sign', toolVersion: '1.0' }, { keyCode: 'CP-401405', operationSetCode: 'NuGetVerify', parameters: [], toolName: 'sign', toolVersion: '1.0' }]; default: throw new Error(`Sign type ${type} not found`); } } export function main([esrpCliPath, type, folderPath, pattern]: string[]) { const tmp = new Temp(); process.on('exit', () => tmp.dispose()); const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); const encryptedToken = cipher.update(process.env['SYSTEM_ACCESSTOKEN']!.trim(), 'utf8', 'hex') + cipher.final('hex'); const encryptionDetailsPath = tmp.tmpNameSync(); fs.writeFileSync(encryptionDetailsPath, JSON.stringify({ key: key.toString('hex'), iv: iv.toString('hex') })); const encryptedTokenPath = tmp.tmpNameSync(); fs.writeFileSync(encryptedTokenPath, encryptedToken); const patternPath = tmp.tmpNameSync(); fs.writeFileSync(patternPath, pattern); const paramsPath = tmp.tmpNameSync(); fs.writeFileSync(paramsPath, JSON.stringify(getParams(type))); const dotnetVersion = cp.execSync('dotnet --version', { encoding: 'utf8' }).trim(); const adoTaskVersion = path.basename(path.dirname(path.dirname(esrpCliPath))); const federatedTokenData = { jobId: process.env['SYSTEM_JOBID'], planId: process.env['SYSTEM_PLANID'], projectId: process.env['SYSTEM_TEAMPROJECTID'], hub: process.env['SYSTEM_HOSTTYPE'], uri: process.env['SYSTEM_COLLECTIONURI'], managedIdentityId: process.env['VSCODE_ESRP_CLIENT_ID'], managedIdentityTenantId: process.env['VSCODE_ESRP_TENANT_ID'], serviceConnectionId: process.env['VSCODE_ESRP_SERVICE_CONNECTION_ID'], tempDirectory: os.tmpdir(), systemAccessToken: encryptedTokenPath, encryptionKey: encryptionDetailsPath }; const args = [ esrpCliPath, 'vsts.sign', '-a', process.env['ESRP_CLIENT_ID']!, '-d', process.env['ESRP_TENANT_ID']!, '-k', JSON.stringify({ akv: 'vscode-esrp' }), '-z', JSON.stringify({ akv: 'vscode-esrp', cert: 'esrp-sign' }), '-f', folderPath, '-p', patternPath, '-u', 'false', '-x', 'regularSigning', '-b', 'input.json', '-l', 'AzSecPack_PublisherPolicyProd.xml', '-y', 'inlineSignParams', '-j', paramsPath, '-c', '9997', '-t', '120', '-g', '10', '-v', 'Tls12', '-s', 'https://api.esrp.microsoft.com/api/v1', '-m', '0', '-o', 'Microsoft', '-i', 'https://www.microsoft.com', '-n', '5', '-r', 'true', '-w', dotnetVersion, '-skipAdoReportAttachment', 'false', '-pendingAnalysisWaitTimeoutMinutes', '5', '-adoTaskVersion', adoTaskVersion, '-resourceUri', 'https://msazurecloud.onmicrosoft.com/api.esrp.microsoft.com', '-esrpClientId', process.env['ESRP_CLIENT_ID']!, '-useMSIAuthentication', 'true', '-federatedTokenData', JSON.stringify(federatedTokenData) ]; try { cp.execFileSync('dotnet', args, { stdio: 'inherit' }); } catch (err) { console.error('ESRP failed'); console.error(err); process.exit(1); } } if (require.main === module) { main(process.argv.slice(2)); process.exit(0); } ================================================ FILE: build/azure-pipelines/common/telemetry-config.json ================================================ [ { "eventPrefix": "typescript-language-features/", "sourceDirs": [ "../../s/extensions/typescript-language-features" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "git/", "sourceDirs": [ "../../s/extensions/git" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "extension-telemetry/", "sourceDirs": [ "vscode-extension-telemetry" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "vscode-markdown/", "sourceDirs": [ "../../s/extensions/markdown-language-features" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "html-language-features/", "sourceDirs": [ "../../s/extensions/html-language-features", "vscode-html-languageservice" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "json-language-features/", "sourceDirs": [ "../../s/extensions/json-language-features", "vscode-json-languageservice" ], "excludedDirs": [], "applyEndpoints": true }, { "eventPrefix": "ms-vscode.node/", "sourceDirs": [ "vscode-chrome-debug-core", "vscode-node-debug" ], "excludedDirs": [], "applyEndpoints": true, "patchDebugEvents": true } ] ================================================ FILE: build/azure-pipelines/config/CredScanSuppressions.json ================================================ { "tool": "Credential Scanner", "suppressions": [ { "file": [ "src/vs/base/test/common/uri.test.ts", "src/vs/workbench/api/test/browser/extHostTelemetry.test.ts" ], "_justification": "These are dummy credentials in tests." }, { "file": [ ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/stage/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/stage/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/prime/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/prime/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/parts/code/build/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/parts/code/install/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/parts/code/src/usr/share/code/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-x64/parts/code/build/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/parts/code/install/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-x64/parts/code/src/usr/share/code/resources/app/extensions/emmet/dist/node/emmetNodeMain.js" ], "_justification": "These are safe to ignore, since they are built artifacts (stable)." }, { "file": [ ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/stage/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/stage/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/prime/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/prime/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/build/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/install/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/src/usr/share/code-insiders/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/build/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/install/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-insiders-x64/parts/code/src/usr/share/code-insiders/resources/app/extensions/emmet/dist/node/emmetNodeMain.js" ], "_justification": "These are safe to ignore, since they are built artifacts (insiders)." }, { "file": [ ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/x86_64/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/armv7hl/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/rpm/aarch64/rpmbuild/BUILD/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/stage/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/stage/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/prime/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/prime/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/build/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/install/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/src/usr/share/code-exploration/resources/app/extensions/github-authentication/dist/extension.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/build/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/install/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js", ".build/linux/snap/x64/code-exploration-x64/parts/code/src/usr/share/code-exploration/resources/app/extensions/emmet/dist/node/emmetNodeMain.js" ], "_justification": "These are safe to ignore, since they are built artifacts (exploration)." }, { "file": [ ".build/web/extensions/github-authentication/dist/browser/extension.js", ".build/web/extensions/emmet/dist/browser/emmetBrowserMain.js.map", ".build/web/extensions/emmet/dist/browser/emmetBrowserMain.js" ], "_justification": "These are safe to ignore, since they are built artifacts (web)." } ] } ================================================ FILE: build/azure-pipelines/config/tsaoptions.json ================================================ { "codebaseName": "devdiv_microsoft_vscode", "serviceTreeID": "79c048b2-322f-4ed5-a1ea-252a1250e4b3", "instanceUrl": "https://devdiv.visualstudio.com/defaultcollection", "projectName": "DevDiv", "areaPath": "DevDiv\\VS Code (compliance tracking only)\\Visual Studio Code Client", "notificationAliases": [ "monacotools@microsoft.com" ], "validateToolOutput": "None", "allTools": true } ================================================ FILE: build/azure-pipelines/darwin/app-entitlements.plist ================================================ com.apple.security.cs.allow-jit com.apple.security.device.audio-input com.apple.security.device.camera com.apple.security.automation.apple-events ================================================ FILE: build/azure-pipelines/darwin/cli-build-darwin.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_BUILD_MACOS type: boolean default: false - name: VSCODE_BUILD_MACOS_ARM64 type: boolean default: false - name: VSCODE_CHECK_ONLY type: boolean default: false steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 displayName: Download openssl prebuilt inputs: command: custom customCommand: pack @vscode-internal/openssl-prebuilt@0.0.11 customRegistry: useFeed customFeed: "Monaco/openssl-prebuilt" workingDir: $(Build.ArtifactStagingDirectory) - script: | set -e mkdir $(Build.ArtifactStagingDirectory)/openssl tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - template: ../cli/install-rust-posix.yml@self parameters: targets: - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - x86_64-apple-darwin - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - aarch64-apple-darwin - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/include - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/include - ${{ if not(parameters.VSCODE_CHECK_ONLY) }}: - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/unsigned_vscode_cli_darwin_x64_cli.zip artifactName: unsigned_vscode_cli_darwin_x64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code macOS x64 CLI (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish unsigned_vscode_cli_darwin_x64_cli artifact - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/unsigned_vscode_cli_darwin_arm64_cli.zip artifactName: unsigned_vscode_cli_darwin_arm64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code macOS arm64 CLI (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish unsigned_vscode_cli_darwin_arm64_cli artifact ================================================ FILE: build/azure-pipelines/darwin/helper-gpu-entitlements.plist ================================================ com.apple.security.cs.allow-jit ================================================ FILE: build/azure-pipelines/darwin/helper-plugin-entitlements.plist ================================================ com.apple.security.cs.allow-jit com.apple.security.cs.allow-unsigned-executable-memory com.apple.security.cs.disable-library-validation ================================================ FILE: build/azure-pipelines/darwin/helper-renderer-entitlements.plist ================================================ com.apple.security.cs.allow-jit ================================================ FILE: build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml ================================================ parameters: - name: VSCODE_BUILD_MACOS type: boolean - name: VSCODE_BUILD_MACOS_ARM64 type: boolean - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - script: node build/setup-npm-registry.js $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies - template: ../cli/cli-darwin-sign.yml@self parameters: VSCODE_CLI_ARTIFACTS: - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - unsigned_vscode_cli_darwin_x64_cli - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - unsigned_vscode_cli_darwin_arm64_cli ================================================ FILE: build/azure-pipelines/darwin/product-build-darwin-sign.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: UseDotNet@2 inputs: version: 6.x - task: EsrpCodeSigning@5 inputs: UseMSIAuthentication: true ConnectedServiceName: vscode-esrp AppRegistrationClientId: $(ESRP_CLIENT_ID) AppRegistrationTenantId: $(ESRP_TENANT_ID) AuthAKVName: vscode-esrp AuthSignCertName: esrp-sign FolderPath: . Pattern: noop displayName: 'Install ESRP Tooling' - script: | # For legacy purposes, arch for x64 is just 'darwin' case $VSCODE_ARCH in x64) ASSET_ID="darwin" ;; arm64) ASSET_ID="darwin-arm64" ;; universal) ASSET_ID="darwin-universal" ;; esac echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID" displayName: Set asset id variable - script: | if [ -z "$(ASSET_ID)" ]; then echo "ASSET_ID is empty" exit 1 else echo "ASSET_ID is set to $(ASSET_ID)" fi displayName: Check ASSET_ID variable - download: current artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive displayName: Download $(VSCODE_ARCH) artifact - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll sign-darwin $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll notarize-darwin $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Notarize - script: unzip $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-$(VSCODE_ARCH).zip -d $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH) displayName: Extract signed app - script: | set -e APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)" APP_NAME="`ls $APP_ROOT | head -n 1`" APP_PATH="$APP_ROOT/$APP_NAME" codesign -dv --deep --verbose=4 "$APP_PATH" "$APP_PATH/Contents/Resources/app/bin/code" --export-default-configuration=.build displayName: Verify signature condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - script: mv $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-x64.zip $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin.zip displayName: Rename x64 build to its legacy name condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-$(ASSET_ID).zip artifactName: vscode_client_darwin_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH) sbomPackageName: "VS Code macOS $(VSCODE_ARCH)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish client archive ================================================ FILE: build/azure-pipelines/darwin/product-build-darwin-test.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean steps: - script: npm exec -- npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test.sh --tfs "Unit Tests" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - script: npm run test-node displayName: Run unit tests (node.js) timeoutInMinutes: 15 - script: npm run test-browser-no-install -- --browser webkit --tfs "Browser Unit Tests" env: DEBUG: "*browser*" displayName: Run unit tests (Browser, Webkit) timeoutInMinutes: 30 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test.sh --build --tfs "Unit Tests" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - script: npm run test-node -- --build displayName: Run unit tests (node.js) timeoutInMinutes: 15 - script: npm run test-browser-no-install -- --build --browser webkit --tfs "Browser Unit Tests" env: DEBUG: "*browser*" displayName: Run unit tests (Browser, Webkit) timeoutInMinutes: 30 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - script: | set -e npm run gulp \ compile-extension:configuration-editing \ compile-extension:css-language-features-server \ compile-extension:emmet \ compile-extension:git \ compile-extension:github-authentication \ compile-extension:html-language-features-server \ compile-extension:ipynb \ compile-extension:notebook-renderers \ compile-extension:json-language-features-server \ compile-extension:markdown-language-features \ compile-extension-media \ compile-extension:microsoft-authentication \ compile-extension:typescript-language-features \ compile-extension:vscode-api-tests \ compile-extension:vscode-colorize-tests \ compile-extension:vscode-colorize-perf-tests \ compile-extension:vscode-test-resolver displayName: Build integration tests - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test-integration --tfs "Integration Tests" displayName: Run integration tests (Electron) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | # Figure out the full absolute path of the product we just built # including the remote server and configure the integration tests # to run with these builds instead of running out of sources. set -e APP_ROOT="$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)" APP_NAME="`ls $APP_ROOT | head -n 1`" INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ ./scripts/test-integration.sh --build --tfs "Integration Tests" env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) displayName: Run integration tests (Electron) timeoutInMinutes: 20 - script: ./scripts/test-web-integration.sh --browser webkit env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web displayName: Run integration tests (Browser, Webkit) timeoutInMinutes: 20 - script: | set -e APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) APP_NAME="`ls $APP_ROOT | head -n 1`" INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ ./scripts/test-remote-integration.sh env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) displayName: Run integration tests (Remote) timeoutInMinutes: 20 - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - script: ps -ef displayName: Diagnostics before smoke test run continueOnError: true condition: succeededOrFailed() - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: npm run compile workingDirectory: test/smoke displayName: Compile smoke tests - script: npm run gulp compile-extension-media displayName: Compile extensions for smoke tests - script: npm run smoketest-no-compile -- --tracing timeoutInMinutes: 20 displayName: Run smoke tests (Electron) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) APP_NAME="`ls $APP_ROOT | head -n 1`" npm run smoketest-no-compile -- --tracing --build "$APP_ROOT/$APP_NAME" timeoutInMinutes: 20 displayName: Run smoke tests (Electron) - script: npm run smoketest-no-compile -- --web --tracing --headless env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web timeoutInMinutes: 20 displayName: Run smoke tests (Browser, Chromium) - script: | set -e npm run gulp compile-extension:vscode-test-resolver APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) APP_NAME="`ls $APP_ROOT | head -n 1`" npm run smoketest-no-compile -- --tracing --remote --build "$APP_ROOT/$APP_NAME" env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) timeoutInMinutes: 20 displayName: Run smoke tests (Remote) - script: ps -ef displayName: Diagnostics after smoke test run continueOnError: true condition: succeededOrFailed() - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: .build/crashes ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: crash-dump-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: crash-dump-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: crash-dump-macos-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Crash Reports" continueOnError: true condition: failed() # In order to properly symbolify above crash reports # (if any), we need the compiled native modules too - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: node_modules ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: node-modules-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: node-modules-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: node-modules-macos-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Node Modules" continueOnError: true condition: failed() - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: .build/logs ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: logs-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: logs-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: logs-macos-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Log Files" continueOnError: true condition: succeededOrFailed() - task: PublishTestResults@2 displayName: Publish Tests Results inputs: testResultsFiles: "*-results.xml" searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" condition: succeededOrFailed() ================================================ FILE: build/azure-pipelines/darwin/product-build-darwin-universal.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.js $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies - download: current artifact: unsigned_vscode_client_darwin_x64_archive displayName: Download x64 artifact - download: current artifact: unsigned_vscode_client_darwin_arm64_archive displayName: Download arm64 artifact - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - script: | set -e unzip $(Pipeline.Workspace)/unsigned_vscode_client_darwin_x64_archive/VSCode-darwin-x64.zip -d $(agent.builddirectory)/VSCode-darwin-x64 unzip $(Pipeline.Workspace)/unsigned_vscode_client_darwin_arm64_archive/VSCode-darwin-arm64.zip -d $(agent.builddirectory)/VSCode-darwin-arm64 DEBUG=* node build/darwin/create-universal-app.js $(agent.builddirectory) displayName: Create Universal App - script: | set -e APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)" APP_NAME="`ls $APP_ROOT | head -n 1`" APP_PATH="$APP_ROOT/$APP_NAME" node build/darwin/verify-macho.js universal displayName: Verify arch of Mach-O objects - script: | set -e security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain security default-keychain -s $(agent.tempdirectory)/buildagent.keychain security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12 security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign export CODESIGN_IDENTITY=$(security find-identity -v -p codesigning $(agent.tempdirectory)/buildagent.keychain | grep -oEi "([0-9A-F]{40})" | head -n 1) security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain DEBUG=electron-osx-sign* node build/darwin/sign.js $(agent.builddirectory) displayName: Set Hardened Entitlements - script: pushd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * && popd displayName: Archive build - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip artifactName: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH) sbomPackageName: "VS Code macOS $(VSCODE_ARCH) (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish client archive ================================================ FILE: build/azure-pipelines/darwin/product-build-darwin.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_CIBUILD type: boolean - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean steps: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - checkout: self fetchDepth: 1 retryCountOnTaskFailure: 3 - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - task: DownloadPipelineArtifact@2 inputs: artifact: Compilation path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js darwin $VSCODE_ARCH > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e c++ --version xcode-select -print-path python3 -m pip install setuptools for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: npm_config_arch: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" # Avoid using dlopen to load Kerberos on macOS which can cause missing libraries # https://github.com/mongodb-js/kerberos/commit/04044d2814ad1d01e77f1ce87f26b03d86692cf2 # flipped the default to support legacy linux distros which shouldn't happen # on macOS. GYP_DEFINES: "kerberos_use_rtld=false" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: ../common/install-builtin-extensions.yml@self - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - script: node build/lib/policies darwin displayName: Generate policy definitions retryCountOnTaskFailure: 3 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e npm run gulp vscode-darwin-$(VSCODE_ARCH)-min-ci echo "##vso[task.setvariable variable=BUILT_CLIENT]true" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client - script: | set -e npm run gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH).zip" mkdir -p $(dirname $ARCHIVE_PATH) (cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH)) echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - script: | set -e npm run gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH)-web.zip" mkdir -p $(dirname $ARCHIVE_PATH) (cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH)-web) echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) - ${{ else }}: - script: npm run gulp transpile-client-esbuild transpile-extensions env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Transpile - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - template: product-build-darwin-test.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} - ${{ elseif and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - task: DownloadPipelineArtifact@2 inputs: artifact: unsigned_vscode_cli_darwin_$(VSCODE_ARCH)_cli patterns: "**" path: $(Build.ArtifactStagingDirectory)/cli displayName: Download VS Code CLI - script: | set -e APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)" APP_NAME="`ls $APP_ROOT | head -n 1`" APP_PATH="$APP_ROOT/$APP_NAME" unzip $(Build.ArtifactStagingDirectory)/cli/*.zip -d $(Build.ArtifactStagingDirectory)/cli CLI_APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").tunnelApplicationName") APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").applicationName") mv "$(Build.ArtifactStagingDirectory)/cli/$APP_NAME" "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME" chmod +x "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME" displayName: Make CLI executable - script: | set -e APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)" APP_NAME="`ls $APP_ROOT | head -n 1`" APP_PATH="$APP_ROOT/$APP_NAME" node build/darwin/verify-macho.js $(VSCODE_ARCH) APP_PATH="$(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)" node build/darwin/verify-macho.js $(VSCODE_ARCH) displayName: Verify arch of Mach-O objects # Setting hardened entitlements is a requirement for: # * Apple notarization # * Running tests on Big Sur (because Big Sur has additional security precautions) - script: | set -e security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain security default-keychain -s $(agent.tempdirectory)/buildagent.keychain security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12 security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign export CODESIGN_IDENTITY=$(security find-identity -v -p codesigning $(agent.tempdirectory)/buildagent.keychain | grep -oEi "([0-9A-F]{40})" | head -n 1) security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain DEBUG=electron-osx-sign* node build/darwin/sign.js $(agent.builddirectory) displayName: Set Hardened Entitlements - script: | set -e ARCHIVE_PATH=".build/darwin/client/VSCode-darwin-$(VSCODE_ARCH).zip" mkdir -p $(dirname $ARCHIVE_PATH) (cd ../VSCode-darwin-$(VSCODE_ARCH) && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH *) echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) displayName: Package client - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) displayName: Generate artifact prefix - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(CLIENT_PATH) artifactName: $(ARTIFACT_PREFIX)unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH) sbomPackageName: "VS Code macOS $(VSCODE_ARCH) (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish client archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SERVER_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH) sbomPackageName: "VS Code macOS $(VSCODE_ARCH) Server" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web sbomPackageName: "VS Code macOS $(VSCODE_ARCH) Web" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive ================================================ FILE: build/azure-pipelines/distro/download-distro.yml ================================================ steps: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" # TODO@joaomoreno: Keep pwsh once we move out of running entire jobs in containers - pwsh: | "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Setup distro auth (Windows) - pwsh: | $ErrorActionPreference = "Stop" $ArchivePath = "$(Agent.TempDirectory)/distro.zip" $PackageJson = Get-Content -Path package.json -Raw | ConvertFrom-Json $DistroVersion = $PackageJson.distro Invoke-WebRequest -Uri "https://api.github.com/repos/microsoft/vscode-distro/zipball/$DistroVersion" ` -OutFile $ArchivePath ` -Headers @{ "Accept" = "application/vnd.github+json"; "Authorization" = "Bearer $(github-distro-mixin-password)"; "X-GitHub-Api-Version" = "2022-11-28" } New-Item -ItemType Directory -Path .build -Force Expand-Archive -Path $ArchivePath -DestinationPath .build Rename-Item -Path ".build/microsoft-vscode-distro-$DistroVersion" -NewName distro condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Download distro (Windows) - script: | mkdir -p .build cat << EOF | tee ~/.netrc .build/.netrc > /dev/null machine github.com login vscode password $(github-distro-mixin-password) EOF condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) displayName: Setup distro auth (non-Windows) - script: | set -e ArchivePath="$(Agent.TempDirectory)/distro.zip" DistroVersion=$(node -p "require('./package.json').distro") curl -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $(github-distro-mixin-password)" \ -H "X-GitHub-Api-Version: 2022-11-28" \ -o $ArchivePath \ -L "https://api.github.com/repos/microsoft/vscode-distro/zipball/$DistroVersion" unzip $ArchivePath -d .build mv .build/microsoft-vscode-distro-$DistroVersion .build/distro condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) displayName: Download distro (non-Windows) ================================================ FILE: build/azure-pipelines/distro/mixin-npm.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const { dirs } = require('../../npm/dirs'); function log(...args) { console.log(`[${new Date().toLocaleTimeString('en', { hour12: false })}]`, '[distro]', ...args); } function mixin(mixinPath) { if (!fs_1.default.existsSync(`${mixinPath}/node_modules`)) { log(`Skipping distro npm dependencies: ${mixinPath} (no node_modules)`); return; } log(`Mixing in distro npm dependencies: ${mixinPath}`); const distroPackageJson = JSON.parse(fs_1.default.readFileSync(`${mixinPath}/package.json`, 'utf8')); const targetPath = path_1.default.relative('.build/distro/npm', mixinPath); for (const dependency of Object.keys(distroPackageJson.dependencies)) { fs_1.default.rmSync(`./${targetPath}/node_modules/${dependency}`, { recursive: true, force: true }); fs_1.default.cpSync(`${mixinPath}/node_modules/${dependency}`, `./${targetPath}/node_modules/${dependency}`, { recursive: true, force: true, dereference: true }); } log(`Mixed in distro npm dependencies: ${mixinPath} ✔︎`); } function main() { log(`Mixing in distro npm dependencies...`); const mixinPaths = dirs.filter(d => /^.build\/distro\/npm/.test(d)); for (const mixinPath of mixinPaths) { mixin(mixinPath); } } main(); //# sourceMappingURL=mixin-npm.js.map ================================================ FILE: build/azure-pipelines/distro/mixin-npm.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; const { dirs } = require('../../npm/dirs') as { dirs: string[] }; function log(...args: any[]): void { console.log(`[${new Date().toLocaleTimeString('en', { hour12: false })}]`, '[distro]', ...args); } function mixin(mixinPath: string) { if (!fs.existsSync(`${mixinPath}/node_modules`)) { log(`Skipping distro npm dependencies: ${mixinPath} (no node_modules)`); return; } log(`Mixing in distro npm dependencies: ${mixinPath}`); const distroPackageJson = JSON.parse(fs.readFileSync(`${mixinPath}/package.json`, 'utf8')); const targetPath = path.relative('.build/distro/npm', mixinPath); for (const dependency of Object.keys(distroPackageJson.dependencies)) { fs.rmSync(`./${targetPath}/node_modules/${dependency}`, { recursive: true, force: true }); fs.cpSync(`${mixinPath}/node_modules/${dependency}`, `./${targetPath}/node_modules/${dependency}`, { recursive: true, force: true, dereference: true }); } log(`Mixed in distro npm dependencies: ${mixinPath} ✔︎`); } function main() { log(`Mixing in distro npm dependencies...`); const mixinPaths = dirs.filter(d => /^.build\/distro\/npm/.test(d)); for (const mixinPath of mixinPaths) { mixin(mixinPath); } } main(); ================================================ FILE: build/azure-pipelines/distro/mixin-quality.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); function log(...args) { console.log(`[${new Date().toLocaleTimeString('en', { hour12: false })}]`, '[distro]', ...args); } function main() { const quality = process.env['VSCODE_QUALITY']; if (!quality) { throw new Error('Missing VSCODE_QUALITY, skipping mixin'); } log(`Mixing in distro quality...`); const basePath = `.build/distro/mixin/${quality}`; for (const name of fs_1.default.readdirSync(basePath)) { const distroPath = path_1.default.join(basePath, name); const ossPath = path_1.default.relative(basePath, distroPath); if (ossPath === 'product.json') { const distro = JSON.parse(fs_1.default.readFileSync(distroPath, 'utf8')); const oss = JSON.parse(fs_1.default.readFileSync(ossPath, 'utf8')); let builtInExtensions = oss.builtInExtensions; if (Array.isArray(distro.builtInExtensions)) { log('Overwriting built-in extensions:', distro.builtInExtensions.map(e => e.name)); builtInExtensions = distro.builtInExtensions; } else if (distro.builtInExtensions) { const include = distro.builtInExtensions['include'] ?? []; const exclude = distro.builtInExtensions['exclude'] ?? []; log('OSS built-in extensions:', builtInExtensions.map(e => e.name)); log('Including built-in extensions:', include.map(e => e.name)); log('Excluding built-in extensions:', exclude); builtInExtensions = builtInExtensions.filter(ext => !include.find(e => e.name === ext.name) && !exclude.find(name => name === ext.name)); builtInExtensions = [...builtInExtensions, ...include]; log('Final built-in extensions:', builtInExtensions.map(e => e.name)); } else { log('Inheriting OSS built-in extensions', builtInExtensions.map(e => e.name)); } const result = { webBuiltInExtensions: oss.webBuiltInExtensions, ...distro, builtInExtensions }; fs_1.default.writeFileSync(ossPath, JSON.stringify(result, null, '\t'), 'utf8'); } else { fs_1.default.cpSync(distroPath, ossPath, { force: true, recursive: true }); } log(distroPath, '✔︎'); } } main(); //# sourceMappingURL=mixin-quality.js.map ================================================ FILE: build/azure-pipelines/distro/mixin-quality.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; interface IBuiltInExtension { readonly name: string; readonly version: string; readonly repo: string; readonly metadata: any; } interface OSSProduct { readonly builtInExtensions: IBuiltInExtension[]; readonly webBuiltInExtensions?: IBuiltInExtension[]; } interface Product { readonly builtInExtensions?: IBuiltInExtension[] | { 'include'?: IBuiltInExtension[]; 'exclude'?: string[] }; readonly webBuiltInExtensions?: IBuiltInExtension[]; } function log(...args: any[]): void { console.log(`[${new Date().toLocaleTimeString('en', { hour12: false })}]`, '[distro]', ...args); } function main() { const quality = process.env['VSCODE_QUALITY']; if (!quality) { throw new Error('Missing VSCODE_QUALITY, skipping mixin'); } log(`Mixing in distro quality...`); const basePath = `.build/distro/mixin/${quality}`; for (const name of fs.readdirSync(basePath)) { const distroPath = path.join(basePath, name); const ossPath = path.relative(basePath, distroPath); if (ossPath === 'product.json') { const distro = JSON.parse(fs.readFileSync(distroPath, 'utf8')) as Product; const oss = JSON.parse(fs.readFileSync(ossPath, 'utf8')) as OSSProduct; let builtInExtensions = oss.builtInExtensions; if (Array.isArray(distro.builtInExtensions)) { log('Overwriting built-in extensions:', distro.builtInExtensions.map(e => e.name)); builtInExtensions = distro.builtInExtensions; } else if (distro.builtInExtensions) { const include = distro.builtInExtensions['include'] ?? []; const exclude = distro.builtInExtensions['exclude'] ?? []; log('OSS built-in extensions:', builtInExtensions.map(e => e.name)); log('Including built-in extensions:', include.map(e => e.name)); log('Excluding built-in extensions:', exclude); builtInExtensions = builtInExtensions.filter(ext => !include.find(e => e.name === ext.name) && !exclude.find(name => name === ext.name)); builtInExtensions = [...builtInExtensions, ...include]; log('Final built-in extensions:', builtInExtensions.map(e => e.name)); } else { log('Inheriting OSS built-in extensions', builtInExtensions.map(e => e.name)); } const result = { webBuiltInExtensions: oss.webBuiltInExtensions, ...distro, builtInExtensions }; fs.writeFileSync(ossPath, JSON.stringify(result, null, '\t'), 'utf8'); } else { fs.cpSync(distroPath, ossPath, { force: true, recursive: true }); } log(distroPath, '✔︎'); } } main(); ================================================ FILE: build/azure-pipelines/distro-build.yml ================================================ pool: name: 1es-ubuntu-22.04-x64 os: linux trigger: branches: include: ["main", "release/*"] pr: none steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - template: ./distro/download-distro.yml@self ================================================ FILE: build/azure-pipelines/linux/.gitignore ================================================ pat ================================================ FILE: build/azure-pipelines/linux/apt-retry.sh ================================================ #!/bin/sh ################################################################################ ## Copied from https://github.com/actions/runner-images/blob/ubuntu22/20240825.1/images/ubuntu/scripts/build/configure-apt-mock.sh ################################################################################ i=1 while [ $i -le 30 ];do err=$(mktemp) "$@" 2>$err # no errors, break the loop and continue normal flow test -f $err || break cat $err >&2 retry=false if grep -q 'Could not get lock' $err;then # apt db locked needs retry retry=true elif grep -q 'Could not open file /var/lib/apt/lists' $err;then # apt update is not completed, needs retry retry=true elif grep -q 'IPC connect call failed' $err;then # the delay should help with gpg-agent not ready retry=true elif grep -q 'Temporary failure in name resolution' $err;then # It looks like DNS is not updated with random generated hostname yet retry=true elif grep -q 'dpkg frontend is locked by another process' $err;then # dpkg process is busy by another process retry=true fi rm $err if [ $retry = false ]; then break fi sleep 5 echo "...retry $i" i=$((i + 1)) done ================================================ FILE: build/azure-pipelines/linux/cli-build-linux.yml ================================================ parameters: - name: VSCODE_BUILD_LINUX type: boolean default: false - name: VSCODE_BUILD_LINUX_ARM64 type: boolean default: false - name: VSCODE_BUILD_LINUX_ARMHF type: boolean default: false - name: VSCODE_CHECK_ONLY type: boolean default: false - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 displayName: Download openssl prebuilt inputs: command: custom customCommand: pack @vscode-internal/openssl-prebuilt@0.0.11 customRegistry: useFeed customFeed: "Monaco/openssl-prebuilt" workingDir: $(Build.ArtifactStagingDirectory) - script: | set -e mkdir $(Build.ArtifactStagingDirectory)/openssl tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/setup-npm-registry.js $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies - script: | set -e mkdir -p $(Build.SourcesDirectory)/.build displayName: Create .build folder for misc dependencies - template: ../cli/install-rust-posix.yml@self parameters: targets: - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - aarch64-unknown-linux-gnu - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - x86_64-unknown-linux-gnu - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - armv7-unknown-linux-gnueabihf - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-unknown-linux-gnu VSCODE_CLI_ARTIFACT: vscode_cli_linux_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/include SYSROOT_ARCH: arm64 - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-unknown-linux-gnu VSCODE_CLI_ARTIFACT: vscode_cli_linux_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/include SYSROOT_ARCH: amd64 - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: armv7-unknown-linux-gnueabihf VSCODE_CLI_ARTIFACT: vscode_cli_linux_armhf_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm-linux/include SYSROOT_ARCH: armhf - ${{ if not(parameters.VSCODE_CHECK_ONLY) }}: - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/vscode_cli_linux_armhf_cli.tar.gz artifactName: vscode_cli_linux_armhf_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Linux armhf CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish vscode_cli_linux_armhf_cli artifact - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/vscode_cli_linux_x64_cli.tar.gz artifactName: vscode_cli_linux_x64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Linux x64 CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish vscode_cli_linux_x64_cli artifact - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/vscode_cli_linux_arm64_cli.tar.gz artifactName: vscode_cli_linux_arm64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Linux arm64 CLI" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish vscode_cli_linux_arm64_cli artifact ================================================ FILE: build/azure-pipelines/linux/product-build-linux-test.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean - name: PUBLISH_TASK_NAME type: string default: PublishPipelineArtifact@0 steps: - script: npm exec -- npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) ELECTRON_ROOT=.build/electron sudo chown root $APP_ROOT/chrome-sandbox sudo chown root $ELECTRON_ROOT/chrome-sandbox sudo chmod 4755 $APP_ROOT/chrome-sandbox sudo chmod 4755 $ELECTRON_ROOT/chrome-sandbox stat $APP_ROOT/chrome-sandbox stat $ELECTRON_ROOT/chrome-sandbox displayName: Change setuid helper binary permission - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test.sh --tfs "Unit Tests" env: DISPLAY: ":10" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - script: npm run test-node displayName: Run unit tests (node.js) timeoutInMinutes: 15 - script: npm run test-browser-no-install -- --browser chromium --tfs "Browser Unit Tests" env: DEBUG: "*browser*" displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 15 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test.sh --build --tfs "Unit Tests" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - script: npm run test-node -- --build displayName: Run unit tests (node.js) timeoutInMinutes: 15 - script: npm run test-browser-no-install -- --build --browser chromium --tfs "Browser Unit Tests" env: DEBUG: "*browser*" displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 15 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - script: | set -e npm run gulp \ compile-extension:configuration-editing \ compile-extension:css-language-features-server \ compile-extension:emmet \ compile-extension:git \ compile-extension:github-authentication \ compile-extension:html-language-features-server \ compile-extension:ipynb \ compile-extension:notebook-renderers \ compile-extension:json-language-features-server \ compile-extension:markdown-language-features \ compile-extension-media \ compile-extension:microsoft-authentication \ compile-extension:typescript-language-features \ compile-extension:vscode-api-tests \ compile-extension:vscode-colorize-tests \ compile-extension:vscode-colorize-perf-tests \ compile-extension:vscode-test-resolver displayName: Build integration tests - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: ./scripts/test-integration.sh --tfs "Integration Tests" env: DISPLAY: ":10" displayName: Run integration tests (Electron) timeoutInMinutes: 20 - script: ./scripts/test-web-integration.sh --browser chromium displayName: Run integration tests (Browser, Chromium) timeoutInMinutes: 20 - script: ./scripts/test-remote-integration.sh displayName: Run integration tests (Remote) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | # Figure out the full absolute path of the product we just built # including the remote server and configure the integration tests # to run with these builds instead of running out of sources. set -e APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") INTEGRATION_TEST_APP_NAME="$APP_NAME" \ INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ ./scripts/test-integration.sh --build --tfs "Integration Tests" env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) displayName: Run integration tests (Electron) timeoutInMinutes: 20 - script: ./scripts/test-web-integration.sh --browser chromium env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)-web displayName: Run integration tests (Browser, Chromium) timeoutInMinutes: 20 - script: | set -e APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") INTEGRATION_TEST_APP_NAME="$APP_NAME" \ INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ ./scripts/test-remote-integration.sh env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) displayName: Run integration tests (Remote) timeoutInMinutes: 20 - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - script: | set -e ps -ef cat /proc/sys/fs/inotify/max_user_watches lsof | wc -l displayName: Diagnostics before smoke test run (processes, max_user_watches, number of opened file handles) continueOnError: true condition: succeededOrFailed() - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: npm run compile workingDirectory: test/smoke displayName: Compile smoke tests - script: npm run gulp compile-extension:markdown-language-features compile-extension:ipynb compile-extension-media compile-extension:vscode-test-resolver displayName: Build extensions for smoke tests - script: npm run gulp node displayName: Download node.js for remote smoke tests retryCountOnTaskFailure: 3 - script: npm run smoketest-no-compile -- --tracing timeoutInMinutes: 20 displayName: Run smoke tests (Electron) - script: npm run smoketest-no-compile -- --web --tracing --headless --electronArgs="--disable-dev-shm-usage" timeoutInMinutes: 20 displayName: Run smoke tests (Browser, Chromium) - script: npm run smoketest-no-compile -- --remote --tracing timeoutInMinutes: 20 displayName: Run smoke tests (Remote) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: npm run smoketest-no-compile -- --tracing --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" timeoutInMinutes: 20 displayName: Run smoke tests (Electron) - script: npm run smoketest-no-compile -- --web --tracing --headless --electronArgs="--disable-dev-shm-usage" env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)-web timeoutInMinutes: 20 displayName: Run smoke tests (Browser, Chromium) - script: | set -e npm run gulp compile-extension:vscode-test-resolver APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)" \ npm run smoketest-no-compile -- --tracing --remote --build "$APP_PATH" timeoutInMinutes: 20 displayName: Run smoke tests (Remote) - script: | set -e ps -ef cat /proc/sys/fs/inotify/max_user_watches lsof | wc -l displayName: Diagnostics after smoke test run (processes, max_user_watches, number of opened file handles) continueOnError: true condition: succeededOrFailed() - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: .build/crashes ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: crash-dump-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: crash-dump-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: crash-dump-linux-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Crash Reports" continueOnError: true condition: failed() # In order to properly symbolify above crash reports # (if any), we need the compiled native modules too - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: node_modules ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: node-modules-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: node-modules-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: node-modules-linux-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Node Modules" continueOnError: true condition: failed() - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: .build/logs ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: logs-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: logs-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: logs-linux-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Log Files" continueOnError: true condition: succeededOrFailed() - task: PublishTestResults@2 displayName: Publish Tests Results inputs: testResultsFiles: "*-results.xml" searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" condition: succeededOrFailed() ================================================ FILE: build/azure-pipelines/linux/product-build-linux.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_CIBUILD type: boolean - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean - name: VSCODE_ARCH type: string steps: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - checkout: self fetchDepth: 1 retryCountOnTaskFailure: 3 - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - task: DownloadPipelineArtifact@2 inputs: artifact: Compilation path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - script: | set -e # Start X server ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get update ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get install -y pkg-config \ dbus \ xvfb \ libgtk-3-0 \ libxkbfile-dev \ libkrb5-dev \ libgbm1 \ rpm sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb sudo chmod +x /etc/init.d/xvfb sudo update-rc.d xvfb defaults sudo service xvfb start # Start dbus session sudo mkdir -p /var/run/dbus DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address) echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT" displayName: Setup system services - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js linux $VSCODE_ARCH > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) # Step will be used by both Install dependencies and building rpm package, # hence avoid adding it behind NODE_MODULES_RESTORED condition. - script: | set -e SYSROOT_ARCH=$VSCODE_ARCH if [ "$SYSROOT_ARCH" == "x64" ]; then SYSROOT_ARCH="amd64" fi export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots SYSROOT_ARCH="$SYSROOT_ARCH" node -e '(async () => { const { getVSCodeSysroot } = require("./build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' env: VSCODE_ARCH: $(VSCODE_ARCH) GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download vscode sysroots - ${{ if or(eq(parameters.VSCODE_ARCH, 'arm64'), eq(parameters.VSCODE_ARCH, 'armhf')) }}: - script: | set -e includes=$(cat << 'EOF' { "target_defaults": { "conditions": [ ["OS=='linux'", { 'cflags_cc!': [ '-std=gnu++20' ], 'cflags_cc': [ '-std=gnu++2a' ], }] ] } } EOF ) if [ ! -d "$HOME/.gyp" ]; then mkdir -p "$HOME/.gyp" fi echo "$includes" > "$HOME/.gyp/include.gypi" displayName: Override gnu target for arm64 and arm - script: | set -e source ./build/azure-pipelines/linux/setup-env.sh for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: npm_config_arch: $(NPM_ARCH) VSCODE_ARCH: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: ../common/install-builtin-extensions.yml@self - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e npm run gulp vscode-linux-$(VSCODE_ARCH)-min-ci ARCHIVE_PATH=".build/linux/client/code-${{ parameters.VSCODE_QUALITY }}-$(VSCODE_ARCH)-$(date +%s).tar.gz" mkdir -p $(dirname $ARCHIVE_PATH) echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: - task: DownloadPipelineArtifact@2 inputs: artifact: $(ARTIFACT_PREFIX)vscode_cli_linux_$(VSCODE_ARCH)_cli patterns: "**" path: $(Build.ArtifactStagingDirectory)/cli displayName: Download VS Code CLI - script: | set -e tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(Build.ArtifactStagingDirectory)/cli CLI_APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").tunnelApplicationName") APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").applicationName") mv $(Build.ArtifactStagingDirectory)/cli/$APP_NAME $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$CLI_APP_NAME displayName: Mix in CLI - script: | set -e tar -czf $CLIENT_PATH -C .. VSCode-linux-$(VSCODE_ARCH) env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Archive client - script: | set -e npm run gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH) # TODO@joaomoreno ARCHIVE_PATH=".build/linux/server/vscode-server-linux-$(VSCODE_ARCH).tar.gz" UNARCHIVE_PATH="`pwd`/../vscode-server-linux-$(VSCODE_ARCH)" mkdir -p $(dirname $ARCHIVE_PATH) tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH) echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" echo "##vso[task.setvariable variable=SERVER_UNARCHIVE_PATH]$UNARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - script: | set -e npm run gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-web-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH)-web # TODO@joaomoreno ARCHIVE_PATH=".build/linux/web/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz" mkdir -p $(dirname $ARCHIVE_PATH) tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH)-web echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) - ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: - script: | set -e EXPECTED_GLIBC_VERSION="2.28" \ EXPECTED_GLIBCXX_VERSION="3.4.25" \ ./build/azure-pipelines/linux/verify-glibc-requirements.sh env: SEARCH_PATH: $(SERVER_UNARCHIVE_PATH) npm_config_arch: $(NPM_ARCH) VSCODE_ARCH: $(VSCODE_ARCH) displayName: Check GLIBC and GLIBCXX dependencies in server archive - ${{ else }}: - script: | set -e EXPECTED_GLIBC_VERSION="2.28" \ EXPECTED_GLIBCXX_VERSION="3.4.26" \ ./build/azure-pipelines/linux/verify-glibc-requirements.sh env: SEARCH_PATH: $(SERVER_UNARCHIVE_PATH) npm_config_arch: $(NPM_ARCH) VSCODE_ARCH: $(VSCODE_ARCH) displayName: Check GLIBC and GLIBCXX dependencies in server archive - ${{ else }}: - script: npm run gulp "transpile-client-esbuild" "transpile-extensions" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Transpile client and extensions - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - template: product-build-linux-test.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1 - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - script: | set -e npm run gulp "vscode-linux-$(VSCODE_ARCH)-prepare-deb" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Prepare deb package - script: | set -e npm run gulp "vscode-linux-$(VSCODE_ARCH)-build-deb" file_output=$(file $(ls .build/linux/deb/*/deb/*.deb)) if [[ "$file_output" != *"data compression xz"* ]]; then echo "Error: unknown compression. $file_output" exit 1 fi echo "##vso[task.setvariable variable=DEB_PATH]$(ls .build/linux/deb/*/deb/*.deb)" displayName: Build deb package - script: | set -e TRIPLE="" if [ "$VSCODE_ARCH" == "x64" ]; then TRIPLE="x86_64-linux-gnu" elif [ "$VSCODE_ARCH" == "arm64" ]; then TRIPLE="aarch64-linux-gnu" elif [ "$VSCODE_ARCH" == "armhf" ]; then TRIPLE="arm-rpi-linux-gnueabihf" fi export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots export STRIP="$VSCODE_SYSROOT_DIR/$TRIPLE/$TRIPLE/bin/strip" npm run gulp "vscode-linux-$(VSCODE_ARCH)-prepare-rpm" env: VSCODE_ARCH: $(VSCODE_ARCH) displayName: Prepare rpm package - script: | set -e npm run gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" echo "##vso[task.setvariable variable=RPM_PATH]$(ls .build/linux/rpm/*/*.rpm)" displayName: Build rpm package - script: | set -e npm run gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap" ARCHIVE_PATH=".build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz" mkdir -p $(dirname $ARCHIVE_PATH) tar -czf $ARCHIVE_PATH -C .build/linux snap echo "##vso[task.setvariable variable=SNAP_PATH]$ARCHIVE_PATH" displayName: Prepare snap package - task: UseDotNet@2 inputs: version: 6.x - task: EsrpCodeSigning@5 inputs: UseMSIAuthentication: true ConnectedServiceName: vscode-esrp AppRegistrationClientId: $(ESRP_CLIENT_ID) AppRegistrationTenantId: $(ESRP_TENANT_ID) AuthAKVName: vscode-esrp AuthSignCertName: esrp-sign FolderPath: . Pattern: noop displayName: 'Install ESRP Tooling' - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll sign-pgp .build/linux/deb '*.deb' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign deb - script: node build/azure-pipelines/common/sign $(Agent.RootDirectory)/_tasks/EsrpCodeSigning_*/*/net6.0/esrpcli.dll sign-pgp .build/linux/rpm '*.rpm' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign rpm - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) displayName: Generate artifact prefix - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(CLIENT_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-linux-$(VSCODE_ARCH) sbomPackageName: "VS Code Linux $(VSCODE_ARCH) (unsigned)" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish client archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SERVER_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH) sbomPackageName: "VS Code Linux $(VSCODE_ARCH) Server" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web sbomPackageName: "VS Code Linux $(VSCODE_ARCH) Web" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(DEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_deb-package sbomBuildDropPath: .build/linux/deb sbomPackageName: "VS Code Linux $(VSCODE_ARCH) DEB" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['DEB_PATH'], '')) displayName: Publish deb package - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(RPM_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_rpm-package sbomBuildDropPath: .build/linux/rpm sbomPackageName: "VS Code Linux $(VSCODE_ARCH) RPM" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['RPM_PATH'], '')) displayName: Publish rpm package - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SNAP_PATH) artifactName: $(ARTIFACT_PREFIX)snap-$(VSCODE_ARCH) sbomEnabled: false condition: and(succeededOrFailed(), ne(variables['SNAP_PATH'], '')) displayName: Publish snap pre-package ================================================ FILE: build/azure-pipelines/linux/setup-env.sh ================================================ #!/usr/bin/env bash set -e SYSROOT_ARCH=$VSCODE_ARCH if [ "$SYSROOT_ARCH" == "x64" ]; then SYSROOT_ARCH="amd64" fi export VSCODE_SYSROOT_DIR=$PWD/.build/sysroots if [ -d "$VSCODE_SYSROOT_DIR" ]; then echo "Using cached sysroot" else echo "Downloading sysroot" SYSROOT_ARCH="$SYSROOT_ARCH" node -e '(async () => { const { getVSCodeSysroot } = require("./build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' fi if [ "$npm_config_arch" == "x64" ]; then # Download clang based on chromium revision used by vscode curl -s https://raw.githubusercontent.com/chromium/chromium/132.0.6834.210/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux # Download libcxx headers and objects from upstream electron releases DEBUG=libcxx-fetcher \ VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \ VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \ VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \ VSCODE_ARCH="$npm_config_arch" \ node build/linux/libcxx-fetcher.js # Set compiler toolchain # Flags for the client build are based on # https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/arm.gni # https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/compiler/BUILD.gn # https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:build/config/c++/BUILD.gn export CC="$PWD/.build/CR_Clang/bin/clang --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu" export CXX="$PWD/.build/CR_Clang/bin/clang++ --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu" export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -DSPDLOG_USE_STD_FORMAT -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" export LDFLAGS="-stdlib=libc++ --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu -Wl,--lto-O0" # Set compiler toolchain for remote server export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-g++ export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu" elif [ "$npm_config_arch" == "arm64" ]; then # Set compiler toolchain for client native modules export CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc export CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu" # Set compiler toolchain for remote server export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu" elif [ "$npm_config_arch" == "arm" ]; then # Set compiler toolchain for client native modules export CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc export CXX=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++ export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-linux-gnueabihf -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/lib/arm-linux-gnueabihf" # Set compiler toolchain for remote server export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++ export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-linux-gnueabihf -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/lib/arm-linux-gnueabihf" fi ================================================ FILE: build/azure-pipelines/linux/snap-build-linux.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: DownloadPipelineArtifact@2 displayName: "Download Pipeline Artifact" inputs: artifact: snap-$(VSCODE_ARCH) path: .build/linux/snap-tarball - script: | set -e # Get snapcraft version snapcraft --version # Make sure we get latest packages sudo apt-get update sudo apt-get upgrade -y sudo apt-get install -y curl apt-transport-https ca-certificates # Define variables SNAP_ROOT="$(pwd)/.build/linux/snap/$(VSCODE_ARCH)" # Unpack snap tarball artifact, in order to preserve file perms (cd .build/linux && tar -xzf snap-tarball/snap-$(VSCODE_ARCH).tar.gz) # Create snap package BUILD_VERSION="$(date +%s)" SNAP_FILENAME="code-$VSCODE_QUALITY-$(VSCODE_ARCH)-$BUILD_VERSION.snap" SNAP_PATH="$SNAP_ROOT/$SNAP_FILENAME" case $(VSCODE_ARCH) in x64) SNAPCRAFT_TARGET_ARGS="" ;; *) SNAPCRAFT_TARGET_ARGS="--target-arch $(VSCODE_ARCH)" ;; esac (cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft snap $SNAPCRAFT_TARGET_ARGS --output "$SNAP_PATH") displayName: Prepare for publish - script: | set -e SNAP_ROOT="$(pwd)/.build/linux/snap/$(VSCODE_ARCH)" SNAP_EXTRACTED_PATH=$(find $SNAP_ROOT -maxdepth 1 -type d -name 'code-*') SNAP_PATH=$(find $SNAP_ROOT -maxdepth 1 -type f -name '*.snap') # SBOM tool doesn't like recursive symlinks sudo find $SNAP_EXTRACTED_PATH -type l -delete echo "##vso[task.setvariable variable=SNAP_EXTRACTED_PATH]$SNAP_EXTRACTED_PATH" echo "##vso[task.setvariable variable=SNAP_PATH]$SNAP_PATH" target: container: host displayName: Find host snap path & prepare for SBOM - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SNAP_PATH) artifactName: vscode_client_linux_$(VSCODE_ARCH)_snap sbomBuildDropPath: $(SNAP_EXTRACTED_PATH) sbomPackageName: "VS Code Linux $(VSCODE_ARCH) SNAP" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish snap package ================================================ FILE: build/azure-pipelines/linux/verify-glibc-requirements.sh ================================================ #!/usr/bin/env bash set -e TRIPLE="x86_64-linux-gnu" if [ "$VSCODE_ARCH" == "arm64" ]; then TRIPLE="aarch64-linux-gnu" elif [ "$VSCODE_ARCH" == "armhf" ]; then TRIPLE="arm-rpi-linux-gnueabihf" fi # Get all files with .node extension from server folder files=$(find $SEARCH_PATH -name "*.node" -not -path "*prebuilds*" -not -path "*extensions/node_modules/@parcel/watcher*" -o -type f -executable -name "node") echo "Verifying requirements for files: $files" for file in $files; do glibc_version="$EXPECTED_GLIBC_VERSION" glibcxx_version="$EXPECTED_GLIBCXX_VERSION" while IFS= read -r line; do if [[ $line == *"GLIBC_"* ]]; then version=$(echo "$line" | awk '{if ($5 ~ /^[0-9a-fA-F]+$/) print $6; else print $5}' | tr -d '()') version=${version#*_} if [[ $(printf "%s\n%s" "$version" "$glibc_version" | sort -V | tail -n1) == "$version" ]]; then glibc_version=$version fi elif [[ $line == *"GLIBCXX_"* ]]; then version=$(echo "$line" | awk '{if ($5 ~ /^[0-9a-fA-F]+$/) print $6; else print $5}' | tr -d '()') version=${version#*_} if [[ $(printf "%s\n%s" "$version" "$glibcxx_version" | sort -V | tail -n1) == "$version" ]]; then glibcxx_version=$version fi fi done < <("$PWD/.build/sysroots/$TRIPLE/$TRIPLE/bin/objdump" -T "$file") if [[ "$glibc_version" != "$EXPECTED_GLIBC_VERSION" ]]; then echo "Error: File $file has dependency on GLIBC > $EXPECTED_GLIBC_VERSION, found $glibc_version" exit 1 fi if [[ "$glibcxx_version" != "$EXPECTED_GLIBCXX_VERSION" ]]; then echo "Error: File $file has dependency on GLIBCXX > $EXPECTED_GLIBCXX_VERSION, found $glibcxx_version" exit 1 fi done ================================================ FILE: build/azure-pipelines/linux/xvfb.init ================================================ #!/bin/bash # # /etc/rc.d/init.d/xvfbd # # chkconfig: 345 95 28 # description: Starts/Stops X Virtual Framebuffer server # processname: Xvfb # ### BEGIN INIT INFO # Provides: xvfb # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start xvfb at boot time # Description: Enable xvfb provided by daemon. ### END INIT INFO [ "${NETWORKING}" = "no" ] && exit 0 PROG="/usr/bin/Xvfb" PROG_OPTIONS=":10 -ac -screen 0 1024x768x24" PROG_OUTPUT="/tmp/Xvfb.out" case "$1" in start) echo "Starting : X Virtual Frame Buffer " $PROG $PROG_OPTIONS>>$PROG_OUTPUT 2>&1 & disown -ar ;; stop) echo "Shutting down : X Virtual Frame Buffer" killproc $PROG RETVAL=$? [ $RETVAL -eq 0 ] && /bin/rm -f /var/lock/subsys/Xvfb /var/run/Xvfb.pid echo ;; restart|reload) $0 stop $0 start RETVAL=$? ;; status) status Xvfb RETVAL=$? ;; *) echo $"Usage: $0 (start|stop|restart|reload|status)" exit 1 esac exit $RETVAL ================================================ FILE: build/azure-pipelines/oss/product-build-pr-cache-linux.yml ================================================ steps: - checkout: self fetchDepth: 1 retryCountOnTaskFailure: 3 - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js linux $VSCODE_ARCH > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get update ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get install -y libkrb5-dev displayName: Setup system services condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive ================================================ FILE: build/azure-pipelines/oss/product-build-pr-cache-win32.yml ================================================ steps: - checkout: self fetchDepth: 1 retryCountOnTaskFailure: 3 - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - pwsh: | mkdir .build -ea 0 node build/azure-pipelines/common/computeNodeModulesCacheKey.js win32 $(VSCODE_ARCH) > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - powershell: 7z.exe x .build/node_modules_cache/cache.7z -aoa condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file exec { npm config set registry "$env:NPM_REGISTRY" } $NpmrcPath = (npm config get userconfig) echo "##vso[task.setvariable variable=NPMRC_PATH]$NpmrcPath" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm ci } env: npm_config_arch: $(VSCODE_ARCH) npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" retryCountOnTaskFailure: 5 displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt } exec { mkdir -Force .build/node_modules_cache } exec { 7z.exe a .build/node_modules_cache/cache.7z -mx3 `@.build/node_modules_list.txt } condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive ================================================ FILE: build/azure-pipelines/product-build-pr.yml ================================================ trigger: - main - release/* pr: branches: include: ["main", "release/*"] variables: - name: Codeql.SkipTaskAutoInjection value: true - name: skipComponentGovernanceDetection value: true - name: NPM_REGISTRY value: "none" - name: CARGO_REGISTRY value: "none" - name: VSCODE_CIBUILD value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - name: VSCODE_QUALITY value: oss - name: VSCODE_STEP_ON_IT value: false jobs: - ${{ if ne(variables['VSCODE_CIBUILD'], true) }}: - job: Compile displayName: Compile & Hygiene pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 steps: - template: product-compile.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - job: Linuxx64UnitTest displayName: Linux (Unit Tests) pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: true VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64IntegrationTest displayName: Linux (Integration Tests) pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: true VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64SmokeTest displayName: Linux (Smoke Tests) pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: true - job: LinuxCLI displayName: Linux (CLI) pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 steps: - template: cli/test.yml@self - job: Windowsx64UnitTests displayName: Windows (Unit Tests) pool: 1es-oss-windows-2022-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 steps: - template: win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: true VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: Windowsx64IntegrationTests displayName: Windows (Integration Tests) pool: 1es-oss-windows-2022-x64 timeoutInMinutes: 60 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 steps: - template: win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: true VSCODE_RUN_SMOKE_TESTS: false # - job: Windowsx64SmokeTests # displayName: Windows (Smoke Tests) # pool: 1es-oss-windows-2022-x64 # timeoutInMinutes: 30 # variables: # VSCODE_ARCH: x64 # NPM_ARCH: x64 # steps: # - template: win32/product-build-win32.yml@self # parameters: # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} # VSCODE_ARCH: x64 # VSCODE_RUN_UNIT_TESTS: false # VSCODE_RUN_INTEGRATION_TESTS: false # VSCODE_RUN_SMOKE_TESTS: true - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - job: Linuxx64MaintainNodeModulesCache displayName: Linux (Maintain node_modules cache) pool: 1es-oss-ubuntu-22.04-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 steps: - template: oss/product-build-pr-cache-linux.yml@self - job: Windowsx64MaintainNodeModulesCache displayName: Windows (Maintain node_modules cache) pool: 1es-oss-windows-2022-x64 timeoutInMinutes: 30 variables: VSCODE_ARCH: x64 steps: - template: oss/product-build-pr-cache-win32.yml@self # - job: macOSUnitTest # displayName: macOS (Unit Tests) # pool: # vmImage: macOS-11 # timeoutInMinutes: 60 # variables: # BUILDSECMON_OPT_IN: true # VSCODE_ARCH: x64 # steps: # - template: darwin/product-build-darwin.yml@self # parameters: # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} # VSCODE_RUN_UNIT_TESTS: true # VSCODE_RUN_INTEGRATION_TESTS: false # VSCODE_RUN_SMOKE_TESTS: false # - job: macOSIntegrationTest # displayName: macOS (Integration Tests) # pool: # vmImage: macOS-11 # timeoutInMinutes: 60 # variables: # BUILDSECMON_OPT_IN: true # VSCODE_ARCH: x64 # steps: # - template: darwin/product-build-darwin.yml@self # parameters: # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} # VSCODE_RUN_UNIT_TESTS: false # VSCODE_RUN_INTEGRATION_TESTS: true # VSCODE_RUN_SMOKE_TESTS: false # - job: macOSSmokeTest # displayName: macOS (Smoke Tests) # pool: # vmImage: macOS-11 # timeoutInMinutes: 60 # variables: # BUILDSECMON_OPT_IN: true # VSCODE_ARCH: x64 # steps: # - template: darwin/product-build-darwin.yml@self # parameters: # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} # VSCODE_RUN_UNIT_TESTS: false # VSCODE_RUN_INTEGRATION_TESTS: false # VSCODE_RUN_SMOKE_TESTS: true ================================================ FILE: build/azure-pipelines/product-build.yml ================================================ pr: none schedules: - cron: "0 5 * * Mon-Fri" displayName: Mon-Fri at 7:00 branches: include: - main trigger: batch: true branches: include: ["main", "release/*"] parameters: - name: VSCODE_QUALITY displayName: Quality type: string default: insider values: - exploration - insider - stable - name: NPM_REGISTRY displayName: "Custom NPM Registry" type: string default: 'https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/npm/registry/' - name: CARGO_REGISTRY displayName: "Custom Cargo Registry" type: string default: 'sparse+https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/Cargo/index/' - name: VSCODE_BUILD_WIN32 displayName: "🎯 Windows x64" type: boolean default: true - name: VSCODE_BUILD_WIN32_ARM64 displayName: "🎯 Windows arm64" type: boolean default: true - name: VSCODE_BUILD_LINUX displayName: "🎯 Linux x64" type: boolean default: true - name: VSCODE_BUILD_LINUX_ARM64 displayName: "🎯 Linux arm64" type: boolean default: true - name: VSCODE_BUILD_LINUX_ARMHF displayName: "🎯 Linux armhf" type: boolean default: true - name: VSCODE_BUILD_ALPINE displayName: "🎯 Alpine x64" type: boolean default: true - name: VSCODE_BUILD_ALPINE_ARM64 displayName: "🎯 Alpine arm64" type: boolean default: true - name: VSCODE_BUILD_MACOS displayName: "🎯 macOS x64" type: boolean default: true - name: VSCODE_BUILD_MACOS_ARM64 displayName: "🎯 macOS arm64" type: boolean default: true - name: VSCODE_BUILD_MACOS_UNIVERSAL displayName: "🎯 macOS universal" type: boolean default: true - name: VSCODE_BUILD_WEB displayName: "🎯 Web" type: boolean default: true - name: VSCODE_PUBLISH displayName: "Publish to builds.code.visualstudio.com" type: boolean default: true - name: VSCODE_RELEASE displayName: "Release build if successful" type: boolean default: false - name: VSCODE_COMPILE_ONLY displayName: "Run Compile stage exclusively" type: boolean default: false - name: VSCODE_STEP_ON_IT displayName: "Skip tests" type: boolean default: false variables: - name: VSCODE_PRIVATE_BUILD value: ${{ ne(variables['Build.Repository.Uri'], 'https://github.com/microsoft/vscode.git') }} - name: NPM_REGISTRY ${{ if in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }}: # disable terrapin when in VSCODE_CIBUILD value: none ${{ else }}: value: ${{ parameters.NPM_REGISTRY }} - name: CARGO_REGISTRY value: ${{ parameters.CARGO_REGISTRY }} - name: VSCODE_QUALITY value: ${{ parameters.VSCODE_QUALITY }} - name: VSCODE_BUILD_STAGE_WINDOWS value: ${{ or(eq(parameters.VSCODE_BUILD_WIN32, true), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }} - name: VSCODE_BUILD_STAGE_LINUX value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }} - name: VSCODE_BUILD_STAGE_ALPINE value: ${{ or(eq(parameters.VSCODE_BUILD_ALPINE, true), eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true)) }} - name: VSCODE_BUILD_STAGE_MACOS value: ${{ or(eq(parameters.VSCODE_BUILD_MACOS, true), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }} - name: VSCODE_BUILD_STAGE_WEB value: ${{ eq(parameters.VSCODE_BUILD_WEB, true) }} - name: VSCODE_CIBUILD value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - name: VSCODE_PUBLISH value: ${{ and(eq(parameters.VSCODE_PUBLISH, true), eq(variables.VSCODE_CIBUILD, false), eq(parameters.VSCODE_COMPILE_ONLY, false)) }} - name: VSCODE_SCHEDULEDBUILD value: ${{ eq(variables['Build.Reason'], 'Schedule') }} - name: VSCODE_STEP_ON_IT value: ${{ eq(parameters.VSCODE_STEP_ON_IT, true) }} - name: VSCODE_BUILD_MACOS_UNIVERSAL value: ${{ and(eq(parameters.VSCODE_BUILD_MACOS, true), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true), eq(parameters.VSCODE_BUILD_MACOS_UNIVERSAL, true)) }} - name: VSCODE_STAGING_BLOB_STORAGE_ACCOUNT_NAME value: vscodeesrp - name: PRSS_CDN_URL value: https://vscode.download.prss.microsoft.com/dbazure/download - name: VSCODE_ESRP_SERVICE_CONNECTION_ID value: fe07e6ce-6ffb-4df9-8d27-d129523a3f3e - name: VSCODE_ESRP_TENANT_ID value: 975f013f-7f24-47e8-a7d3-abc4752bf346 - name: VSCODE_ESRP_CLIENT_ID value: 4ac7ed59-b5e9-4f66-9c30-8d1afa72d32d - name: ESRP_TENANT_ID value: 975f013f-7f24-47e8-a7d3-abc4752bf346 - name: ESRP_CLIENT_ID value: c24324f7-e65f-4c45-8702-ed2d4c35df99 - name: AZURE_DOCUMENTDB_ENDPOINT value: https://vscode.documents.azure.com/ - name: VSCODE_MIXIN_REPO value: microsoft/vscode-distro - name: skipComponentGovernanceDetection value: true - name: ComponentDetection.Timeout value: 600 - name: Codeql.SkipTaskAutoInjection value: true - name: ARTIFACT_PREFIX value: '' name: "$(Date:yyyyMMdd).$(Rev:r) (${{ parameters.VSCODE_QUALITY }})" resources: pipelines: - pipeline: vscode-7pm-kick-off source: 'VS Code 7PM Kick-Off' trigger: true repositories: - repository: 1ESPipelines type: git name: 1ESPipelineTemplates/1ESPipelineTemplates ref: refs/tags/release extends: template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines parameters: sdl: tsa: enabled: true configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json binskim: analyzeTargetGlob: '+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.exe;+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.node;+:file|$(Agent.BuildDirectory)/VSCode-*/**/*.dll;-:file|$(Build.SourcesDirectory)/.build/**/system-setup/VSCodeSetup*.exe;-:file|$(Build.SourcesDirectory)/.build/**/user-setup/VSCodeUserSetup*.exe' codeql: runSourceLanguagesInSourceAnalysis: true compiled: enabled: false justificationForDisabling: "CodeQL breaks ESRP CodeSign on macOS (ICM #520035761, githubcustomers/microsoft-codeql-support#198)" credscan: suppressionsFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/CredScanSuppressions.json eslint: enabled: true enableExclusions: true exclusionsFilePath: $(Build.SourcesDirectory)/.eslint-ignore sourceAnalysisPool: 1es-windows-2022-x64 createAdoIssuesForJustificationsForDisablement: false containers: snapcraft: image: vscodehub.azurecr.io/vscode-linux-build-agent:snapcraft-x64 ubuntu-2004-arm64: image: onebranch.azurecr.io/linux/ubuntu-2004-arm64:latest stages: - stage: Compile jobs: - job: Compile timeoutInMinutes: 90 pool: name: AcesShared os: macOS variables: VSCODE_ARCH: arm64 steps: - template: build/azure-pipelines/product-compile.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true),eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true),eq(parameters.VSCODE_BUILD_LINUX_ARM64, true),eq(parameters.VSCODE_BUILD_ALPINE, true),eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true),eq(parameters.VSCODE_BUILD_MACOS, true),eq(parameters.VSCODE_BUILD_MACOS_ARM64, true),eq(parameters.VSCODE_BUILD_WIN32, true),eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - stage: CompileCLI dependsOn: [] jobs: - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - job: CLILinuxX64 pool: name: 1es-ubuntu-22.04-x64 os: linux steps: - template: build/azure-pipelines/linux/cli-build-linux.yml@self parameters: VSCODE_CHECK_ONLY: ${{ variables.VSCODE_CIBUILD }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_LINUX: ${{ parameters.VSCODE_BUILD_LINUX }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), or(eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true))) }}: - job: CLILinuxGnuARM pool: name: 1es-ubuntu-22.04-x64 os: linux steps: - template: build/azure-pipelines/linux/cli-build-linux.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_LINUX_ARMHF: ${{ parameters.VSCODE_BUILD_LINUX_ARMHF }} VSCODE_BUILD_LINUX_ARM64: ${{ parameters.VSCODE_BUILD_LINUX_ARM64 }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_ALPINE, true)) }}: - job: CLIAlpineX64 pool: name: 1es-ubuntu-22.04-x64 os: linux steps: - template: build/azure-pipelines/alpine/cli-build-alpine.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_ALPINE: ${{ parameters.VSCODE_BUILD_ALPINE }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true)) }}: - job: CLIAlpineARM64 pool: name: 1es-mariner-2.0-arm64 os: linux hostArchitecture: arm64 container: ubuntu-2004-arm64 templateContext: authenticatedContainerRegistries: - registry: onebranch.azurecr.io tenant: AME identity: 1ESPipelineIdentity steps: - template: build/azure-pipelines/alpine/cli-build-alpine.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_ALPINE_ARM64: ${{ parameters.VSCODE_BUILD_ALPINE_ARM64 }} - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: - job: CLIMacOSX64 pool: name: Azure Pipelines image: macOS-13 os: macOS variables: # todo@connor4312 to diagnose build flakes - name: MSRUSTUP_LOG value: debug steps: - template: build/azure-pipelines/darwin/cli-build-darwin.yml@self parameters: VSCODE_CHECK_ONLY: ${{ variables.VSCODE_CIBUILD }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}: - job: CLIMacOSARM64 pool: name: Azure Pipelines image: macOS-13 os: macOS variables: # todo@connor4312 to diagnose build flakes - name: MSRUSTUP_LOG value: debug steps: - template: build/azure-pipelines/darwin/cli-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_MACOS_ARM64: ${{ parameters.VSCODE_BUILD_MACOS_ARM64 }} - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - job: CLIWindowsX64 pool: name: 1es-windows-2019-x64 os: windows steps: - template: build/azure-pipelines/win32/cli-build-win32.yml@self parameters: VSCODE_CHECK_ONLY: ${{ variables.VSCODE_CIBUILD }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - job: CLIWindowsARM64 pool: name: 1es-windows-2019-x64 os: windows steps: - template: build/azure-pipelines/win32/cli-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false)) }}: - stage: APIScan dependsOn: [] pool: name: 1es-windows-2019-x64 os: windows jobs: - job: WindowsAPIScan steps: - template: build/azure-pipelines/win32/sdl-scan-win32.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WINDOWS'], true)) }}: - stage: Windows dependsOn: - Compile - ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true),eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true),eq(parameters.VSCODE_BUILD_LINUX_ARM64, true),eq(parameters.VSCODE_BUILD_ALPINE, true),eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true),eq(parameters.VSCODE_BUILD_MACOS, true),eq(parameters.VSCODE_BUILD_MACOS_ARM64, true),eq(parameters.VSCODE_BUILD_WIN32, true),eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - CompileCLI pool: name: 1es-windows-2019-x64 os: windows jobs: - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - job: WindowsUnitTests displayName: Unit Tests timeoutInMinutes: 60 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: true VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: WindowsIntegrationTests displayName: Integration Tests timeoutInMinutes: 60 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: true VSCODE_RUN_SMOKE_TESTS: false - job: WindowsSmokeTests displayName: Smoke Tests timeoutInMinutes: 60 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: true - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32, true)) }}: - job: Windows timeoutInMinutes: 120 variables: VSCODE_ARCH: x64 templateContext: sdl: suppression: suppressionFile: $(Build.SourcesDirectory)\.config\guardian\.gdnsuppress steps: - template: build/azure-pipelines/win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: x64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - job: WindowsCLISign timeoutInMinutes: 90 steps: - template: build/azure-pipelines/win32/product-build-win32-cli-sign.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }} VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - job: WindowsARM64 timeoutInMinutes: 90 variables: VSCODE_ARCH: arm64 templateContext: sdl: suppression: suppressionFile: $(Build.SourcesDirectory)\.config\guardian\.gdnsuppress steps: - template: build/azure-pipelines/win32/product-build-win32.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_ARCH: arm64 VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}: - stage: Linux dependsOn: - Compile - ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true),eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true),eq(parameters.VSCODE_BUILD_LINUX_ARM64, true),eq(parameters.VSCODE_BUILD_ALPINE, true),eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true),eq(parameters.VSCODE_BUILD_MACOS, true),eq(parameters.VSCODE_BUILD_MACOS_ARM64, true),eq(parameters.VSCODE_BUILD_WIN32, true),eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - CompileCLI pool: name: 1es-ubuntu-22.04-x64 os: linux jobs: - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - job: Linuxx64UnitTest displayName: Unit Tests variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: true VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64IntegrationTest displayName: Integration Tests variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: true VSCODE_RUN_SMOKE_TESTS: false - job: Linuxx64SmokeTest displayName: Smoke Tests variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: true - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true)) }}: - job: Linuxx64 timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 NPM_ARCH: x64 DISPLAY: ":10" steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: x64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true)) }}: - job: LinuxSnap dependsOn: - Linuxx64 container: snapcraft variables: VSCODE_ARCH: x64 templateContext: authenticatedContainerRegistries: - registry: onebranch.azurecr.io tenant: AME identity: 1ESPipelineIdentity steps: - template: build/azure-pipelines/linux/snap-build-linux.yml@self - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}: - job: LinuxArmhf variables: VSCODE_ARCH: armhf NPM_ARCH: arm steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: armhf VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}: - job: LinuxArm64 variables: VSCODE_ARCH: arm64 NPM_ARCH: arm64 steps: - template: build/azure-pipelines/linux/product-build-linux.yml@self parameters: VSCODE_ARCH: arm64 VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_ALPINE'], true)) }}: - stage: Alpine dependsOn: - Compile - ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true),eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true),eq(parameters.VSCODE_BUILD_LINUX_ARM64, true),eq(parameters.VSCODE_BUILD_ALPINE, true),eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true),eq(parameters.VSCODE_BUILD_MACOS, true),eq(parameters.VSCODE_BUILD_MACOS_ARM64, true),eq(parameters.VSCODE_BUILD_WIN32, true),eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - CompileCLI pool: name: 1es-ubuntu-22.04-x64 os: linux jobs: - ${{ if eq(parameters.VSCODE_BUILD_ALPINE, true) }}: - job: LinuxAlpine variables: VSCODE_ARCH: x64 NPM_ARCH: x64 steps: - template: build/azure-pipelines/alpine/product-build-alpine.yml@self - ${{ if eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true) }}: - job: LinuxAlpineArm64 timeoutInMinutes: 120 variables: VSCODE_ARCH: arm64 NPM_ARCH: arm64 steps: - template: build/azure-pipelines/alpine/product-build-alpine.yml@self - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_MACOS'], true)) }}: - stage: macOS dependsOn: - Compile - ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true),eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true),eq(parameters.VSCODE_BUILD_LINUX_ARM64, true),eq(parameters.VSCODE_BUILD_ALPINE, true),eq(parameters.VSCODE_BUILD_ALPINE_ARM64, true),eq(parameters.VSCODE_BUILD_MACOS, true),eq(parameters.VSCODE_BUILD_MACOS_ARM64, true),eq(parameters.VSCODE_BUILD_WIN32, true),eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - CompileCLI pool: name: Azure Pipelines image: macOS-13 os: macOS variables: BUILDSECMON_OPT_IN: true jobs: - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - job: macOSUnitTest displayName: Unit Tests timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: true VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: macOSIntegrationTest displayName: Integration Tests timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: true VSCODE_RUN_SMOKE_TESTS: false - job: macOSSmokeTest displayName: Smoke Tests timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: true - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS, true)) }}: - job: macOS timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - ${{ if eq(parameters.VSCODE_STEP_ON_IT, false) }}: - job: macOSTest timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - job: macOSSign dependsOn: - macOS timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/darwin/product-build-darwin-sign.yml@self - job: macOSCLISign timeoutInMinutes: 90 steps: - template: build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }} VSCODE_BUILD_MACOS_ARM64: ${{ parameters.VSCODE_BUILD_MACOS_ARM64 }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}: - job: macOSARM64 timeoutInMinutes: 90 variables: VSCODE_ARCH: arm64 steps: - template: build/azure-pipelines/darwin/product-build-darwin.yml@self parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} VSCODE_RUN_UNIT_TESTS: false VSCODE_RUN_INTEGRATION_TESTS: false VSCODE_RUN_SMOKE_TESTS: false - job: macOSARM64Sign dependsOn: - macOSARM64 timeoutInMinutes: 90 variables: VSCODE_ARCH: arm64 steps: - template: build/azure-pipelines/darwin/product-build-darwin-sign.yml@self - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(variables['VSCODE_BUILD_MACOS_UNIVERSAL'], true)) }}: - job: macOSUniversal dependsOn: - macOS - macOSARM64 timeoutInMinutes: 90 variables: VSCODE_ARCH: universal steps: - template: build/azure-pipelines/darwin/product-build-darwin-universal.yml@self - job: macOSUniversalSign dependsOn: - macOSUniversal timeoutInMinutes: 90 variables: VSCODE_ARCH: universal steps: - template: build/azure-pipelines/darwin/product-build-darwin-sign.yml@self - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WEB'], true)) }}: - stage: Web dependsOn: - Compile pool: name: 1es-ubuntu-22.04-x64 os: linux jobs: - ${{ if eq(parameters.VSCODE_BUILD_WEB, true) }}: - job: Web variables: VSCODE_ARCH: x64 steps: - template: build/azure-pipelines/web/product-build-web.yml@self - ${{ if eq(variables['VSCODE_PUBLISH'], 'true') }}: - stage: Publish dependsOn: [] pool: name: 1es-windows-2019-x64 os: windows variables: - name: BUILDS_API_URL value: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ jobs: - job: PublishBuild timeoutInMinutes: 180 displayName: Publish Build steps: - template: build/azure-pipelines/product-publish.yml@self - ${{ if and(parameters.VSCODE_RELEASE, eq(variables['VSCODE_PRIVATE_BUILD'], false)) }}: - stage: ApproveRelease dependsOn: [] # run in parallel to compile stage pool: name: 1es-ubuntu-22.04-x64 os: linux jobs: - job: ApproveRelease displayName: "Approve Release" variables: - group: VSCodePeerApproval - name: skipComponentGovernanceDetection value: true - ${{ if or(and(parameters.VSCODE_RELEASE, eq(variables['VSCODE_PRIVATE_BUILD'], false)), and(in(parameters.VSCODE_QUALITY, 'insider', 'exploration'), eq(variables['VSCODE_SCHEDULEDBUILD'], true))) }}: - stage: Release dependsOn: - Publish - ${{ if and(parameters.VSCODE_RELEASE, eq(variables['VSCODE_PRIVATE_BUILD'], false)) }}: - ApproveRelease pool: name: 1es-ubuntu-22.04-x64 os: linux jobs: - job: ReleaseBuild displayName: Release Build steps: - template: build/azure-pipelines/product-release.yml@self parameters: VSCODE_RELEASE: ${{ parameters.VSCODE_RELEASE }} ================================================ FILE: build/azure-pipelines/product-compile.yml ================================================ parameters: - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ./distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js compile $VSCODE_ARCH > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: sudo apt update -y && sudo apt install -y build-essential pkg-config libx11-dev libx11-xcb-dev libxkbfile-dev libnotify-bin libkrb5-dev displayName: Install build tools condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: npm run compile workingDirectory: build displayName: Compile /build/ folder - script: .github/workflows/check-clean-git-state.sh displayName: Check /build/ folder - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: common/install-builtin-extensions.yml@self - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - script: npm exec -- npm-run-all -lp core-ci-pr extensions-ci-pr hygiene eslint valid-layers-check property-init-order-check vscode-dts-compile-check tsec-compile-check env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Compile & Hygiene (OSS) - ${{ else }}: - script: npm exec -- npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check property-init-order-check vscode-dts-compile-check tsec-compile-check env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Compile & Hygiene (non-OSS) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e npm run compile displayName: Compile smoke test suites (non-OSS) workingDirectory: test/smoke condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e npm run compile displayName: Compile integration test suites (non-OSS) workingDirectory: test/integration/browser condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - task: AzureCLI@2 displayName: Fetch secrets inputs: azureSubscription: vscode scriptType: pscore scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=AZURE_ID_TOKEN;issecret=true]$env:idToken" - script: | set -e AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/upload-sourcemaps displayName: Upload sourcemaps to Azure - script: ./build/azure-pipelines/common/extract-telemetry.sh displayName: Generate lists of telemetry events - script: tar -cz --exclude='.build/node_modules_cache' --exclude='.build/node_modules_list.txt' --exclude='.build/distro' -f $(Build.ArtifactStagingDirectory)/compilation.tar.gz $(ls -d .build out-* test/integration/browser/out test/smoke/out test/automation/out 2>/dev/null) displayName: Compress compilation artifact - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz artifactName: Compilation sbomEnabled: false displayName: Publish compilation artifact - script: npm run download-builtin-extensions-cg env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download component details of built-in extensions - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: "Component Detection" inputs: sourceScanPath: $(Build.SourcesDirectory) alertWarningLevel: Medium continueOnError: true ================================================ FILE: build/azure-pipelines/product-npm-package-validate.yml ================================================ trigger: none pr: branches: include: ["main"] paths: include: ["package.json", "package-lock.json"] variables: - name: NPM_REGISTRY value: "https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/npm/registry/" - name: VSCODE_CIBUILD value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - name: VSCODE_QUALITY value: oss jobs: - ${{ if ne(variables['VSCODE_CIBUILD'], true) }}: - job: ValidateNpmPackage displayName: Valiate NPM package against Terrapin pool: name: 1es-ubuntu-22.04-x64 os: linux timeoutInMinutes: 40000 continueOnError: true variables: VSCODE_ARCH: x64 steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file echo "NPMRC Path: $(npm config get userconfig)" echo "NPM Registry: $(npm config get registry)" npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: sudo apt update -y && sudo apt install -y build-essential pkg-config libx11-dev libx11-xcb-dev libxkbfile-dev libnotify-bin libkrb5-dev displayName: Install build tools condition: succeeded() - script: | set -e for attempt in {1..6}; do if [ $attempt -gt 1 ]; then echo "Attempt $attempt: Waiting for 1 hour before retrying..." sleep 3600 fi echo "Attempt $attempt: Running npm ci" if npm i --ignore-scripts; then if node build/npm/postinstall.js; then echo "npm i succeeded on attempt $attempt" exit 0 else echo "node build/npm/postinstall.js failed on attempt $attempt" fi else echo "npm i failed on attempt $attempt" fi done echo "npm i failed after 6 attempts" exit 1 env: npm_command: 'install --ignore-scripts' ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install dependencies with retries timeoutInMinutes: 400 - script: .github/workflows/check-clean-git-state.sh displayName: Check clean git state ================================================ FILE: build/azure-pipelines/product-publish.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get ESRP Secrets" inputs: azureSubscription: vscode-esrp KeyVaultName: vscode-esrp SecretsFilter: esrp-auth,esrp-sign # allow-any-unicode-next-line - pwsh: Write-Host "##vso[build.addbuildtag]🚀" displayName: Add build tag - pwsh: | npm ci workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install build dependencies - download: current patterns: "**/artifacts_processed_*.txt" displayName: Download all artifacts_processed text files - task: AzureCLI@2 displayName: Fetch secrets inputs: azureSubscription: vscode scriptType: pscore scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=AZURE_ID_TOKEN;issecret=true]$env:idToken" - pwsh: | . build/azure-pipelines/win32/exec.ps1 if (Test-Path "$(Pipeline.Workspace)/artifacts_processed_*/artifacts_processed_*.txt") { Write-Host "Artifacts already processed so a build must have already been created." return } $VERSION = node -p "require('./package.json').version" Write-Host "Creating build with version: $VERSION" exec { node build/azure-pipelines/common/createBuild.js $VERSION } env: AZURE_TENANT_ID: "$(AZURE_TENANT_ID)" AZURE_CLIENT_ID: "$(AZURE_CLIENT_ID)" AZURE_ID_TOKEN: "$(AZURE_ID_TOKEN)" displayName: Create build if it hasn't been created before - pwsh: | $publishAuthTokens = (node build/azure-pipelines/common/getPublishAuthTokens) Write-Host "##vso[task.setvariable variable=PUBLISH_AUTH_TOKENS;issecret=true]$publishAuthTokens" env: AZURE_TENANT_ID: "$(AZURE_TENANT_ID)" AZURE_CLIENT_ID: "$(AZURE_CLIENT_ID)" AZURE_ID_TOKEN: "$(AZURE_ID_TOKEN)" displayName: Get publish auth tokens - pwsh: node build/azure-pipelines/common/publish.js env: GITHUB_TOKEN: "$(github-distro-mixin-password)" AZURE_TENANT_ID: "$(AZURE_TENANT_ID)" AZURE_CLIENT_ID: "$(AZURE_CLIENT_ID)" AZURE_ID_TOKEN: "$(AZURE_ID_TOKEN)" SYSTEM_ACCESSTOKEN: $(System.AccessToken) PUBLISH_AUTH_TOKENS: "$(PUBLISH_AUTH_TOKENS)" RELEASE_TENANT_ID: "$(ESRP_TENANT_ID)" RELEASE_CLIENT_ID: "$(ESRP_CLIENT_ID)" RELEASE_AUTH_CERT: "$(esrp-auth)" RELEASE_REQUEST_SIGNING_CERT: "$(esrp-sign)" displayName: Process artifacts retryCountOnTaskFailure: 3 - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Pipeline.Workspace)/artifacts_processed_$(System.StageAttempt)/artifacts_processed_$(System.StageAttempt).txt artifactName: artifacts_processed_$(System.StageAttempt) sbomEnabled: false displayName: Publish the artifacts processed for this stage attempt condition: always() - pwsh: | $ErrorActionPreference = 'Stop' # Determine which stages we need to watch $stages = @( if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' } if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' } if ($env:VSCODE_BUILD_STAGE_ALPINE -eq 'True') { 'Alpine' } if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' } if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' } ) Write-Host "Stages to check: $stages" # Get the timeline and see if it says the other stage completed $timeline = Invoke-RestMethod "$($env:BUILDS_API_URL)timeline?api-version=6.0" -Headers @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } -MaximumRetryCount 5 -RetryIntervalSec 1 $failedStages = @() foreach ($stage in $stages) { $didStageFail = $timeline.records | Where-Object { $_.name -eq $stage -and $_.type -eq 'stage' -and $_.result -ne 'succeeded' -and $_.result -ne 'succeededWithIssues' } if($didStageFail) { $failedStages += $stage Write-Host "'$stage' failed!" Write-Host $didStageFail } else { Write-Host "'$stage' did not fail." } } if ($failedStages.Length) { throw "Failed stages: $($failedStages -join ', '). This stage will now fail so that it is easier to retry failed jobs." } env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Determine if stage should succeed ================================================ FILE: build/azure-pipelines/product-release.yml ================================================ parameters: - name: VSCODE_RELEASE type: boolean steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: AzureCLI@2 displayName: Fetch secrets inputs: azureSubscription: vscode scriptType: pscore scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=AZURE_ID_TOKEN;issecret=true]$env:idToken" - script: npm ci workingDirectory: build displayName: Install /build dependencies - script: | set -e AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/common/releaseBuild.js ${{ parameters.VSCODE_RELEASE }} displayName: Release build ================================================ FILE: build/azure-pipelines/publish-types/check-version.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = __importDefault(require("child_process")); let tag = ''; try { tag = child_process_1.default .execSync('git describe --tags `git rev-list --tags --max-count=1`') .toString() .trim(); if (!isValidTag(tag)) { throw Error(`Invalid tag ${tag}`); } } catch (err) { console.error(err); console.error('Failed to update types'); process.exit(1); } function isValidTag(t) { if (t.split('.').length !== 3) { return false; } const [major, minor, bug] = t.split('.'); // Only release for tags like 1.34.0 if (bug !== '0') { return false; } if (isNaN(parseInt(major, 10)) || isNaN(parseInt(minor, 10))) { return false; } return true; } //# sourceMappingURL=check-version.js.map ================================================ FILE: build/azure-pipelines/publish-types/check-version.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import cp from 'child_process'; let tag = ''; try { tag = cp .execSync('git describe --tags `git rev-list --tags --max-count=1`') .toString() .trim(); if (!isValidTag(tag)) { throw Error(`Invalid tag ${tag}`); } } catch (err) { console.error(err); console.error('Failed to update types'); process.exit(1); } function isValidTag(t: string) { if (t.split('.').length !== 3) { return false; } const [major, minor, bug] = t.split('.'); // Only release for tags like 1.34.0 if (bug !== '0') { return false; } if (isNaN(parseInt(major, 10)) || isNaN(parseInt(minor, 10))) { return false; } return true; } ================================================ FILE: build/azure-pipelines/publish-types/publish-types.yml ================================================ # Publish @types/vscode for each release trigger: branches: include: ["refs/tags/*"] pr: none pool: vmImage: ubuntu-latest steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - bash: | TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) CHANNEL="C1C14HJ2F" if [ "$TAG_VERSION" == "1.999.0" ]; then MESSAGE=". Someone pushed 1.999.0 tag. Please delete it ASAP from remote and local." curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \ -H 'Content-type: application/json; charset=utf-8' \ --data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$MESSAGE"'"}' \ https://slack.com/api/chat.postMessage exit 1 fi displayName: Check 1.999.0 tag - bash: | # Install build dependencies (cd build && npm ci) node build/azure-pipelines/publish-types/check-version.js displayName: Check version - bash: | git config --global user.email "vscode@microsoft.com" git config --global user.name "VSCode" git clone https://$(GITHUB_TOKEN)@github.com/DefinitelyTyped/DefinitelyTyped.git --depth=1 node build/azure-pipelines/publish-types/update-types.js TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) cd DefinitelyTyped git diff --color | cat git add -A git status git checkout -b "vscode-types-$TAG_VERSION" git commit -m "VS Code $TAG_VERSION Extension API" git push origin "vscode-types-$TAG_VERSION" displayName: Push update to DefinitelyTyped - bash: | TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) CHANNEL="C1C14HJ2F" MESSAGE="DefinitelyTyped/DefinitelyTyped#vscode-types-$TAG_VERSION created. Endgame champion, please open this link, examine changes and create a PR:" LINK="https://github.com/DefinitelyTyped/DefinitelyTyped/compare/vscode-types-$TAG_VERSION?quick_pull=1&body=Updating%20VS%20Code%20Extension%20API.%20See%20https%3A%2F%2Fgithub.com%2Fmicrosoft%2Fvscode%2Fissues%2F70175%20for%20details." MESSAGE2="[@jrieken, @kmaetzel, @egamma]. Please review and merge PR to publish @types/vscode." curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \ -H 'Content-type: application/json; charset=utf-8' \ --data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$MESSAGE"'"}' \ https://slack.com/api/chat.postMessage curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \ -H 'Content-type: application/json; charset=utf-8' \ --data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$LINK"'"}' \ https://slack.com/api/chat.postMessage curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \ -H 'Content-type: application/json; charset=utf-8' \ --data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$MESSAGE2"'"}' \ https://slack.com/api/chat.postMessage displayName: Send message linking to changes on Slack ================================================ FILE: build/azure-pipelines/publish-types/update-types.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const child_process_1 = __importDefault(require("child_process")); const path_1 = __importDefault(require("path")); let tag = ''; try { tag = child_process_1.default .execSync('git describe --tags `git rev-list --tags --max-count=1`') .toString() .trim(); const dtsUri = `https://raw.githubusercontent.com/microsoft/vscode/${tag}/src/vscode-dts/vscode.d.ts`; const outPath = path_1.default.resolve(process.cwd(), 'DefinitelyTyped/types/vscode/index.d.ts'); child_process_1.default.execSync(`curl ${dtsUri} --output ${outPath}`); updateDTSFile(outPath, tag); console.log(`Done updating vscode.d.ts at ${outPath}`); } catch (err) { console.error(err); console.error('Failed to update types'); process.exit(1); } function updateDTSFile(outPath, tag) { const oldContent = fs_1.default.readFileSync(outPath, 'utf-8'); const newContent = getNewFileContent(oldContent, tag); fs_1.default.writeFileSync(outPath, newContent); } function repeat(str, times) { const result = new Array(times); for (let i = 0; i < times; i++) { result[i] = str; } return result.join(''); } function convertTabsToSpaces(str) { return str.replace(/\t/gm, value => repeat(' ', value.length)); } function getNewFileContent(content, tag) { const oldheader = [ `/*---------------------------------------------------------------------------------------------`, ` * Copyright (c) Microsoft Corporation. All rights reserved.`, ` * Licensed under the MIT License. See License.txt in the project root for license information.`, ` *--------------------------------------------------------------------------------------------*/` ].join('\n'); return convertTabsToSpaces(getNewFileHeader(tag) + content.slice(oldheader.length)); } function getNewFileHeader(tag) { const [major, minor] = tag.split('.'); const shorttag = `${major}.${minor}`; const header = [ `// Type definitions for Visual Studio Code ${shorttag}`, `// Project: https://github.com/microsoft/vscode`, `// Definitions by: Visual Studio Code Team, Microsoft `, `// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped`, ``, `/*---------------------------------------------------------------------------------------------`, ` * Copyright (c) Microsoft Corporation. All rights reserved.`, ` * Licensed under the MIT License.`, ` * See https://github.com/microsoft/vscode/blob/main/LICENSE.txt for license information.`, ` *--------------------------------------------------------------------------------------------*/`, ``, `/**`, ` * Type Definition for Visual Studio Code ${shorttag} Extension API`, ` * See https://code.visualstudio.com/api for more information`, ` */` ].join('\n'); return header; } //# sourceMappingURL=update-types.js.map ================================================ FILE: build/azure-pipelines/publish-types/update-types.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import cp from 'child_process'; import path from 'path'; let tag = ''; try { tag = cp .execSync('git describe --tags `git rev-list --tags --max-count=1`') .toString() .trim(); const dtsUri = `https://raw.githubusercontent.com/microsoft/vscode/${tag}/src/vscode-dts/vscode.d.ts`; const outPath = path.resolve(process.cwd(), 'DefinitelyTyped/types/vscode/index.d.ts'); cp.execSync(`curl ${dtsUri} --output ${outPath}`); updateDTSFile(outPath, tag); console.log(`Done updating vscode.d.ts at ${outPath}`); } catch (err) { console.error(err); console.error('Failed to update types'); process.exit(1); } function updateDTSFile(outPath: string, tag: string) { const oldContent = fs.readFileSync(outPath, 'utf-8'); const newContent = getNewFileContent(oldContent, tag); fs.writeFileSync(outPath, newContent); } function repeat(str: string, times: number): string { const result = new Array(times); for (let i = 0; i < times; i++) { result[i] = str; } return result.join(''); } function convertTabsToSpaces(str: string): string { return str.replace(/\t/gm, value => repeat(' ', value.length)); } function getNewFileContent(content: string, tag: string) { const oldheader = [ `/*---------------------------------------------------------------------------------------------`, ` * Copyright (c) Microsoft Corporation. All rights reserved.`, ` * Licensed under the MIT License. See License.txt in the project root for license information.`, ` *--------------------------------------------------------------------------------------------*/` ].join('\n'); return convertTabsToSpaces(getNewFileHeader(tag) + content.slice(oldheader.length)); } function getNewFileHeader(tag: string) { const [major, minor] = tag.split('.'); const shorttag = `${major}.${minor}`; const header = [ `// Type definitions for Visual Studio Code ${shorttag}`, `// Project: https://github.com/microsoft/vscode`, `// Definitions by: Visual Studio Code Team, Microsoft `, `// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped`, ``, `/*---------------------------------------------------------------------------------------------`, ` * Copyright (c) Microsoft Corporation. All rights reserved.`, ` * Licensed under the MIT License.`, ` * See https://github.com/microsoft/vscode/blob/main/LICENSE.txt for license information.`, ` *--------------------------------------------------------------------------------------------*/`, ``, `/**`, ` * Type Definition for Visual Studio Code ${shorttag} Extension API`, ` * See https://code.visualstudio.com/api for more information`, ` */` ].join('\n'); return header; } ================================================ FILE: build/azure-pipelines/upload-cdn.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const event_stream_1 = __importDefault(require("event-stream")); const vinyl_1 = __importDefault(require("vinyl")); const vinyl_fs_1 = __importDefault(require("vinyl-fs")); const gulp_filter_1 = __importDefault(require("gulp-filter")); const gulp_gzip_1 = __importDefault(require("gulp-gzip")); const mime_1 = __importDefault(require("mime")); const identity_1 = require("@azure/identity"); const azure = require('gulp-azure-storage'); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new identity_1.ClientAssertionCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], () => Promise.resolve(process.env['AZURE_ID_TOKEN'])); mime_1.default.define({ 'application/typescript': ['ts'], 'application/json': ['code-snippets'], }); // From default AFD configuration const MimeTypesToCompress = new Set([ 'application/eot', 'application/font', 'application/font-sfnt', 'application/javascript', 'application/json', 'application/opentype', 'application/otf', 'application/pkcs7-mime', 'application/truetype', 'application/ttf', 'application/typescript', 'application/vnd.ms-fontobject', 'application/xhtml+xml', 'application/xml', 'application/xml+rss', 'application/x-font-opentype', 'application/x-font-truetype', 'application/x-font-ttf', 'application/x-httpd-cgi', 'application/x-javascript', 'application/x-mpegurl', 'application/x-opentype', 'application/x-otf', 'application/x-perl', 'application/x-ttf', 'font/eot', 'font/ttf', 'font/otf', 'font/opentype', 'image/svg+xml', 'text/css', 'text/csv', 'text/html', 'text/javascript', 'text/js', 'text/markdown', 'text/plain', 'text/richtext', 'text/tab-separated-values', 'text/xml', 'text/x-script', 'text/x-component', 'text/x-java-source' ]); function wait(stream) { return new Promise((c, e) => { stream.on('end', () => c()); stream.on('error', (err) => e(err)); }); } async function main() { const files = []; const options = (compressed) => ({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `${process.env.VSCODE_QUALITY}/${commit}/`, contentSettings: { contentEncoding: compressed ? 'gzip' : undefined, cacheControl: 'max-age=31536000, public' } }); const all = vinyl_fs_1.default.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true }) .pipe((0, gulp_filter_1.default)(f => !f.isDirectory())); const compressed = all .pipe((0, gulp_filter_1.default)(f => MimeTypesToCompress.has(mime_1.default.lookup(f.path)))) .pipe((0, gulp_gzip_1.default)({ append: false })) .pipe(azure.upload(options(true))); const uncompressed = all .pipe((0, gulp_filter_1.default)(f => !MimeTypesToCompress.has(mime_1.default.lookup(f.path)))) .pipe(azure.upload(options(false))); const out = event_stream_1.default.merge(compressed, uncompressed) .pipe(event_stream_1.default.through(function (f) { console.log('Uploaded:', f.relative); files.push(f.relative); this.emit('data', f); })); console.log(`Uploading files to CDN...`); // debug await wait(out); const listing = new vinyl_1.default({ path: 'files.txt', contents: Buffer.from(files.join('\n')), stat: { mode: 0o666 } }); const filesOut = event_stream_1.default.readArray([listing]) .pipe((0, gulp_gzip_1.default)({ append: false })) .pipe(azure.upload(options(true))); console.log(`Uploading: files.txt (${files.length} files)`); // debug await wait(filesOut); } main().catch(err => { console.error(err); process.exit(1); }); //# sourceMappingURL=upload-cdn.js.map ================================================ FILE: build/azure-pipelines/upload-cdn.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import Vinyl from 'vinyl'; import vfs from 'vinyl-fs'; import filter from 'gulp-filter'; import gzip from 'gulp-gzip'; import mime from 'mime'; import { ClientAssertionCredential } from '@azure/identity'; const azure = require('gulp-azure-storage'); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new ClientAssertionCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, () => Promise.resolve(process.env['AZURE_ID_TOKEN']!)); mime.define({ 'application/typescript': ['ts'], 'application/json': ['code-snippets'], }); // From default AFD configuration const MimeTypesToCompress = new Set([ 'application/eot', 'application/font', 'application/font-sfnt', 'application/javascript', 'application/json', 'application/opentype', 'application/otf', 'application/pkcs7-mime', 'application/truetype', 'application/ttf', 'application/typescript', 'application/vnd.ms-fontobject', 'application/xhtml+xml', 'application/xml', 'application/xml+rss', 'application/x-font-opentype', 'application/x-font-truetype', 'application/x-font-ttf', 'application/x-httpd-cgi', 'application/x-javascript', 'application/x-mpegurl', 'application/x-opentype', 'application/x-otf', 'application/x-perl', 'application/x-ttf', 'font/eot', 'font/ttf', 'font/otf', 'font/opentype', 'image/svg+xml', 'text/css', 'text/csv', 'text/html', 'text/javascript', 'text/js', 'text/markdown', 'text/plain', 'text/richtext', 'text/tab-separated-values', 'text/xml', 'text/x-script', 'text/x-component', 'text/x-java-source' ]); function wait(stream: es.ThroughStream): Promise { return new Promise((c, e) => { stream.on('end', () => c()); stream.on('error', (err: any) => e(err)); }); } async function main(): Promise { const files: string[] = []; const options = (compressed: boolean) => ({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `${process.env.VSCODE_QUALITY}/${commit}/`, contentSettings: { contentEncoding: compressed ? 'gzip' : undefined, cacheControl: 'max-age=31536000, public' } }); const all = vfs.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true }) .pipe(filter(f => !f.isDirectory())); const compressed = all .pipe(filter(f => MimeTypesToCompress.has(mime.lookup(f.path)))) .pipe(gzip({ append: false })) .pipe(azure.upload(options(true))); const uncompressed = all .pipe(filter(f => !MimeTypesToCompress.has(mime.lookup(f.path)))) .pipe(azure.upload(options(false))); const out = es.merge(compressed, uncompressed) .pipe(es.through(function (f) { console.log('Uploaded:', f.relative); files.push(f.relative); this.emit('data', f); })); console.log(`Uploading files to CDN...`); // debug await wait(out); const listing = new Vinyl({ path: 'files.txt', contents: Buffer.from(files.join('\n')), stat: { mode: 0o666 } as any }); const filesOut = es.readArray([listing]) .pipe(gzip({ append: false })) .pipe(azure.upload(options(true))); console.log(`Uploading: files.txt (${files.length} files)`); // debug await wait(filesOut); } main().catch(err => { console.error(err); process.exit(1); }); ================================================ FILE: build/azure-pipelines/upload-nlsmetadata.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const event_stream_1 = __importDefault(require("event-stream")); const vinyl_fs_1 = __importDefault(require("vinyl-fs")); const gulp_merge_json_1 = __importDefault(require("gulp-merge-json")); const gulp_gzip_1 = __importDefault(require("gulp-gzip")); const identity_1 = require("@azure/identity"); const path = require("path"); const fs_1 = require("fs"); const azure = require('gulp-azure-storage'); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new identity_1.ClientAssertionCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], () => Promise.resolve(process.env['AZURE_ID_TOKEN'])); function main() { return new Promise((c, e) => { const combinedMetadataJson = event_stream_1.default.merge( // vscode: we are not using `out-build/nls.metadata.json` here because // it includes metadata for translators for `keys`. but for our purpose // we want only the `keys` and `messages` as `string`. event_stream_1.default.merge(vinyl_fs_1.default.src('out-build/nls.keys.json', { base: 'out-build' }), vinyl_fs_1.default.src('out-build/nls.messages.json', { base: 'out-build' })) .pipe((0, gulp_merge_json_1.default)({ fileName: 'vscode.json', jsonSpace: '', concatArrays: true, edit: (parsedJson, file) => { if (file.base === 'out-build') { if (file.basename === 'nls.keys.json') { return { keys: parsedJson }; } else { return { messages: parsedJson }; } } } })), // extensions vinyl_fs_1.default.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }), vinyl_fs_1.default.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }), vinyl_fs_1.default.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' })).pipe((0, gulp_merge_json_1.default)({ fileName: 'combined.nls.metadata.json', jsonSpace: '', concatArrays: true, edit: (parsedJson, file) => { if (file.basename === 'vscode.json') { return { vscode: parsedJson }; } // Handle extensions and follow the same structure as the Core nls file. switch (file.basename) { case 'package.nls.json': // put package.nls.json content in Core NlsMetadata format // language packs use the key "package" to specify that // translations are for the package.json file parsedJson = { messages: { package: Object.values(parsedJson) }, keys: { package: Object.keys(parsedJson) }, bundles: { main: ['package'] } }; break; case 'nls.metadata.header.json': parsedJson = { header: parsedJson }; break; case 'nls.metadata.json': { // put nls.metadata.json content in Core NlsMetadata format const modules = Object.keys(parsedJson); const json = { keys: {}, messages: {}, bundles: { main: [] } }; for (const module of modules) { json.messages[module] = parsedJson[module].messages; json.keys[module] = parsedJson[module].keys; json.bundles.main.push(module); } parsedJson = json; break; } } // Get extension id and use that as the key const folderPath = path.join(file.base, file.relative.split('/')[0]); const manifest = (0, fs_1.readFileSync)(path.join(folderPath, 'package.json'), 'utf-8'); const manifestJson = JSON.parse(manifest); const key = manifestJson.publisher + '.' + manifestJson.name; return { [key]: parsedJson }; }, })); const nlsMessagesJs = vinyl_fs_1.default.src('out-build/nls.messages.js', { base: 'out-build' }); event_stream_1.default.merge(combinedMetadataJson, nlsMessagesJs) .pipe((0, gulp_gzip_1.default)({ append: false })) .pipe(vinyl_fs_1.default.dest('./nlsMetadata')) .pipe(event_stream_1.default.through(function (data) { console.log(`Uploading ${data.path}`); // trigger artifact upload console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=${data.basename}]${data.path}`); this.emit('data', data); })) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `nlsmetadata/${commit}/`, contentSettings: { contentEncoding: 'gzip', cacheControl: 'max-age=31536000, public' } })) .on('end', () => c()) .on('error', (err) => e(err)); }); } main().catch(err => { console.error(err); process.exit(1); }); //# sourceMappingURL=upload-nlsmetadata.js.map ================================================ FILE: build/azure-pipelines/upload-nlsmetadata.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import Vinyl from 'vinyl'; import vfs from 'vinyl-fs'; import merge from 'gulp-merge-json'; import gzip from 'gulp-gzip'; import { ClientAssertionCredential } from '@azure/identity'; import path = require('path'); import { readFileSync } from 'fs'; const azure = require('gulp-azure-storage'); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new ClientAssertionCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, () => Promise.resolve(process.env['AZURE_ID_TOKEN']!)); interface NlsMetadata { keys: { [module: string]: string }; messages: { [module: string]: string }; bundles: { [bundle: string]: string[] }; } function main(): Promise { return new Promise((c, e) => { const combinedMetadataJson = es.merge( // vscode: we are not using `out-build/nls.metadata.json` here because // it includes metadata for translators for `keys`. but for our purpose // we want only the `keys` and `messages` as `string`. es.merge( vfs.src('out-build/nls.keys.json', { base: 'out-build' }), vfs.src('out-build/nls.messages.json', { base: 'out-build' })) .pipe(merge({ fileName: 'vscode.json', jsonSpace: '', concatArrays: true, edit: (parsedJson, file) => { if (file.base === 'out-build') { if (file.basename === 'nls.keys.json') { return { keys: parsedJson }; } else { return { messages: parsedJson }; } } } })), // extensions vfs.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' }) ).pipe(merge({ fileName: 'combined.nls.metadata.json', jsonSpace: '', concatArrays: true, edit: (parsedJson, file) => { if (file.basename === 'vscode.json') { return { vscode: parsedJson }; } // Handle extensions and follow the same structure as the Core nls file. switch (file.basename) { case 'package.nls.json': // put package.nls.json content in Core NlsMetadata format // language packs use the key "package" to specify that // translations are for the package.json file parsedJson = { messages: { package: Object.values(parsedJson) }, keys: { package: Object.keys(parsedJson) }, bundles: { main: ['package'] } }; break; case 'nls.metadata.header.json': parsedJson = { header: parsedJson }; break; case 'nls.metadata.json': { // put nls.metadata.json content in Core NlsMetadata format const modules = Object.keys(parsedJson); const json: NlsMetadata = { keys: {}, messages: {}, bundles: { main: [] } }; for (const module of modules) { json.messages[module] = parsedJson[module].messages; json.keys[module] = parsedJson[module].keys; json.bundles.main.push(module); } parsedJson = json; break; } } // Get extension id and use that as the key const folderPath = path.join(file.base, file.relative.split('/')[0]); const manifest = readFileSync(path.join(folderPath, 'package.json'), 'utf-8'); const manifestJson = JSON.parse(manifest); const key = manifestJson.publisher + '.' + manifestJson.name; return { [key]: parsedJson }; }, })); const nlsMessagesJs = vfs.src('out-build/nls.messages.js', { base: 'out-build' }); es.merge(combinedMetadataJson, nlsMessagesJs) .pipe(gzip({ append: false })) .pipe(vfs.dest('./nlsMetadata')) .pipe(es.through(function (data: Vinyl) { console.log(`Uploading ${data.path}`); // trigger artifact upload console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=${data.basename}]${data.path}`); this.emit('data', data); })) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `nlsmetadata/${commit}/`, contentSettings: { contentEncoding: 'gzip', cacheControl: 'max-age=31536000, public' } })) .on('end', () => c()) .on('error', (err: any) => e(err)); }); } main().catch(err => { console.error(err); process.exit(1); }); ================================================ FILE: build/azure-pipelines/upload-sourcemaps.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const event_stream_1 = __importDefault(require("event-stream")); const vinyl_fs_1 = __importDefault(require("vinyl-fs")); const util = __importStar(require("../lib/util")); const dependencies_1 = require("../lib/dependencies"); const identity_1 = require("@azure/identity"); const azure = require('gulp-azure-storage'); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new identity_1.ClientAssertionCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], () => Promise.resolve(process.env['AZURE_ID_TOKEN'])); // optionally allow to pass in explicit base/maps to upload const [, , base, maps] = process.argv; function src(base, maps = `${base}/**/*.map`) { return vinyl_fs_1.default.src(maps, { base }) .pipe(event_stream_1.default.mapSync((f) => { f.path = `${f.base}/core/${f.relative}`; return f; })); } function main() { const sources = []; // vscode client maps (default) if (!base) { const vs = src('out-vscode-min'); // client source-maps only sources.push(vs); const productionDependencies = (0, dependencies_1.getProductionDependencies)(root); const productionDependenciesSrc = productionDependencies.map((d) => path_1.default.relative(root, d)).map((d) => `./${d}/**/*.map`); const nodeModules = vinyl_fs_1.default.src(productionDependenciesSrc, { base: '.' }) .pipe(util.cleanNodeModules(path_1.default.join(root, 'build', '.moduleignore'))) .pipe(util.cleanNodeModules(path_1.default.join(root, 'build', `.moduleignore.${process.platform}`))); sources.push(nodeModules); const extensionsOut = vinyl_fs_1.default.src(['.build/extensions/**/*.js.map', '!**/node_modules/**'], { base: '.build' }); sources.push(extensionsOut); } // specific client base/maps else { sources.push(src(base, maps)); } return new Promise((c, e) => { event_stream_1.default.merge(...sources) .pipe(event_stream_1.default.through(function (data) { console.log('Uploading Sourcemap', data.relative); // debug this.emit('data', data); })) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `sourcemaps/${commit}/` })) .on('end', () => c()) .on('error', (err) => e(err)); }); } main().catch(err => { console.error(err); process.exit(1); }); //# sourceMappingURL=upload-sourcemaps.js.map ================================================ FILE: build/azure-pipelines/upload-sourcemaps.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import es from 'event-stream'; import Vinyl from 'vinyl'; import vfs from 'vinyl-fs'; import * as util from '../lib/util'; import { getProductionDependencies } from '../lib/dependencies'; import { ClientAssertionCredential } from '@azure/identity'; const azure = require('gulp-azure-storage'); const root = path.dirname(path.dirname(__dirname)); const commit = process.env['BUILD_SOURCEVERSION']; const credential = new ClientAssertionCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, () => Promise.resolve(process.env['AZURE_ID_TOKEN']!)); // optionally allow to pass in explicit base/maps to upload const [, , base, maps] = process.argv; function src(base: string, maps = `${base}/**/*.map`) { return vfs.src(maps, { base }) .pipe(es.mapSync((f: Vinyl) => { f.path = `${f.base}/core/${f.relative}`; return f; })); } function main(): Promise { const sources: any[] = []; // vscode client maps (default) if (!base) { const vs = src('out-vscode-min'); // client source-maps only sources.push(vs); const productionDependencies = getProductionDependencies(root); const productionDependenciesSrc = productionDependencies.map((d: string) => path.relative(root, d)).map((d: string) => `./${d}/**/*.map`); const nodeModules = vfs.src(productionDependenciesSrc, { base: '.' }) .pipe(util.cleanNodeModules(path.join(root, 'build', '.moduleignore'))) .pipe(util.cleanNodeModules(path.join(root, 'build', `.moduleignore.${process.platform}`))); sources.push(nodeModules); const extensionsOut = vfs.src(['.build/extensions/**/*.js.map', '!**/node_modules/**'], { base: '.build' }); sources.push(extensionsOut); } // specific client base/maps else { sources.push(src(base, maps)); } return new Promise((c, e) => { es.merge(...sources) .pipe(es.through(function (data: Vinyl) { console.log('Uploading Sourcemap', data.relative); // debug this.emit('data', data); })) .pipe(azure.upload({ account: process.env.AZURE_STORAGE_ACCOUNT, credential, container: '$web', prefix: `sourcemaps/${commit}/` })) .on('end', () => c()) .on('error', (err: any) => e(err)); }); } main().catch(err => { console.error(err); process.exit(1); }); ================================================ FILE: build/azure-pipelines/web/product-build-web.yml ================================================ steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - task: DownloadPipelineArtifact@2 inputs: artifact: Compilation path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - script: node build/setup-npm-registry.js $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js web > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - script: tar -xzf .build/node_modules_cache/cache.tgz condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - script: | set -e # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file npm config set registry "$NPM_REGISTRY" echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - script: | set -e ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get update ./build/azure-pipelines/linux/apt-retry.sh sudo apt-get install -y libkrb5-dev displayName: Setup system services condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: | set -e for i in {1..5}; do # try 5 times npm ci && break if [ $i -eq 5 ]; then echo "Npm install failed too many times" >&2 exit 1 fi echo "Npm install failed $i, trying again..." done env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt mkdir -p .build/node_modules_cache tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: ../common/install-builtin-extensions.yml@self - script: | set -e npm run gulp vscode-web-min-ci ARCHIVE_PATH=".build/web/vscode-web.tar.gz" mkdir -p $(dirname $ARCHIVE_PATH) tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-web echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build - task: AzureCLI@2 displayName: Fetch secrets from Azure inputs: azureSubscription: vscode scriptType: pscore scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=AZURE_ID_TOKEN;issecret=true]$env:idToken" - script: | set -e AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/upload-cdn displayName: Upload to CDN - script: | set -e AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.main.js.map displayName: Upload sourcemaps (Web Main) - script: | set -e AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.main.internal.js.map displayName: Upload sourcemaps (Web Internal) - script: | set -e AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \ node build/azure-pipelines/upload-nlsmetadata displayName: Upload NLS Metadata - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) displayName: Generate artifact prefix - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_linux_standalone_archive-unsigned sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-web sbomPackageName: "VS Code Web" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web archive ================================================ FILE: build/azure-pipelines/win32/cli-build-win32.yml ================================================ parameters: - name: VSCODE_BUILD_WIN32 type: boolean default: false - name: VSCODE_BUILD_WIN32_ARM64 type: boolean default: false - name: VSCODE_CHECK_ONLY type: boolean default: false - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 displayName: Download openssl prebuilt inputs: command: custom customCommand: pack @vscode-internal/openssl-prebuilt@0.0.11 customRegistry: useFeed customFeed: "Monaco/openssl-prebuilt" workingDir: $(Build.ArtifactStagingDirectory) - powershell: | mkdir $(Build.ArtifactStagingDirectory)/openssl tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - template: ../cli/install-rust-win32.yml@self parameters: targets: - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - x86_64-pc-windows-msvc - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - aarch64-pc-windows-msvc - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: x86_64-pc-windows-msvc VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_x64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static/include RUSTFLAGS: "-Ctarget-feature=+crt-static -Clink-args=/guard:cf -Clink-args=/CETCOMPAT" CFLAGS: "/guard:cf /Qspectre" - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - template: ../cli/cli-compile.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_CLI_TARGET: aarch64-pc-windows-msvc VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static/include RUSTFLAGS: "-C target-feature=+crt-static -Clink-args=/guard:cf -Clink-args=/CETCOMPAT:NO" CFLAGS: "/guard:cf /Qspectre" - ${{ if not(parameters.VSCODE_CHECK_ONLY) }}: - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/unsigned_vscode_cli_win32_arm64_cli.zip artifactName: unsigned_vscode_cli_win32_arm64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Windows arm64 CLI (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish unsigned_vscode_cli_win32_arm64_cli artifact - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(Build.ArtifactStagingDirectory)/unsigned_vscode_cli_win32_x64_cli.zip artifactName: unsigned_vscode_cli_win32_x64_cli sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli sbomPackageName: "VS Code Windows x64 CLI (unsigned)" sbomPackageVersion: $(Build.SourceVersion) displayName: Publish unsigned_vscode_cli_win32_x64_cli artifact ================================================ FILE: build/azure-pipelines/win32/exec.ps1 ================================================ # Taken from psake https://github.com/psake/psake <# .SYNOPSIS This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode to see if an error occcured. If an error is detected then an exception is thrown. This function allows you to run command-line programs without having to explicitly check the $lastexitcode variable. .EXAMPLE exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed" #> function Exec { [CmdletBinding()] param( [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd, [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd) ) & $cmd if ($lastexitcode -ne 0) { throw ("Exec: " + $errorMessage) } } ================================================ FILE: build/azure-pipelines/win32/import-esrp-auth-cert.ps1 ================================================ param ($CertBase64) $ErrorActionPreference = "Stop" $CertBytes = [System.Convert]::FromBase64String($CertBase64) $CertCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection $CertCollection.Import($CertBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet) $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine") $CertStore.Open("ReadWrite") $CertStore.AddRange($CertCollection) $CertStore.Close() $ESRPAuthCertificateSubjectName = $CertCollection[0].Subject Write-Output ("##vso[task.setvariable variable=ESRPAuthCertificateSubjectName;]$ESRPAuthCertificateSubjectName") ================================================ FILE: build/azure-pipelines/win32/listprocesses.bat ================================================ echo "------------------------------------" tasklist /V echo "------------------------------------" ================================================ FILE: build/azure-pipelines/win32/product-build-win32-cli-sign.yml ================================================ parameters: - name: VSCODE_BUILD_WIN32 type: boolean - name: VSCODE_BUILD_WIN32_ARM64 type: boolean - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 displayName: "Use Node.js" inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file exec { npm config set registry "$env:NPM_REGISTRY" } $NpmrcPath = (npm config get userconfig) echo "##vso[task.setvariable variable=NPMRC_PATH]$NpmrcPath" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - powershell: | . azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm ci } workingDirectory: build env: GITHUB_TOKEN: "$(github-distro-mixin-password)" retryCountOnTaskFailure: 5 displayName: Install build dependencies - template: ../cli/cli-win32-sign.yml@self parameters: VSCODE_CLI_ARTIFACTS: - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - unsigned_vscode_cli_win32_x64_cli - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - unsigned_vscode_cli_win32_arm64_cli ================================================ FILE: build/azure-pipelines/win32/product-build-win32-test.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_ARCH type: string - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean - name: PUBLISH_TASK_NAME type: string default: PublishPipelineArtifact@0 steps: - powershell: npm exec -- npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: .\scripts\test.bat --tfs "Unit Tests" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - powershell: npm run test-node displayName: Run unit tests (node.js) timeoutInMinutes: 15 - powershell: node test/unit/browser/index.js --browser chromium --tfs "Browser Unit Tests" displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: .\scripts\test.bat --build --tfs "Unit Tests" displayName: Run unit tests (Electron) timeoutInMinutes: 15 - powershell: npm run test-node -- --build displayName: Run unit tests (node.js) timeoutInMinutes: 15 - powershell: npm run test-browser-no-install -- --build --browser chromium --tfs "Browser Unit Tests" displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 20 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm run gulp ` compile-extension:configuration-editing ` compile-extension:css-language-features-server ` compile-extension:emmet ` compile-extension:git ` compile-extension:github-authentication ` compile-extension:html-language-features-server ` compile-extension:ipynb ` compile-extension:notebook-renderers ` compile-extension:json-language-features-server ` compile-extension:markdown-language-features ` compile-extension-media ` compile-extension:microsoft-authentication ` compile-extension:typescript-language-features ` compile-extension:vscode-api-tests ` compile-extension:vscode-colorize-tests ` compile-extension:vscode-colorize-perf-tests ` compile-extension:vscode-test-resolver ` } displayName: Build integration tests - powershell: .\build\azure-pipelines\win32\listprocesses.bat displayName: Diagnostics before integration test runs continueOnError: true condition: succeededOrFailed() - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: .\scripts\test-integration.bat --tfs "Integration Tests" displayName: Run integration tests (Electron) timeoutInMinutes: 20 - powershell: .\scripts\test-web-integration.bat --browser chromium displayName: Run integration tests (Browser, Chromium) timeoutInMinutes: 20 - powershell: .\scripts\test-remote-integration.bat displayName: Run integration tests (Remote) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: | # Figure out the full absolute path of the product we just built # including the remote server and configure the integration tests # to run with these builds instead of running out of sources. . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json $AppNameShort = $AppProductJson.nameShort $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe" $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)" exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } displayName: Run integration tests (Electron) timeoutInMinutes: 20 - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)-web" exec { .\scripts\test-web-integration.bat --browser firefox } displayName: Run integration tests (Browser, Firefox) timeoutInMinutes: 20 - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json $AppNameShort = $AppProductJson.nameShort $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe" $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)" exec { .\scripts\test-remote-integration.bat } displayName: Run integration tests (Remote) timeoutInMinutes: 20 - powershell: .\build\azure-pipelines\win32\listprocesses.bat displayName: Diagnostics after integration test runs continueOnError: true condition: succeededOrFailed() - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - powershell: .\build\azure-pipelines\win32\listprocesses.bat displayName: Diagnostics before smoke test run continueOnError: true condition: succeededOrFailed() - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: npm run compile workingDirectory: test/smoke displayName: Compile smoke tests - powershell: npm run gulp compile-extension-media displayName: Build extensions for smoke tests - powershell: npm run smoketest-no-compile -- --tracing displayName: Run smoke tests (Electron) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: npm run smoketest-no-compile -- --tracing --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" displayName: Run smoke tests (Electron) timeoutInMinutes: 20 - powershell: npm run smoketest-no-compile -- --web --tracing --headless env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)-web displayName: Run smoke tests (Browser, Chromium) timeoutInMinutes: 20 - powershell: npm run gulp compile-extension:vscode-test-resolver displayName: Compile test resolver extension timeoutInMinutes: 20 - powershell: npm run smoketest-no-compile -- --tracing --remote --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" env: VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH) displayName: Run smoke tests (Remote) timeoutInMinutes: 20 - powershell: .\build\azure-pipelines\win32\listprocesses.bat displayName: Diagnostics after smoke test run continueOnError: true condition: succeededOrFailed() - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: .build\crashes ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: crash-dump-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: crash-dump-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: crash-dump-windows-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Crash Reports" continueOnError: true condition: failed() # In order to properly symbolify above crash reports # (if any), we need the compiled native modules too - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: node_modules ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: node-modules-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: node-modules-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: node-modules-windows-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Node Modules" continueOnError: true condition: failed() - task: ${{ parameters.PUBLISH_TASK_NAME }} inputs: targetPath: .build\logs ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: artifactName: logs-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: artifactName: logs-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) ${{ else }}: artifactName: logs-windows-$(VSCODE_ARCH)-$(System.JobAttempt) sbomEnabled: false displayName: "Publish Log Files" continueOnError: true condition: succeededOrFailed() - task: PublishTestResults@2 displayName: Publish Tests Results inputs: testResultsFiles: "*-results.xml" searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" condition: succeededOrFailed() ================================================ FILE: build/azure-pipelines/win32/product-build-win32.yml ================================================ parameters: - name: VSCODE_QUALITY type: string - name: VSCODE_ARCH type: string - name: VSCODE_CIBUILD type: boolean - name: VSCODE_RUN_UNIT_TESTS type: boolean - name: VSCODE_RUN_INTEGRATION_TESTS type: boolean - name: VSCODE_RUN_SMOKE_TESTS type: boolean steps: - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - checkout: self fetchDepth: 1 retryCountOnTaskFailure: 3 - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: UsePythonVersion@0 inputs: versionSpec: "3.x" addToPath: true - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - task: DownloadPipelineArtifact@2 inputs: artifact: Compilation path: $(Build.ArtifactStagingDirectory) displayName: Download compilation output - task: ExtractFiles@1 displayName: Extract compilation output inputs: archiveFilePatterns: "$(Build.ArtifactStagingDirectory)/compilation.tar.gz" cleanDestinationFolder: false - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - pwsh: | mkdir .build -ea 0 node build/azure-pipelines/common/computeNodeModulesCacheKey.js win32 $(VSCODE_ARCH) > .build/packagelockhash displayName: Prepare node_modules cache key - task: Cache@2 inputs: key: '"node_modules" | .build/packagelockhash' path: .build/node_modules_cache cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache - powershell: 7z.exe x .build/node_modules_cache/cache.7z -aoa condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file exec { npm config set registry "$env:NPM_REGISTRY" } $NpmrcPath = (npm config get userconfig) echo "##vso[task.setvariable variable=NPMRC_PATH]$NpmrcPath" condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm ci } env: npm_config_arch: $(VSCODE_ARCH) npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" retryCountOnTaskFailure: 5 displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt } exec { mkdir -Force .build/node_modules_cache } exec { 7z.exe a .build/node_modules_cache/cache.7z -mx3 `@.build/node_modules_list.txt } condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality - template: ../common/install-builtin-extensions.yml@self - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - powershell: node build\lib\policies win32 displayName: Generate Group Policy definitions retryCountOnTaskFailure: 3 - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: npm run gulp "transpile-client-esbuild" "transpile-extensions" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Transpile client and extensions - ${{ else }}: - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), eq(parameters.VSCODE_QUALITY, 'insider')) }}: - powershell: node build/win32/explorer-appx-fetcher .build/win32/appx displayName: Download Explorer Sparse Package - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm run gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" } exec { npm run gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } echo "##vso[task.setvariable variable=BUILT_CLIENT]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm run gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" } mv ..\vscode-reh-win32-$(VSCODE_ARCH) ..\vscode-server-win32-$(VSCODE_ARCH) # TODO@joaomoreno echo "##vso[task.setvariable variable=BUILT_SERVER]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm run gulp "vscode-reh-web-win32-$(VSCODE_ARCH)-min-ci" } mv ..\vscode-reh-web-win32-$(VSCODE_ARCH) ..\vscode-server-win32-$(VSCODE_ARCH)-web # TODO@joaomoreno echo "##vso[task.setvariable variable=BUILT_WEB]true" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - template: product-build-win32-test.yml@self parameters: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1 - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - task: DownloadPipelineArtifact@2 inputs: artifact: unsigned_vscode_cli_win32_$(VSCODE_ARCH)_cli patterns: "**" path: $(Build.ArtifactStagingDirectory)/cli displayName: Download VS Code CLI - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $ArtifactName = (gci -Path "$(Build.ArtifactStagingDirectory)/cli" | Select-Object -last 1).FullName Expand-Archive -Path $ArtifactName -DestinationPath "$(Build.ArtifactStagingDirectory)/cli" $AppProductJson = Get-Content -Raw -Path "$(Agent.BuildDirectory)\VSCode-win32-$(VSCODE_ARCH)\resources\app\product.json" | ConvertFrom-Json $CliAppName = $AppProductJson.tunnelApplicationName $AppName = $AppProductJson.applicationName Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/$AppName.exe" -Destination "$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$CliAppName.exe" displayName: Move VS Code CLI - task: UseDotNet@2 inputs: version: 6.x - task: EsrpCodeSigning@5 inputs: UseMSIAuthentication: true ConnectedServiceName: vscode-esrp AppRegistrationClientId: $(ESRP_CLIENT_ID) AppRegistrationTenantId: $(ESRP_TENANT_ID) AuthAKVName: vscode-esrp AuthSignCertName: esrp-sign FolderPath: . Pattern: noop displayName: 'Install ESRP Tooling' - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $EsrpCodeSigningTool = (gci -directory -filter EsrpCodeSigning_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName $Version = (gci -directory $EsrpCodeSigningTool | Select-Object -last 1).FullName echo "##vso[task.setvariable variable=EsrpCliDllPath]$Version\net6.0\esrpcli.dll" displayName: Find ESRP CLI - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows $(CodeSigningFolderPath) '*.dll,*.exe,*.node' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign executables and shared libraries - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.ps1' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign Powershell scripts - ${{ if eq(parameters.VSCODE_QUALITY, 'insider') }}: - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.appx' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Codesign context menu appx package - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $PackageJson = Get-Content -Raw -Path ..\VSCode-win32-$(VSCODE_ARCH)\resources\app\package.json | ConvertFrom-Json $Version = $PackageJson.version echo "##vso[task.setvariable variable=VSCODE_VERSION]$Version" condition: succeededOrFailed() displayName: Get product version - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\VSCode-win32-$(VSCODE_ARCH)-$(VSCODE_VERSION).zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force exec { 7z.exe a -tzip $ArchivePath ..\VSCode-win32-$(VSCODE_ARCH)\* "-xr!CodeSignSummary*.md" } echo "##vso[task.setvariable variable=CLIENT_PATH]$ArchivePath" echo "Listing archive contents" 7z.exe l $ArchivePath condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) displayName: Package client - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) } echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath" echo "Listing archive contents" 7z.exe l $ArchivePath condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true')) displayName: Package server - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web } echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath" echo "Listing archive contents" 7z.exe l $ArchivePath condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true')) displayName: Package server (web) - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm exec -- npm-run-all -lp "gulp vscode-win32-$(VSCODE_ARCH)-system-setup -- --sign" "gulp vscode-win32-$(VSCODE_ARCH)-user-setup -- --sign" } $SystemSetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" $UserSetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeUserSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" mv .build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe $SystemSetupPath mv .build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe $UserSetupPath echo "##vso[task.setvariable variable=SYSTEM_SETUP_PATH]$SystemSetupPath" echo "##vso[task.setvariable variable=USER_SETUP_PATH]$UserSetupPath" env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Build setup packages (system, user) - powershell: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) displayName: Generate artifact prefix - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(CLIENT_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH) sbomPackageName: "VS Code Windows $(VSCODE_ARCH)" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SERVER_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_server_win32_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH) sbomPackageName: "VS Code Windows $(VSCODE_ARCH) Server" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(WEB_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_web_win32_$(VSCODE_ARCH)_archive sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)-web sbomPackageName: "VS Code Windows $(VSCODE_ARCH) Web" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(SYSTEM_SETUP_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_setup sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH) sbomPackageName: "VS Code Windows $(VSCODE_ARCH) System Setup" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['SYSTEM_SETUP_PATH'], '')) displayName: Publish system setup - task: 1ES.PublishPipelineArtifact@1 inputs: targetPath: $(USER_SETUP_PATH) artifactName: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_user-setup sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH) sbomPackageName: "VS Code Windows $(VSCODE_ARCH) User Setup" sbomPackageVersion: $(Build.SourceVersion) condition: and(succeededOrFailed(), ne(variables['USER_SETUP_PATH'], '')) displayName: Publish user setup ================================================ FILE: build/azure-pipelines/win32/retry.ps1 ================================================ function Retry { [CmdletBinding()] param( [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd ) $retry = 0 while ($retry++ -lt 5) { try { & $cmd return } catch { # noop } } throw "Max retries reached" } ================================================ FILE: build/azure-pipelines/win32/sdl-scan-win32.yml ================================================ parameters: - name: VSCODE_ARCH type: string - name: VSCODE_QUALITY type: string steps: - task: NodeTool@0 inputs: versionSource: fromFile versionFilePath: .nvmrc nodejsMirror: https://github.com/joaomoreno/node-mirror/releases/download - task: UsePythonVersion@0 inputs: versionSpec: "3.x" addToPath: true - template: ../distro/download-distro.yml@self - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" # Set the private NPM registry to the global npmrc file # so that authentication works for subfolders like build/, remote/, extensions/ etc # which does not have their own .npmrc file exec { npm config set registry "$env:NPM_REGISTRY" } $NpmrcPath = (npm config get userconfig) echo "##vso[task.setvariable variable=NPMRC_PATH]$NpmrcPath" condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM - task: npmAuthenticate@0 inputs: workingFile: $(NPMRC_PATH) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - pwsh: | $includes = @' { 'target_defaults': { 'conditions': [ ['OS=="win"', { 'msvs_settings': { 'VCCLCompilerTool': { 'AdditionalOptions': [ '/Zi', '/FS' ], }, 'VCLinkerTool': { 'AdditionalOptions': [ '/profile' ] } } }] ] } } '@ if (!(Test-Path "~/.gyp")) { mkdir "~/.gyp" } echo $includes > "~/.gyp/include.gypi" displayName: Create include.gypi - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { npm ci } env: npm_config_arch: ${{ parameters.VSCODE_ARCH }} npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" retryCountOnTaskFailure: 5 displayName: Install dependencies - script: node build/azure-pipelines/distro/mixin-npm displayName: Mixin distro node modules - script: node build/azure-pipelines/distro/mixin-quality displayName: Mixin distro quality env: VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - powershell: npm run compile displayName: Compile - powershell: npm run gulp "vscode-symbols-win32-${{ parameters.VSCODE_ARCH }}" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Download Symbols - powershell: | Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.exe" Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.dll" Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.node" Get-ChildItem '$(Agent.BuildDirectory)\scanbin' -Recurse -Filter "*.pdb" displayName: List files - task: CopyFiles@2 displayName: 'Collect Symbols for API Scan' inputs: SourceFolder: $(Agent.BuildDirectory) Contents: 'scanbin\**\*.pdb' TargetFolder: '$(Agent.BuildDirectory)\symbols' flattenFolders: true condition: succeeded() - task: APIScan@2 inputs: softwareFolder: $(Agent.BuildDirectory)\scanbin softwareName: 'vscode-client' softwareVersionNum: '1' symbolsFolder: 'srv*https://symweb.azurefd.net;$(Agent.BuildDirectory)\symbols' isLargeApp: false toolVersion: 'Latest' azureSubscription: 'vscode-apiscan' displayName: Run ApiScan condition: succeeded() env: AzureServicesAuthConnectionString: RunAs=App;AppId=c0940da5-8bd3-4dd3-8af1-40774b50edbd;TenantId=72f988bf-86f1-41af-91ab-2d7cd011db47;ServiceConnectionId=3e55d992-b60d-414d-9071-e4fad359c748; SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: PublishSecurityAnalysisLogs@3 inputs: ArtifactName: CodeAnalysisLogs ArtifactType: Container PublishProcessedResults: false AllTools: true # TSA Upload - task: securedevelopmentteam.vss-secure-development-tools.build-task-uploadtotsa.TSAUpload@2 displayName: TSA Upload continueOnError: true inputs: GdnPublishTsaOnboard: true GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json' ================================================ FILE: build/buildfile.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * @param {string} name * @returns {import('./lib/bundle').IEntryPoint} */ function createModuleDescription(name) { return { name }; } exports.workerEditor = createModuleDescription('vs/editor/common/services/editorWebWorkerMain'); exports.workerExtensionHost = createModuleDescription('vs/workbench/api/worker/extensionHostWorkerMain'); exports.workerNotebook = createModuleDescription('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain'); exports.workerLanguageDetection = createModuleDescription('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain'); exports.workerLocalFileSearch = createModuleDescription('vs/workbench/services/search/worker/localFileSearchMain'); exports.workerProfileAnalysis = createModuleDescription('vs/platform/profiling/electron-sandbox/profileAnalysisWorkerMain'); exports.workerOutputLinks = createModuleDescription('vs/workbench/contrib/output/common/outputLinkComputerMain'); exports.workerBackgroundTokenization = createModuleDescription('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain'); exports.workbenchDesktop = [ createModuleDescription('vs/workbench/contrib/debug/node/telemetryApp'), createModuleDescription('vs/platform/files/node/watcher/watcherMain'), createModuleDescription('vs/platform/terminal/node/ptyHostMain'), createModuleDescription('vs/workbench/api/node/extensionHostProcess'), createModuleDescription('vs/workbench/workbench.desktop.main') ]; exports.workbenchWeb = createModuleDescription('vs/workbench/workbench.web.main'); exports.keyboardMaps = [ createModuleDescription('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux'), createModuleDescription('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin'), createModuleDescription('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win') ]; exports.code = [ // 'vs/code/electron-main/main' is not included here because it comes in via ./src/main.js // 'vs/code/node/cli' is not included here because it comes in via ./src/cli.js createModuleDescription('vs/code/node/cliProcessMain'), createModuleDescription('vs/code/electron-utility/sharedProcess/sharedProcessMain'), createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain'), createModuleDescription('vs/code/electron-sandbox/workbench/workbench'), createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorer') ]; exports.codeWeb = createModuleDescription('vs/code/browser/workbench/workbench'); exports.codeServer = [ // 'vs/server/node/server.main' is not included here because it gets inlined via ./src/server-main.js // 'vs/server/node/server.cli' is not included here because it gets inlined via ./src/server-cli.js createModuleDescription('vs/workbench/api/node/extensionHostProcess'), createModuleDescription('vs/platform/files/node/watcher/watcherMain'), createModuleDescription('vs/platform/terminal/node/ptyHostMain') ]; exports.entrypoint = createModuleDescription; ================================================ FILE: build/builtin/.eslintrc ================================================ { "env": { "node": true, "es6": true, "browser": true }, "rules": { "no-console": 0, "no-cond-assign": 0, "no-unused-vars": 1, "no-extra-semi": "warn", "semi": "warn" }, "extends": "eslint:recommended", "parserOptions": { "ecmaFeatures": { "experimentalObjectRestSpread": true } } } ================================================ FILE: build/builtin/browser-main.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check const fs = require('fs'); const path = require('path'); const os = require('os'); const { ipcRenderer } = require('electron'); const builtInExtensionsPath = path.join(__dirname, '..', '..', 'product.json'); const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json'); /** * @param {string} filePath */ function readJson(filePath) { return JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' })); } /** * @param {string} filePath * @param {any} obj */ function writeJson(filePath, obj) { fs.writeFileSync(filePath, JSON.stringify(obj, null, 2)); } /** * @param {HTMLFormElement} form * @param {string} id * @param {string} title * @param {string} value * @param {boolean} checked */ function renderOption(form, id, title, value, checked) { const input = document.createElement('input'); input.type = 'radio'; input.id = id; input.name = 'choice'; input.value = value; input.checked = !!checked; form.appendChild(input); const label = document.createElement('label'); label.setAttribute('for', id); label.textContent = title; form.appendChild(label); return input; } /** * @param {HTMLElement} el * @param {any} state */ function render(el, state) { /** * @param {any} state */ function setState(state) { try { writeJson(controlFilePath, state.control); } catch (err) { console.error(err); } el.innerHTML = ''; render(el, state); } const ul = document.createElement('ul'); const { builtin, control } = state; for (const ext of builtin) { const controlState = control[ext.name] || 'marketplace'; const li = document.createElement('li'); ul.appendChild(li); const name = document.createElement('code'); name.textContent = ext.name; li.appendChild(name); const form = document.createElement('form'); li.appendChild(form); const marketplaceInput = renderOption(form, `marketplace-${ext.name}`, 'Marketplace', 'marketplace', controlState === 'marketplace'); marketplaceInput.onchange = function () { control[ext.name] = 'marketplace'; setState({ builtin, control }); }; const disabledInput = renderOption(form, `disabled-${ext.name}`, 'Disabled', 'disabled', controlState === 'disabled'); disabledInput.onchange = function () { control[ext.name] = 'disabled'; setState({ builtin, control }); }; let local = undefined; if (controlState !== 'marketplace' && controlState !== 'disabled') { local = controlState; } const localInput = renderOption(form, `local-${ext.name}`, 'Local', 'local', !!local); localInput.onchange = async function () { const result = await ipcRenderer.invoke('pickdir'); if (result) { control[ext.name] = result; setState({ builtin, control }); } }; if (local) { const localSpan = document.createElement('code'); localSpan.className = 'local'; localSpan.textContent = local; form.appendChild(localSpan); } } el.appendChild(ul); } function main() { const el = document.getElementById('extensions'); const builtin = readJson(builtInExtensionsPath).builtInExtensions; let control; try { control = readJson(controlFilePath); } catch (err) { control = {}; } if (el) { render(el, { builtin, control }); } } window.onload = main; ================================================ FILE: build/builtin/index.html ================================================ Manage Built-in Extensions

Built-in Extensions

================================================ FILE: build/builtin/main.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // @ts-check const { app, BrowserWindow, ipcMain, dialog } = require('electron'); const url = require('url'); const path = require('path'); let window = null; ipcMain.handle('pickdir', async () => { const result = await dialog.showOpenDialog(window, { title: 'Choose Folder', properties: ['openDirectory'] }); if (result.canceled || result.filePaths.length < 1) { return undefined; } return result.filePaths[0]; }); app.once('ready', () => { window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, enableWebSQL: false } }); window.setMenuBarVisibility(false); window.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })); // window.webContents.openDevTools(); window.once('closed', () => window = null); }); app.on('window-all-closed', () => app.quit()); ================================================ FILE: build/builtin/package.json ================================================ { "name": "builtin", "version": "0.1.0", "main": "main.js" } ================================================ FILE: build/checksums/electron.txt ================================================ c9b82c9f381742e839fea00aeb14f24519bcaf38a0f4eed25532191701f9535b *chromedriver-v34.3.2-darwin-arm64.zip d556c1e2b06f1bf131e83c2fb981de755c28e1083a884d257eb964815be16b0c *chromedriver-v34.3.2-darwin-x64.zip 1cabad4f3303ac2ff172a9f22185f64944dbaa6fc68271609077158eaefdee35 *chromedriver-v34.3.2-linux-arm64.zip 4213ce52c72ef414179b5c5c22ae8423847ff030d438296bd6c2aac763930a7b *chromedriver-v34.3.2-linux-armv7l.zip 3c64c08221fdfc0f4be60ea8b1b126f2ecca45f60001b63778522f711022c6ea *chromedriver-v34.3.2-linux-x64.zip e8388734d88e011cb6cd79795431de9206820749219d80565ee49d90501d2bf3 *chromedriver-v34.3.2-mas-arm64.zip 3ad1dd37bd6e0bb37e8503898db7aedd56bd5213e6d6760b05c3d11f4625062b *chromedriver-v34.3.2-mas-x64.zip d567b481a0f5d88e84bba7718f89fb08f56363bfc4cb5914e1c2086358a5c252 *chromedriver-v34.3.2-win32-arm64.zip df6732e9dc61cb20a3c0b2a2de453aac7e2bd54e7cbff43512afa614852c15fa *chromedriver-v34.3.2-win32-ia32.zip dda0765c8d064924632e18cd152014ecd767f3808fc51c8249a053bfb7ca70a2 *chromedriver-v34.3.2-win32-x64.zip 1945f15caff98f2e0f1ee539c483d352fb8d4d0c13f342caa7abe247676d828c *electron-api.json c078bbf727b3c3026f60e07a0f4643b85c06c581b54be017d0a6c284ba6772d3 *electron-v34.3.2-darwin-arm64-dsym-snapshot.zip 35f587754d6a3272606258386bf73688d63dd53c7e572d3a7cbaae6f3f60bdae *electron-v34.3.2-darwin-arm64-dsym.zip 08b14ee02c98353de3c738120dfd017322666e82b914a7f6de9b9888dcc5c0f0 *electron-v34.3.2-darwin-arm64-symbols.zip 2a4aa7e8fa30f229e465ebd18d3e4722e2b41529dc51a68a954d333a7e556ffe *electron-v34.3.2-darwin-arm64.zip 1509ccdeb80024f5e3edd5ecf804b4cef4e47ea2bd74e33ef0b39044b0ccf892 *electron-v34.3.2-darwin-x64-dsym-snapshot.zip 3bbe5d587c3f582ed8c126b0fb635cc02ad9a14d077b04892fe6f862092445b0 *electron-v34.3.2-darwin-x64-dsym.zip fa7ece82e6ecaf1c94ed341e8ebff98e64687c68fe113f52cd9a21400302e22f *electron-v34.3.2-darwin-x64-symbols.zip 23938c62257a65a863ed7aa7c7966ba5f257a7d3dc16c78293e826962cc39c5c *electron-v34.3.2-darwin-x64.zip 0547eecf8ab538d74fa854f591ce8b888a3dbb339256d2db3038e7bb2c6dd929 *electron-v34.3.2-linux-arm64-debug.zip 676d0dc2b1c1c85c8b2abbb8cd5376ee22ecdb910493b910d9ae5a998532136a *electron-v34.3.2-linux-arm64-symbols.zip 774e4ccb39d553e5487994a9f8c60774a90f08cdb049ff65f3963fc27c969ff2 *electron-v34.3.2-linux-arm64.zip 0547eecf8ab538d74fa854f591ce8b888a3dbb339256d2db3038e7bb2c6dd929 *electron-v34.3.2-linux-armv7l-debug.zip ba33bf53fcb35dea568a2795f5b23ecf46c218abe8258946611c72a1f42f716c *electron-v34.3.2-linux-armv7l-symbols.zip 73ae92c8fffb351d3a455569cf57ce9a3f676f42bf61939c613c607fe0fc3bfb *electron-v34.3.2-linux-armv7l.zip e61a9a69dd7ea6f2687708a8e83516670cdea53c728226e598e2f6f1fad5b77b *electron-v34.3.2-linux-x64-debug.zip f1a04df7fe67dd1cd29e7b87871525458d2eb24c0cf3b5835a1c56974707562a *electron-v34.3.2-linux-x64-symbols.zip 7b74c0c4fae82e27c7e9cbca13e9763e046113dba8737d3e27de9a0b300ac87e *electron-v34.3.2-linux-x64.zip 8571a6aa83e00925ceb39fdc5a45a9f6b9aa3d92fd84951c6f252ed723aea4ae *electron-v34.3.2-mas-arm64-dsym-snapshot.zip 477410c6f9a6c5eeaedf376058a02c2996fc0a334aa40eeec7d3734c09347f4d *electron-v34.3.2-mas-arm64-dsym.zip c2e62dcd6630cb51b2d8e2869e74e47d29bda785521cea6e82e546d0fc58aabb *electron-v34.3.2-mas-arm64-symbols.zip a1698e8546a062fd59b7f8e5507a7f3220fb00b347f2377de83fc9a07f7f3507 *electron-v34.3.2-mas-arm64.zip 741a24ac230a3651dca81d211f9f00b835c428a5ed0c5f67d370d4e88b62f8d6 *electron-v34.3.2-mas-x64-dsym-snapshot.zip aeff97ec9e5c9e173ac89e38acd94476025c5640d5f27be1e8c2abd54398bab3 *electron-v34.3.2-mas-x64-dsym.zip 9f14b66b1d612ac66697288e8763171c388f7f200854871a5f0ab464a6a921c2 *electron-v34.3.2-mas-x64-symbols.zip c979d7e7175f1e8e03ca187997d4c156b878189fc3611b347fadebcb16f3e027 *electron-v34.3.2-mas-x64.zip f43c700641e8220205dd356952e32718d113cf530520c4ed7209b59851eac266 *electron-v34.3.2-win32-arm64-pdb.zip 3ba6e01c99bffac6b5dd3fd6f122ecdb571cf6f675dc5498c65050bd7a382ef8 *electron-v34.3.2-win32-arm64-symbols.zip c23f84aabb09c24cd2ae759a547fdba4206af19a3bb0f4554a91cd9528648ad0 *electron-v34.3.2-win32-arm64-toolchain-profile.zip 9b9cb65d75a16782088b492f9ef3bb4d27525012b819c12bf29bd27e159d749b *electron-v34.3.2-win32-arm64.zip 1006e7af4c149114b5ebc3497617aaa6cd1bb0b131e0a225fd73709ff308f9c5 *electron-v34.3.2-win32-ia32-pdb.zip 1ecb6430cd04454f08f557c9579163f3552144bfcc0b67b768dad8868b5b891d *electron-v34.3.2-win32-ia32-symbols.zip c23f84aabb09c24cd2ae759a547fdba4206af19a3bb0f4554a91cd9528648ad0 *electron-v34.3.2-win32-ia32-toolchain-profile.zip d004fd5f853754001fafaec33e383d1950b30c935ee71b297ec1c9e084355e9b *electron-v34.3.2-win32-ia32.zip 4e0721552fd2f09e9466e88089af8b965f1bfbc4ae00a59aaf6245b1d1efabfd *electron-v34.3.2-win32-x64-pdb.zip 9dea812a7e7cd0fb18e5fed9a99db5531959a068c24d3c0ecedceb644cd3ffa0 *electron-v34.3.2-win32-x64-symbols.zip c23f84aabb09c24cd2ae759a547fdba4206af19a3bb0f4554a91cd9528648ad0 *electron-v34.3.2-win32-x64-toolchain-profile.zip 1785e161420fb90d2331c26e50bba3413cae9625b7db3c8524ea02ade631efba *electron-v34.3.2-win32-x64.zip 722b304c31ddac58b0083d94a241c5276464f04bd8ea4fcbfd33051d197be103 *electron.d.ts 31ce159b2e47d1de5bc907d8e1c89726b0f2ba530ec2e9d7a8e5c723b1ccf6e0 *ffmpeg-v34.3.2-darwin-arm64.zip 565539bac64a6ee9cf6f188070f520210a1507341718f5dc388ac7c454b1e1d5 *ffmpeg-v34.3.2-darwin-x64.zip 6006ea0f46ab229feb2685be086b0fafd65981e2939dd2218a078459c75ab527 *ffmpeg-v34.3.2-linux-arm64.zip 9404ce2e85df7c40f809f2cf62c7af607de299839fe6b7ae978c3015500abcc8 *ffmpeg-v34.3.2-linux-armv7l.zip 79aec96898b7e2462826780ee0b52b9ab299dc662af333e128a34fd5ddae87f1 *ffmpeg-v34.3.2-linux-x64.zip 9190743c78210574faf5d5ecb82a00f8fa15e5f2253378cb925a99ca9d39961b *ffmpeg-v34.3.2-mas-arm64.zip 48915adcb1a6342efeda896035101300f0432c0304cfb38f2378e98c6309ebae *ffmpeg-v34.3.2-mas-x64.zip 745d5ef786de6d4a720475079836e2fda7b501cfcd255819485a47de5b24b74e *ffmpeg-v34.3.2-win32-arm64.zip d0d86d60978439dc8ae4a723d4e4c1f853891d596bfd84033440a232fa762e2f *ffmpeg-v34.3.2-win32-ia32.zip 4441539fd8c9cbe79880ff1bade9bdc0c3744c33d7409130af6404e57ee401ff *ffmpeg-v34.3.2-win32-x64.zip 39edd1eeefe881aa75af0e438204e0b1c6e6724e34fa5819109276331c0c2c9a *hunspell_dictionaries.zip 20dd417536e5f4ebc01f480221284c0673729c27b082bc04e2922f16cd571719 *libcxx-objects-v34.3.2-linux-arm64.zip 7e53c5779c04f895f8282c0450ec4a63074d15a0e910e41006cfea133d0288af *libcxx-objects-v34.3.2-linux-armv7l.zip 92e2283c924ab523ffec3ea22513beaab6417f7fc3d570f57d51a1e1ceb7f510 *libcxx-objects-v34.3.2-linux-x64.zip 9bf3c6e8ad68f523fe086fada4148dd04e5bb0b9290d104873e66f2584a5cf50 *libcxx_headers.zip 34e4b44f9c5e08b557a2caed55456ce7690abab910196a783a2a47b58d2b9ac9 *libcxxabi_headers.zip 11f67635e6659f9188198e4086c51b89890b61a22f6c17c99eff35595ee8f51d *mksnapshot-v34.3.2-darwin-arm64.zip c0add9ef4ac27c73fa043d04b4c9635fd3fd9f5c16d7a03e961864ba05252813 *mksnapshot-v34.3.2-darwin-x64.zip 6262adf86a340d8d28059937b01ef1117b93212e945fddbceea5c18d7e7c64f0 *mksnapshot-v34.3.2-linux-arm64-x64.zip f7db8ebe91a1cc8d24ef6aad12949a18d8e4975ac296e3e5e9ecd88c9bccb143 *mksnapshot-v34.3.2-linux-armv7l-x64.zip 6642038e86bda362980ff1c8973a404e2b02efdd87de9e35b650fc1e743833da *mksnapshot-v34.3.2-linux-x64.zip 15883bf8e8cd737c3682d1e719d7cbac92f50b525681aac324dca876861dfc7d *mksnapshot-v34.3.2-mas-arm64.zip 4da23a950bfcc377ef21c37d496017ab4c36da03f3b41049ac114042c42608ce *mksnapshot-v34.3.2-mas-x64.zip fab59573d3c2f9bdf31146a1896d24ac0c51f736aad86d2f3c7ecef13c05a7fd *mksnapshot-v34.3.2-win32-arm64-x64.zip 66f25e07c6f8d5d2009577a129440255a3baf63c929a5b60b2e77cd52e46105b *mksnapshot-v34.3.2-win32-ia32.zip 8168bfbf61882cfac80aed1e71e364e1c7f2fccd11eac298e6abade8b46894ea *mksnapshot-v34.3.2-win32-x64.zip ================================================ FILE: build/checksums/nodejs.txt ================================================ 1f15b7ed18a580af31cf32bc126572292d820f547bf55bf9cdce08041a24e1d9 node-v20.18.3-darwin-arm64.tar.gz ba668f64df9239843fefcef095ee539f5ac5aa1b0fc15a71f1ecca16abedec7a node-v20.18.3-darwin-x64.tar.gz 93a9df19238adfaa289f4784041d03edaf2fdd89fbb247faffca2fe4a1000703 node-v20.18.3-linux-arm64.tar.gz 8a84eb34287db6a273066934d7195e429f57b91686b62fc19497210204a2b3de node-v20.18.3-linux-armv7l.tar.gz 9fc3952da39b20d1fcfdb777b198cc035485afbbb1004b4df93f35245d61151e node-v20.18.3-linux-x64.tar.gz 4258e333f4b95060681d61bffa762542a8068547d3dffebe57c575b38d380dda win-arm64/node.exe 528a9aa64888a2a3ba71c6aea89434dd5ab5cb3caa9f0f31345cf5facf685ab0 win-x64/node.exe ================================================ FILE: build/checksums/vscode-sysroot.txt ================================================ 0de422a81683cf9e8cf875dbd1e0c27545ac3c775b2d53015daf3ca2b31d3f15 aarch64-linux-gnu-glibc-2.28.tar.gz 7aea163f7fad8cc50000c86b5108be880121d35e2f55d016ef8c96bbe54129eb arm-rpi-linux-gnueabihf-glibc-2.28.tar.gz dbb927408393041664a020661f2641c9785741be3d29b050b9dac58980967784 x86_64-linux-gnu-glibc-2.28.tar.gz ================================================ FILE: build/darwin/create-universal-app.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const minimatch_1 = __importDefault(require("minimatch")); const vscode_universal_bundler_1 = require("vscode-universal-bundler"); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); async function main(buildDir) { const arch = process.env['VSCODE_ARCH']; if (!buildDir) { throw new Error('Build dir not provided'); } const product = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'product.json'), 'utf8')); const appName = product.nameLong + '.app'; const x64AppPath = path_1.default.join(buildDir, 'VSCode-darwin-x64', appName); const arm64AppPath = path_1.default.join(buildDir, 'VSCode-darwin-arm64', appName); const asarRelativePath = path_1.default.join('Contents', 'Resources', 'app', 'node_modules.asar'); const outAppPath = path_1.default.join(buildDir, `VSCode-darwin-${arch}`, appName); const productJsonPath = path_1.default.resolve(outAppPath, 'Contents', 'Resources', 'app', 'product.json'); const filesToSkip = [ '**/CodeResources', '**/Credits.rtf', '**/policies/{*.mobileconfig,**/*.plist}', // TODO: Should we consider expanding this to other files in this area? '**/node_modules/@parcel/node-addon-api/nothing.target.mk' ]; await (0, vscode_universal_bundler_1.makeUniversalApp)({ x64AppPath, arm64AppPath, asarPath: asarRelativePath, outAppPath, force: true, mergeASARs: true, x64ArchFiles: '*/kerberos.node', filesToSkipComparison: (file) => { for (const expected of filesToSkip) { if ((0, minimatch_1.default)(file, expected)) { return true; } } return false; } }); const productJson = JSON.parse(fs_1.default.readFileSync(productJsonPath, 'utf8')); Object.assign(productJson, { darwinUniversalAssetId: 'darwin-universal' }); fs_1.default.writeFileSync(productJsonPath, JSON.stringify(productJson, null, '\t')); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=create-universal-app.js.map ================================================ FILE: build/darwin/create-universal-app.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import fs from 'fs'; import minimatch from 'minimatch'; import { makeUniversalApp } from 'vscode-universal-bundler'; const root = path.dirname(path.dirname(__dirname)); async function main(buildDir?: string) { const arch = process.env['VSCODE_ARCH']; if (!buildDir) { throw new Error('Build dir not provided'); } const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8')); const appName = product.nameLong + '.app'; const x64AppPath = path.join(buildDir, 'VSCode-darwin-x64', appName); const arm64AppPath = path.join(buildDir, 'VSCode-darwin-arm64', appName); const asarRelativePath = path.join('Contents', 'Resources', 'app', 'node_modules.asar'); const outAppPath = path.join(buildDir, `VSCode-darwin-${arch}`, appName); const productJsonPath = path.resolve(outAppPath, 'Contents', 'Resources', 'app', 'product.json'); const filesToSkip = [ '**/CodeResources', '**/Credits.rtf', '**/policies/{*.mobileconfig,**/*.plist}', // TODO: Should we consider expanding this to other files in this area? '**/node_modules/@parcel/node-addon-api/nothing.target.mk' ]; await makeUniversalApp({ x64AppPath, arm64AppPath, asarPath: asarRelativePath, outAppPath, force: true, mergeASARs: true, x64ArchFiles: '*/kerberos.node', filesToSkipComparison: (file: string) => { for (const expected of filesToSkip) { if (minimatch(file, expected)) { return true; } } return false; } }); const productJson = JSON.parse(fs.readFileSync(productJsonPath, 'utf8')); Object.assign(productJson, { darwinUniversalAssetId: 'darwin-universal' }); fs.writeFileSync(productJsonPath, JSON.stringify(productJson, null, '\t')); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/darwin/sign.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const electron_osx_sign_1 = __importDefault(require("electron-osx-sign")); const cross_spawn_promise_1 = require("@malept/cross-spawn-promise"); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); function getElectronVersion() { const npmrc = fs_1.default.readFileSync(path_1.default.join(root, '.npmrc'), 'utf8'); const target = /^target="(.*)"$/m.exec(npmrc)[1]; return target; } async function main(buildDir) { const tempDir = process.env['AGENT_TEMPDIRECTORY']; const arch = process.env['VSCODE_ARCH']; const identity = process.env['CODESIGN_IDENTITY']; if (!buildDir) { throw new Error('$AGENT_BUILDDIRECTORY not set'); } if (!tempDir) { throw new Error('$AGENT_TEMPDIRECTORY not set'); } const product = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'product.json'), 'utf8')); const baseDir = path_1.default.dirname(__dirname); const appRoot = path_1.default.join(buildDir, `VSCode-darwin-${arch}`); const appName = product.nameLong + '.app'; const appFrameworkPath = path_1.default.join(appRoot, appName, 'Contents', 'Frameworks'); const helperAppBaseName = product.nameShort; const gpuHelperAppName = helperAppBaseName + ' Helper (GPU).app'; const rendererHelperAppName = helperAppBaseName + ' Helper (Renderer).app'; const pluginHelperAppName = helperAppBaseName + ' Helper (Plugin).app'; const infoPlistPath = path_1.default.resolve(appRoot, appName, 'Contents', 'Info.plist'); const defaultOpts = { app: path_1.default.join(appRoot, appName), platform: 'darwin', entitlements: path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'app-entitlements.plist'), 'entitlements-inherit': path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'app-entitlements.plist'), hardenedRuntime: true, 'pre-auto-entitlements': false, 'pre-embed-provisioning-profile': false, keychain: path_1.default.join(tempDir, 'buildagent.keychain'), version: getElectronVersion(), identity, 'gatekeeper-assess': false }; const appOpts = { ...defaultOpts, // TODO(deepak1556): Incorrectly declared type in electron-osx-sign ignore: (filePath) => { return filePath.includes(gpuHelperAppName) || filePath.includes(rendererHelperAppName) || filePath.includes(pluginHelperAppName); } }; const gpuHelperOpts = { ...defaultOpts, app: path_1.default.join(appFrameworkPath, gpuHelperAppName), entitlements: path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-gpu-entitlements.plist'), 'entitlements-inherit': path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-gpu-entitlements.plist'), }; const rendererHelperOpts = { ...defaultOpts, app: path_1.default.join(appFrameworkPath, rendererHelperAppName), entitlements: path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-renderer-entitlements.plist'), 'entitlements-inherit': path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-renderer-entitlements.plist'), }; const pluginHelperOpts = { ...defaultOpts, app: path_1.default.join(appFrameworkPath, pluginHelperAppName), entitlements: path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), 'entitlements-inherit': path_1.default.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), }; // Only overwrite plist entries for x64 and arm64 builds, // universal will get its copy from the x64 build. if (arch !== 'universal') { await (0, cross_spawn_promise_1.spawn)('plutil', [ '-insert', 'NSAppleEventsUsageDescription', '-string', 'An application in Visual Studio Code wants to use AppleScript.', `${infoPlistPath}` ]); await (0, cross_spawn_promise_1.spawn)('plutil', [ '-replace', 'NSMicrophoneUsageDescription', '-string', 'An application in Visual Studio Code wants to use the Microphone.', `${infoPlistPath}` ]); await (0, cross_spawn_promise_1.spawn)('plutil', [ '-replace', 'NSCameraUsageDescription', '-string', 'An application in Visual Studio Code wants to use the Camera.', `${infoPlistPath}` ]); } await electron_osx_sign_1.default.signAsync(gpuHelperOpts); await electron_osx_sign_1.default.signAsync(rendererHelperOpts); await electron_osx_sign_1.default.signAsync(pluginHelperOpts); await electron_osx_sign_1.default.signAsync(appOpts); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=sign.js.map ================================================ FILE: build/darwin/sign.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import codesign from 'electron-osx-sign'; import { spawn } from '@malept/cross-spawn-promise'; const root = path.dirname(path.dirname(__dirname)); function getElectronVersion(): string { const npmrc = fs.readFileSync(path.join(root, '.npmrc'), 'utf8'); const target = /^target="(.*)"$/m.exec(npmrc)![1]; return target; } async function main(buildDir?: string): Promise { const tempDir = process.env['AGENT_TEMPDIRECTORY']; const arch = process.env['VSCODE_ARCH']; const identity = process.env['CODESIGN_IDENTITY']; if (!buildDir) { throw new Error('$AGENT_BUILDDIRECTORY not set'); } if (!tempDir) { throw new Error('$AGENT_TEMPDIRECTORY not set'); } const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8')); const baseDir = path.dirname(__dirname); const appRoot = path.join(buildDir, `VSCode-darwin-${arch}`); const appName = product.nameLong + '.app'; const appFrameworkPath = path.join(appRoot, appName, 'Contents', 'Frameworks'); const helperAppBaseName = product.nameShort; const gpuHelperAppName = helperAppBaseName + ' Helper (GPU).app'; const rendererHelperAppName = helperAppBaseName + ' Helper (Renderer).app'; const pluginHelperAppName = helperAppBaseName + ' Helper (Plugin).app'; const infoPlistPath = path.resolve(appRoot, appName, 'Contents', 'Info.plist'); const defaultOpts: codesign.SignOptions = { app: path.join(appRoot, appName), platform: 'darwin', entitlements: path.join(baseDir, 'azure-pipelines', 'darwin', 'app-entitlements.plist'), 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'app-entitlements.plist'), hardenedRuntime: true, 'pre-auto-entitlements': false, 'pre-embed-provisioning-profile': false, keychain: path.join(tempDir, 'buildagent.keychain'), version: getElectronVersion(), identity, 'gatekeeper-assess': false }; const appOpts = { ...defaultOpts, // TODO(deepak1556): Incorrectly declared type in electron-osx-sign ignore: (filePath: string) => { return filePath.includes(gpuHelperAppName) || filePath.includes(rendererHelperAppName) || filePath.includes(pluginHelperAppName); } }; const gpuHelperOpts: codesign.SignOptions = { ...defaultOpts, app: path.join(appFrameworkPath, gpuHelperAppName), entitlements: path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-gpu-entitlements.plist'), 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-gpu-entitlements.plist'), }; const rendererHelperOpts: codesign.SignOptions = { ...defaultOpts, app: path.join(appFrameworkPath, rendererHelperAppName), entitlements: path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-renderer-entitlements.plist'), 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-renderer-entitlements.plist'), }; const pluginHelperOpts: codesign.SignOptions = { ...defaultOpts, app: path.join(appFrameworkPath, pluginHelperAppName), entitlements: path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), }; // Only overwrite plist entries for x64 and arm64 builds, // universal will get its copy from the x64 build. if (arch !== 'universal') { await spawn('plutil', [ '-insert', 'NSAppleEventsUsageDescription', '-string', 'An application in Visual Studio Code wants to use AppleScript.', `${infoPlistPath}` ]); await spawn('plutil', [ '-replace', 'NSMicrophoneUsageDescription', '-string', 'An application in Visual Studio Code wants to use the Microphone.', `${infoPlistPath}` ]); await spawn('plutil', [ '-replace', 'NSCameraUsageDescription', '-string', 'An application in Visual Studio Code wants to use the Camera.', `${infoPlistPath}` ]); } await codesign.signAsync(gpuHelperOpts); await codesign.signAsync(rendererHelperOpts); await codesign.signAsync(pluginHelperOpts); await codesign.signAsync(appOpts as any); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/darwin/verify-macho.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = __importDefault(require("assert")); const path_1 = __importDefault(require("path")); const promises_1 = require("fs/promises"); const cross_spawn_promise_1 = require("@malept/cross-spawn-promise"); const MACHO_PREFIX = 'Mach-O '; const MACHO_64_MAGIC_LE = 0xfeedfacf; const MACHO_UNIVERSAL_MAGIC_LE = 0xbebafeca; const MACHO_ARM64_CPU_TYPE = new Set([ 0x0c000001, 0x0100000c, ]); const MACHO_X86_64_CPU_TYPE = new Set([ 0x07000001, 0x01000007, ]); async function read(file, buf, offset, length, position) { let filehandle; try { filehandle = await (0, promises_1.open)(file); await filehandle.read(buf, offset, length, position); } finally { await filehandle?.close(); } } async function checkMachOFiles(appPath, arch) { const visited = new Set(); const invalidFiles = []; const header = Buffer.alloc(8); const file_header_entry_size = 20; const checkx86_64Arch = (arch === 'x64'); const checkArm64Arch = (arch === 'arm64'); const checkUniversalArch = (arch === 'universal'); const traverse = async (p) => { p = await (0, promises_1.realpath)(p); if (visited.has(p)) { return; } visited.add(p); const info = await (0, promises_1.stat)(p); if (info.isSymbolicLink()) { return; } if (info.isFile()) { let fileOutput = ''; try { fileOutput = await (0, cross_spawn_promise_1.spawn)('file', ['--brief', '--no-pad', p]); } catch (e) { if (e instanceof cross_spawn_promise_1.ExitCodeError) { /* silently accept error codes from "file" */ } else { throw e; } } if (fileOutput.startsWith(MACHO_PREFIX)) { console.log(`Verifying architecture of ${p}`); read(p, header, 0, 8, 0).then(_ => { const header_magic = header.readUInt32LE(); if (header_magic === MACHO_64_MAGIC_LE) { const cpu_type = header.readUInt32LE(4); if (checkUniversalArch) { invalidFiles.push(p); } else if (checkArm64Arch && !MACHO_ARM64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } else if (checkx86_64Arch && !MACHO_X86_64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } } else if (header_magic === MACHO_UNIVERSAL_MAGIC_LE) { const num_binaries = header.readUInt32BE(4); assert_1.default.equal(num_binaries, 2); const file_entries_size = file_header_entry_size * num_binaries; const file_entries = Buffer.alloc(file_entries_size); read(p, file_entries, 0, file_entries_size, 8).then(_ => { for (let i = 0; i < num_binaries; i++) { const cpu_type = file_entries.readUInt32LE(file_header_entry_size * i); if (!MACHO_ARM64_CPU_TYPE.has(cpu_type) && !MACHO_X86_64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } } }); } }); } } if (info.isDirectory()) { for (const child of await (0, promises_1.readdir)(p)) { await traverse(path_1.default.resolve(p, child)); } } }; await traverse(appPath); return invalidFiles; } const archToCheck = process.argv[2]; (0, assert_1.default)(process.env['APP_PATH'], 'APP_PATH not set'); (0, assert_1.default)(archToCheck === 'x64' || archToCheck === 'arm64' || archToCheck === 'universal', `Invalid architecture ${archToCheck} to check`); checkMachOFiles(process.env['APP_PATH'], archToCheck).then(invalidFiles => { if (invalidFiles.length > 0) { console.error('\x1b[31mThe following files are built for the wrong architecture:\x1b[0m'); for (const file of invalidFiles) { console.error(`\x1b[31m${file}\x1b[0m`); } process.exit(1); } else { console.log('\x1b[32mAll files are valid\x1b[0m'); } }).catch(err => { console.error(err); process.exit(1); }); //# sourceMappingURL=verify-macho.js.map ================================================ FILE: build/darwin/verify-macho.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import assert from 'assert'; import path from 'path'; import { open, stat, readdir, realpath } from 'fs/promises'; import { spawn, ExitCodeError } from '@malept/cross-spawn-promise'; const MACHO_PREFIX = 'Mach-O '; const MACHO_64_MAGIC_LE = 0xfeedfacf; const MACHO_UNIVERSAL_MAGIC_LE = 0xbebafeca; const MACHO_ARM64_CPU_TYPE = new Set([ 0x0c000001, 0x0100000c, ]); const MACHO_X86_64_CPU_TYPE = new Set([ 0x07000001, 0x01000007, ]); async function read(file: string, buf: Buffer, offset: number, length: number, position: number) { let filehandle; try { filehandle = await open(file); await filehandle.read(buf, offset, length, position); } finally { await filehandle?.close(); } } async function checkMachOFiles(appPath: string, arch: string) { const visited = new Set(); const invalidFiles: string[] = []; const header = Buffer.alloc(8); const file_header_entry_size = 20; const checkx86_64Arch = (arch === 'x64'); const checkArm64Arch = (arch === 'arm64'); const checkUniversalArch = (arch === 'universal'); const traverse = async (p: string) => { p = await realpath(p); if (visited.has(p)) { return; } visited.add(p); const info = await stat(p); if (info.isSymbolicLink()) { return; } if (info.isFile()) { let fileOutput = ''; try { fileOutput = await spawn('file', ['--brief', '--no-pad', p]); } catch (e) { if (e instanceof ExitCodeError) { /* silently accept error codes from "file" */ } else { throw e; } } if (fileOutput.startsWith(MACHO_PREFIX)) { console.log(`Verifying architecture of ${p}`); read(p, header, 0, 8, 0).then(_ => { const header_magic = header.readUInt32LE(); if (header_magic === MACHO_64_MAGIC_LE) { const cpu_type = header.readUInt32LE(4); if (checkUniversalArch) { invalidFiles.push(p); } else if (checkArm64Arch && !MACHO_ARM64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } else if (checkx86_64Arch && !MACHO_X86_64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } } else if (header_magic === MACHO_UNIVERSAL_MAGIC_LE) { const num_binaries = header.readUInt32BE(4); assert.equal(num_binaries, 2); const file_entries_size = file_header_entry_size * num_binaries; const file_entries = Buffer.alloc(file_entries_size); read(p, file_entries, 0, file_entries_size, 8).then(_ => { for (let i = 0; i < num_binaries; i++) { const cpu_type = file_entries.readUInt32LE(file_header_entry_size * i); if (!MACHO_ARM64_CPU_TYPE.has(cpu_type) && !MACHO_X86_64_CPU_TYPE.has(cpu_type)) { invalidFiles.push(p); } } }); } }); } } if (info.isDirectory()) { for (const child of await readdir(p)) { await traverse(path.resolve(p, child)); } } }; await traverse(appPath); return invalidFiles; } const archToCheck = process.argv[2]; assert(process.env['APP_PATH'], 'APP_PATH not set'); assert(archToCheck === 'x64' || archToCheck === 'arm64' || archToCheck === 'universal', `Invalid architecture ${archToCheck} to check`); checkMachOFiles(process.env['APP_PATH'], archToCheck).then(invalidFiles => { if (invalidFiles.length > 0) { console.error('\x1b[31mThe following files are built for the wrong architecture:\x1b[0m'); for (const file of invalidFiles) { console.error(`\x1b[31m${file}\x1b[0m`); } process.exit(1); } else { console.log('\x1b[32mAll files are valid\x1b[0m'); } }).catch(err => { console.error(err); process.exit(1); }); ================================================ FILE: build/eslint.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const es = require('event-stream'); const vfs = require('vinyl-fs'); const { eslintFilter } = require('./filters'); function eslint() { const eslint = require('./gulp-eslint'); return vfs .src(eslintFilter, { base: '.', follow: true, allowEmpty: true }) .pipe( eslint((results) => { if (results.warningCount > 0 || results.errorCount > 0) { throw new Error('eslint failed with warnings and/or errors'); } }) ).pipe(es.through(function () { /* noop, important for the stream to end */ })); } if (require.main === module) { eslint().on('error', (err) => { console.error(); console.error(err); process.exit(1); }); } ================================================ FILE: build/filters.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /** * Hygiene works by creating cascading subsets of all our files and * passing them through a sequence of checks. Here are the current subsets, * named according to the checks performed on them. Each subset contains * the following one, as described in mathematical notation: * * all ⊃ eol ⊇ indentation ⊃ copyright ⊃ typescript */ const { readFileSync } = require('fs'); const { join } = require('path'); module.exports.all = [ '*', 'build/**/*', 'extensions/**/*', 'scripts/**/*', 'src/**/*', 'test/**/*', '!cli/**/*', '!out*/**', '!test/**/out/**', '!**/node_modules/**', ]; module.exports.unicodeFilter = [ '**', '!**/ThirdPartyNotices.txt', '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', '!**/*.{dll,exe,png,bmp,jpg,scpt,cur,ttf,woff,eot,template,ico,icns,opus,wasm}', '!**/test/**', '!**/*.test.ts', '!**/*.{d.ts,json,md}', '!**/*.mp3', '!build/win32/**', '!extensions/markdown-language-features/notebook-out/*.js', '!extensions/markdown-math/notebook-out/**', '!extensions/ipynb/notebook-out/**', '!extensions/notebook-renderers/renderer-out/**', '!extensions/php-language-features/src/features/phpGlobalFunctions.ts', '!extensions/terminal-suggest/src/completions/upstream/**', '!extensions/typescript-language-features/test-workspace/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', '!extensions/**/dist/**', '!extensions/**/out/**', '!extensions/**/snippets/**', '!extensions/**/colorize-fixtures/**', '!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts', '!src/vs/base/browser/dompurify/**', '!src/vs/workbench/services/keybinding/browser/keyboardLayouts/**', ]; module.exports.indentationFilter = [ '**', // except specific files '!**/ThirdPartyNotices.txt', '!**/ThirdPartyNotices.cli.txt', '!**/LICENSE.{txt,rtf}', '!LICENSES.chromium.html', '!**/LICENSE', '!**/*.mp3', '!src/vs/loader.js', '!src/vs/base/browser/dompurify/*', '!src/vs/base/common/marked/marked.js', '!src/vs/base/common/semver/semver.js', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', '!src/vs/editor/common/languages/highlights/*.scm', '!src/vs/editor/common/languages/injections/*.scm', '!test/unit/assert.js', '!resources/linux/snap/electron-launch', '!build/ext.js', '!build/npm/gyp/patches/gyp_spectre_mitigation_support.patch', '!product.overrides.json', // except specific folders '!test/automation/out/**', '!test/monaco/out/**', '!test/smoke/out/**', '!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts', '!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts', '!extensions/terminal-suggest/src/completions/upstream/**', '!extensions/typescript-language-features/test-workspace/**', '!extensions/typescript-language-features/resources/walkthroughs/**', '!extensions/typescript-language-features/package-manager/node-maintainer/**', '!extensions/markdown-math/notebook-out/**', '!extensions/ipynb/notebook-out/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', '!build/monaco/**', '!build/win32/**', // except multiple specific files '!**/package.json', '!**/package-lock.json', // except multiple specific folders '!**/codicon/**', '!**/fixtures/**', '!**/lib/**', '!extensions/**/dist/**', '!extensions/**/out/**', '!extensions/**/snippets/**', '!extensions/**/syntaxes/**', '!extensions/**/themes/**', '!extensions/**/colorize-fixtures/**', // except specific file types '!src/vs/*/**/*.d.ts', '!src/typings/**/*.d.ts', '!extensions/**/*.d.ts', '!**/*.{svg,exe,png,bmp,jpg,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,psm1,template,yaml,yml,d.ts.recipe,ico,icns,plist,opus,admx,adml,wasm}', '!build/{lib,download,linux,darwin}/**/*.js', '!build/**/*.sh', '!build/azure-pipelines/**/*.js', '!build/azure-pipelines/**/*.config', '!**/Dockerfile', '!**/Dockerfile.*', '!**/*.Dockerfile', '!**/*.dockerfile', // except for built files '!extensions/markdown-language-features/media/*.js', '!extensions/markdown-language-features/notebook-out/*.js', '!extensions/markdown-math/notebook-out/*.js', '!extensions/ipynb/notebook-out/**', '!extensions/notebook-renderers/renderer-out/*.js', '!extensions/simple-browser/media/*.js', ]; module.exports.copyrightFilter = [ '**', '!**/*.desktop', '!**/*.json', '!**/*.html', '!**/*.template', '!**/*.md', '!**/*.bat', '!**/*.cmd', '!**/*.ico', '!**/*.opus', '!**/*.mp3', '!**/*.icns', '!**/*.xml', '!**/*.sh', '!**/*.zsh', '!**/*.fish', '!**/*.txt', '!**/*.xpm', '!**/*.opts', '!**/*.disabled', '!**/*.code-workspace', '!**/*.js.map', '!**/*.wasm', '!build/**/*.init', '!build/linux/libcxx-fetcher.*', '!resources/linux/snap/snapcraft.yaml', '!resources/win32/bin/code.js', '!resources/completions/**', '!extensions/configuration-editing/build/inline-allOf.ts', '!extensions/markdown-language-features/media/highlight.css', '!extensions/markdown-math/notebook-out/**', '!extensions/ipynb/notebook-out/**', '!extensions/simple-browser/media/codicon.css', '!extensions/terminal-suggest/src/completions/upstream/**', '!extensions/typescript-language-features/node-maintainer/**', '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', ]; module.exports.tsFormattingFilter = [ 'src/**/*.ts', 'test/**/*.ts', 'extensions/**/*.ts', '!src/vs/*/**/*.d.ts', '!src/typings/**/*.d.ts', '!extensions/**/*.d.ts', '!**/fixtures/**', '!**/typings/**', '!**/node_modules/**', '!extensions/**/colorize-fixtures/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', '!extensions/**/*.test.ts', '!extensions/html-language-features/server/lib/jquery.d.ts', '!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts', '!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts', ]; module.exports.eslintFilter = [ '**/*.js', '**/*.cjs', '**/*.mjs', '**/*.ts', '.eslint-plugin-local/**/*.ts', ...readFileSync(join(__dirname, '..', '.eslint-ignore')) .toString() .split(/\r\n|\n/) .filter(line => line && !line.startsWith('#')) .map(line => line.startsWith('!') ? line.slice(1) : `!${line}`) ]; module.exports.stylelintFilter = [ 'src/**/*.css' ]; ================================================ FILE: build/gulp-eslint.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const { ESLint } = require('eslint'); const { Transform } = require('stream'); const { relative } = require('path'); const fancyLog = require('fancy-log'); /** * @param {Function} action - A function to handle all ESLint results * @returns {stream} gulp file stream */ function eslint(action) { const linter = new ESLint({}); const formatter = linter.loadFormatter('compact'); const results = []; results.errorCount = 0; results.warningCount = 0; return transform( async (file, enc, cb) => { const filePath = relative(process.cwd(), file.path); if (file.isNull()) { cb(null, file); return; } if (file.isStream()) { cb(new Error('vinyl files with Stream contents are not supported')); return; } try { // TODO: Should this be checked? if (await linter.isPathIgnored(filePath)) { cb(null, file); return; } const result = (await linter.lintText(file.contents.toString(), { filePath }))[0]; results.push(result); results.errorCount += result.errorCount; results.warningCount += result.warningCount; const message = (await formatter).format([result]); if (message) { fancyLog(message); } cb(null, file); } catch (error) { cb(error); } }, (done) => { try { action(results); done(); } catch (error) { done(error); } }); } function transform(transform, flush) { return new Transform({ objectMode: true, transform, flush }); } module.exports = eslint; ================================================ FILE: build/gulpfile.cli.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const es = require('event-stream'); const gulp = require('gulp'); const path = require('path'); const fancyLog = require('fancy-log'); const ansiColors = require('ansi-colors'); const cp = require('child_process'); const { tmpdir } = require('os'); const { promises: fs, existsSync, mkdirSync, rmSync } = require('fs'); const task = require('./lib/task'); const watcher = require('./lib/watch'); const { debounce } = require('./lib/util'); const createReporter = require('./lib/reporter').createReporter; const root = 'cli'; const rootAbs = path.resolve(__dirname, '..', root); const src = `${root}/src`; const platformOpensslDirName = process.platform === 'win32' ? ( process.arch === 'arm64' ? 'arm64-windows-static-md' : 'x64-windows-static-md') : process.platform === 'darwin' ? ( process.arch === 'arm64' ? 'arm64-osx' : 'x64-osx') : (process.arch === 'arm64' ? 'arm64-linux' : process.arch === 'arm' ? 'arm-linux' : 'x64-linux'); const platformOpensslDir = path.join(rootAbs, 'openssl', 'package', 'out', platformOpensslDirName); const hasLocalRust = (() => { /** @type boolean | undefined */ let result = undefined; return () => { if (result !== undefined) { return result; } try { const r = cp.spawnSync('cargo', ['--version']); result = r.status === 0; } catch (e) { result = false; } return result; }; })(); const debounceEsStream = (fn, duration = 100) => { let handle = undefined; let pending = []; const sendAll = (pending) => (event, ...args) => { for (const stream of pending) { pending.emit(event, ...args); } }; return es.map(function (_, callback) { console.log('defer'); if (handle !== undefined) { clearTimeout(handle); } handle = setTimeout(() => { handle = undefined; const previous = pending; pending = []; fn() .on('error', sendAll('error')) .on('data', sendAll('data')) .on('end', sendAll('end')); }, duration); pending.push(this); }); }; const compileFromSources = (callback) => { const proc = cp.spawn('cargo', ['--color', 'always', 'build'], { cwd: root, stdio: ['ignore', 'pipe', 'pipe'], env: existsSync(platformOpensslDir) ? { OPENSSL_DIR: platformOpensslDir, ...process.env } : process.env }); /** @type Buffer[] */ const stdoutErr = []; proc.stdout.on('data', d => stdoutErr.push(d)); proc.stderr.on('data', d => stdoutErr.push(d)); proc.on('error', callback); proc.on('exit', code => { if (code !== 0) { callback(Buffer.concat(stdoutErr).toString()); } else { callback(); } }); }; const acquireBuiltOpenSSL = (callback) => { const untar = require('gulp-untar'); const gunzip = require('gulp-gunzip'); const dir = path.join(tmpdir(), 'vscode-openssl-download'); mkdirSync(dir, { recursive: true }); cp.spawnSync( process.platform === 'win32' ? 'npm.cmd' : 'npm', ['pack', '@vscode/openssl-prebuilt'], { stdio: ['ignore', 'ignore', 'inherit'], cwd: dir } ); gulp.src('*.tgz', { cwd: dir }) .pipe(gunzip()) .pipe(untar()) .pipe(gulp.dest(`${root}/openssl`)) .on('error', callback) .on('end', () => { rmSync(dir, { recursive: true, force: true }); callback(); }); }; const compileWithOpenSSLCheck = (/** @type import('./lib/reporter').IReporter */ reporter) => es.map((_, callback) => { compileFromSources(err => { if (!err) { // no-op } else if (err.toString().includes('Could not find directory of OpenSSL installation') && !existsSync(platformOpensslDir)) { fancyLog(ansiColors.yellow(`[cli]`), 'OpenSSL libraries not found, acquiring prebuilt bits...'); acquireBuiltOpenSSL(err => { if (err) { callback(err); } else { compileFromSources(err => { if (err) { reporter(err.toString()); } callback(null, ''); }); } }); } else { reporter(err.toString()); } callback(null, ''); }); }); const warnIfRustNotInstalled = () => { if (!hasLocalRust()) { fancyLog(ansiColors.yellow(`[cli]`), 'No local Rust install detected, compilation may fail.'); fancyLog(ansiColors.yellow(`[cli]`), 'Get rust from: https://rustup.rs/'); } }; const compileCliTask = task.define('compile-cli', () => { warnIfRustNotInstalled(); const reporter = createReporter('cli'); return gulp.src(`${root}/Cargo.toml`) .pipe(compileWithOpenSSLCheck(reporter)) .pipe(reporter.end(true)); }); const watchCliTask = task.define('watch-cli', () => { warnIfRustNotInstalled(); return watcher(`${src}/**`, { read: false }) .pipe(debounce(compileCliTask)); }); gulp.task(compileCliTask); gulp.task(watchCliTask); ================================================ FILE: build/gulpfile.compile.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const gulp = require('gulp'); const util = require('./lib/util'); const date = require('./lib/date'); const task = require('./lib/task'); const compilation = require('./lib/compilation'); /** * @param {boolean} disableMangle */ function makeCompileBuildTask(disableMangle) { return task.series( util.rimraf('out-build'), date.writeISODate('out-build'), compilation.compileApiProposalNamesTask, compilation.compileTask('src', 'out-build', true, { disableMangle }) ); } // Local/PR compile, including nls and inline sources in sourcemaps, minification, no mangling const compileBuildWithoutManglingTask = task.define('compile-build-without-mangling', makeCompileBuildTask(true)); gulp.task(compileBuildWithoutManglingTask); exports.compileBuildWithoutManglingTask = compileBuildWithoutManglingTask; // CI compile, including nls and inline sources in sourcemaps, mangling, minification, for build const compileBuildWithManglingTask = task.define('compile-build-with-mangling', makeCompileBuildTask(false)); gulp.task(compileBuildWithManglingTask); exports.compileBuildWithManglingTask = compileBuildWithManglingTask; ================================================ FILE: build/gulpfile.editor.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check const gulp = require('gulp'); const path = require('path'); const util = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const task = require('./lib/task'); const es = require('event-stream'); const File = require('vinyl'); const i18n = require('./lib/i18n'); const standalone = require('./lib/standalone'); const cp = require('child_process'); const compilation = require('./lib/compilation'); const monacoapi = require('./lib/monaco-api'); const fs = require('fs'); const filter = require('gulp-filter'); const root = path.dirname(__dirname); const sha1 = getVersion(root); const semver = require('./monaco/package.json').version; const headerVersion = semver + '(' + sha1 + ')'; const BUNDLED_FILE_HEADER = [ '/*!-----------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Version: ' + headerVersion, ' * Released under the MIT license', ' * https://github.com/microsoft/vscode/blob/main/LICENSE.txt', ' *-----------------------------------------------------------*/', '' ].join('\n'); const extractEditorSrcTask = task.define('extract-editor-src', () => { const apiusages = monacoapi.execute().usageContent; const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString(); standalone.extractEditor({ sourcesRoot: path.join(root, 'src'), entryPoints: [ 'vs/editor/editor.main', 'vs/editor/editor.worker.start', 'vs/editor/common/services/editorWebWorkerMain', ], inlineEntryPoints: [ apiusages, extrausages ], typings: [], shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers importIgnorePattern: /\.css$/, destRoot: path.join(root, 'out-editor-src'), tsOutDir: '../out-monaco-editor-core/esm/vs', redirects: { '@vscode/tree-sitter-wasm': '../node_modules/@vscode/tree-sitter-wasm/wasm/web-tree-sitter', } }); }); const compileEditorESMTask = task.define('compile-editor-esm', () => { const src = 'out-editor-src'; const out = 'out-monaco-editor-core/esm'; const compile = compilation.createCompile(src, { build: true, emitError: true, transpileOnly: false, preserveEnglish: true }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); return ( srcPipe .pipe(compile()) .pipe(i18n.processNlsFiles({ out, fileHeader: BUNDLED_FILE_HEADER, languages: i18n.defaultLanguages, })) .pipe(filter(['**', '!**/inlineEntryPoint*', '!**/tsconfig.json', '!**/loader.js'])) .pipe(gulp.dest(out)) ); }); /** * @param {string} contents */ function toExternalDTS(contents) { const lines = contents.split(/\r\n|\r|\n/); let killNextCloseCurlyBrace = false; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (killNextCloseCurlyBrace) { if ('}' === line) { lines[i] = ''; killNextCloseCurlyBrace = false; continue; } if (line.indexOf(' ') === 0) { lines[i] = line.substr(4); } else if (line.charAt(0) === '\t') { lines[i] = line.substr(1); } continue; } if ('declare namespace monaco {' === line) { lines[i] = ''; killNextCloseCurlyBrace = true; continue; } if (line.indexOf('declare namespace monaco.') === 0) { lines[i] = line.replace('declare namespace monaco.', 'export namespace '); } if (line.indexOf('declare let MonacoEnvironment') === 0) { lines[i] = `declare global {\n let MonacoEnvironment: Environment | undefined;\n}`; } if (line.indexOf('\tMonacoEnvironment?') === 0) { lines[i] = ` MonacoEnvironment?: Environment | undefined;`; } } return lines.join('\n').replace(/\n\n\n+/g, '\n\n'); } const finalEditorResourcesTask = task.define('final-editor-resources', () => { return es.merge( // other assets es.merge( gulp.src('build/monaco/LICENSE'), gulp.src('build/monaco/ThirdPartyNotices.txt'), gulp.src('src/vs/monaco.d.ts') ).pipe(gulp.dest('out-monaco-editor-core')), // place the .d.ts in the esm folder gulp.src('src/vs/monaco.d.ts') .pipe(es.through(function (data) { this.emit('data', new File({ path: data.path.replace(/monaco\.d\.ts/, 'editor.api.d.ts'), base: data.base, contents: Buffer.from(toExternalDTS(data.contents.toString())) })); })) .pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')), // package.json gulp.src('build/monaco/package.json') .pipe(es.through(function (data) { const json = JSON.parse(data.contents.toString()); json.private = false; data.contents = Buffer.from(JSON.stringify(json, null, ' ')); this.emit('data', data); })) .pipe(gulp.dest('out-monaco-editor-core')), // version.txt gulp.src('build/monaco/version.txt') .pipe(es.through(function (data) { data.contents = Buffer.from(`monaco-editor-core: https://github.com/microsoft/vscode/tree/${sha1}`); this.emit('data', data); })) .pipe(gulp.dest('out-monaco-editor-core')), // README.md gulp.src('build/monaco/README-npm.md') .pipe(es.through(function (data) { this.emit('data', new File({ path: data.path.replace(/README-npm\.md/, 'README.md'), base: data.base, contents: data.contents })); })) .pipe(gulp.dest('out-monaco-editor-core')), ); }); gulp.task('extract-editor-src', task.series( util.rimraf('out-editor-src'), extractEditorSrcTask ) ); gulp.task('editor-distro', task.series( task.parallel( util.rimraf('out-editor-src'), util.rimraf('out-monaco-editor-core'), ), extractEditorSrcTask, compileEditorESMTask, finalEditorResourcesTask ) ); gulp.task('monacodts', task.define('monacodts', () => { const result = monacoapi.execute(); fs.writeFileSync(result.filePath, result.content); fs.writeFileSync(path.join(root, 'src/vs/editor/common/standalone/standaloneEnums.ts'), result.enums); return Promise.resolve(true); })); //#region monaco type checking /** * @param {boolean} watch */ function createTscCompileTask(watch) { return () => { const createReporter = require('./lib/reporter').createReporter; return new Promise((resolve, reject) => { const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit']; if (watch) { args.push('-w'); } const child = cp.spawn(`node`, args, { cwd: path.join(__dirname, '..'), // stdio: [null, 'pipe', 'inherit'] }); const errors = []; const reporter = createReporter('monaco'); /** @type {NodeJS.ReadWriteStream | undefined} */ let report; const magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings child.stdout.on('data', data => { let str = String(data); str = str.replace(magic, '').trim(); if (str.indexOf('Starting compilation') >= 0 || str.indexOf('File change detected') >= 0) { errors.length = 0; report = reporter.end(false); } else if (str.indexOf('Compilation complete') >= 0) { // @ts-ignore report.end(); } else if (str) { const match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); if (match) { // trying to massage the message so that it matches the gulp-tsb error messages // e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'. const fullpath = path.join(root, match[1]); const message = match[3]; reporter(fullpath + message); } else { reporter(str); } } }); child.on('exit', resolve); child.on('error', reject); }); }; } const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true)); exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask; const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false)); exports.monacoTypecheckTask = monacoTypecheckTask; //#endregion ================================================ FILE: build/gulpfile.extensions.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Increase max listeners for event emitters require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const path = require('path'); const nodeUtil = require('util'); const es = require('event-stream'); const filter = require('gulp-filter'); const util = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const task = require('./lib/task'); const watcher = require('./lib/watch'); const createReporter = require('./lib/reporter').createReporter; const glob = require('glob'); const root = path.dirname(__dirname); const commit = getVersion(root); const plumber = require('gulp-plumber'); const ext = require('./lib/extensions'); // To save 250ms for each gulp startup, we are caching the result here // const compilations = glob.sync('**/tsconfig.json', { // cwd: extensionsPath, // ignore: ['**/out/**', '**/node_modules/**'] // }); const compilations = [ 'extensions/configuration-editing/tsconfig.json', 'extensions/css-language-features/client/tsconfig.json', 'extensions/css-language-features/server/tsconfig.json', 'extensions/debug-auto-launch/tsconfig.json', 'extensions/debug-server-ready/tsconfig.json', 'extensions/emmet/tsconfig.json', 'extensions/extension-editing/tsconfig.json', 'extensions/git/tsconfig.json', 'extensions/git-base/tsconfig.json', 'extensions/github/tsconfig.json', 'extensions/github-authentication/tsconfig.json', 'extensions/grunt/tsconfig.json', 'extensions/gulp/tsconfig.json', 'extensions/html-language-features/client/tsconfig.json', 'extensions/html-language-features/server/tsconfig.json', 'extensions/ipynb/tsconfig.json', 'extensions/jake/tsconfig.json', 'extensions/json-language-features/client/tsconfig.json', 'extensions/json-language-features/server/tsconfig.json', 'extensions/markdown-language-features/preview-src/tsconfig.json', 'extensions/markdown-language-features/tsconfig.json', 'extensions/markdown-math/tsconfig.json', 'extensions/media-preview/tsconfig.json', 'extensions/merge-conflict/tsconfig.json', 'extensions/terminal-suggest/tsconfig.json', 'extensions/microsoft-authentication/tsconfig.json', 'extensions/notebook-renderers/tsconfig.json', 'extensions/npm/tsconfig.json', 'extensions/php-language-features/tsconfig.json', 'extensions/references-view/tsconfig.json', 'extensions/search-result/tsconfig.json', 'extensions/simple-browser/tsconfig.json', 'extensions/tunnel-forwarding/tsconfig.json', 'extensions/typescript-language-features/test-workspace/tsconfig.json', 'extensions/typescript-language-features/web/tsconfig.json', 'extensions/typescript-language-features/tsconfig.json', 'extensions/vscode-api-tests/tsconfig.json', 'extensions/vscode-colorize-tests/tsconfig.json', 'extensions/vscode-colorize-perf-tests/tsconfig.json', 'extensions/vscode-test-resolver/tsconfig.json', '.vscode/extensions/vscode-selfhost-test-provider/tsconfig.json', '.vscode/extensions/vscode-selfhost-import-aid/tsconfig.json', ]; const getBaseUrl = out => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`; const tasks = compilations.map(function (tsconfigFile) { const absolutePath = path.join(root, tsconfigFile); const relativeDirname = path.dirname(tsconfigFile.replace(/^(.*\/)?extensions\//i, '')); const overrideOptions = {}; overrideOptions.sourceMap = true; const name = relativeDirname.replace(/\//g, '-'); const srcRoot = path.dirname(tsconfigFile); const srcBase = path.join(srcRoot, 'src'); const src = path.join(srcBase, '**'); const srcOpts = { cwd: root, base: srcBase, dot: true }; const out = path.join(srcRoot, 'out'); const baseUrl = getBaseUrl(out); let headerId, headerOut; const index = relativeDirname.indexOf('/'); if (index < 0) { headerId = 'vscode.' + relativeDirname; headerOut = 'out'; } else { headerId = 'vscode.' + relativeDirname.substr(0, index); headerOut = relativeDirname.substr(index + 1) + '/out'; } function createPipeline(build, emitError, transpileOnly) { const tsb = require('./lib/tsb'); const sourcemaps = require('gulp-sourcemaps'); const reporter = createReporter('extensions'); overrideOptions.inlineSources = Boolean(build); overrideOptions.base = path.dirname(absolutePath); const compilation = tsb.create(absolutePath, overrideOptions, { verbose: false, transpileOnly, transpileOnlyIncludesDts: transpileOnly, transpileWithSwc: true }, err => reporter(err.toString())); const pipeline = function () { const input = es.through(); const tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true, dot: true }); const output = input .pipe(plumber({ errorHandler: function (err) { if (err && !err.__reporter__) { reporter(err); } } })) .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation()) .pipe(build ? util.stripSourceMappingURL() : es.through()) .pipe(sourcemaps.write('.', { sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`, addComment: !!build, includeContent: !!build, // note: trailing slash is important, else the source URLs in V8's file coverage are incorrect sourceRoot: '../src/', })) .pipe(tsFilter.restore) .pipe(reporter.end(emitError)); return es.duplex(input, output); }; // add src-stream for project files pipeline.tsProjectSrc = () => { return compilation.src(srcOpts); }; return pipeline; } const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out)); const transpileTask = task.define(`transpile-extension:${name}`, task.series(cleanTask, () => { const pipeline = createPipeline(false, true, true); const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); const input = es.merge(nonts, pipeline.tsProjectSrc()); return input .pipe(pipeline()) .pipe(gulp.dest(out)); })); const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => { const pipeline = createPipeline(false, true); const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); const input = es.merge(nonts, pipeline.tsProjectSrc()); return input .pipe(pipeline()) .pipe(gulp.dest(out)); })); const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => { const pipeline = createPipeline(false); const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); const input = es.merge(nonts, pipeline.tsProjectSrc()); const watchInput = watcher(src, { ...srcOpts, ...{ readDelay: 200 } }); return watchInput .pipe(util.incremental(pipeline, input)) .pipe(gulp.dest(out)); })); const compileBuildTask = task.define(`compile-build-extension-${name}`, task.series(cleanTask, () => { const pipeline = createPipeline(true, true); const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); const input = es.merge(nonts, pipeline.tsProjectSrc()); return input .pipe(pipeline()) .pipe(gulp.dest(out)); })); // Tasks gulp.task(transpileTask); gulp.task(compileTask); gulp.task(watchTask); return { transpileTask, compileTask, watchTask, compileBuildTask }; }); const transpileExtensionsTask = task.define('transpile-extensions', task.parallel(...tasks.map(t => t.transpileTask))); gulp.task(transpileExtensionsTask); const compileExtensionsTask = task.define('compile-extensions', task.parallel(...tasks.map(t => t.compileTask))); gulp.task(compileExtensionsTask); exports.compileExtensionsTask = compileExtensionsTask; const watchExtensionsTask = task.define('watch-extensions', task.parallel(...tasks.map(t => t.watchTask))); gulp.task(watchExtensionsTask); exports.watchExtensionsTask = watchExtensionsTask; const compileExtensionsBuildLegacyTask = task.define('compile-extensions-build-legacy', task.parallel(...tasks.map(t => t.compileBuildTask))); gulp.task(compileExtensionsBuildLegacyTask); //#region Extension media const compileExtensionMediaTask = task.define('compile-extension-media', () => ext.buildExtensionMedia(false)); gulp.task(compileExtensionMediaTask); exports.compileExtensionMediaTask = compileExtensionMediaTask; const watchExtensionMedia = task.define('watch-extension-media', () => ext.buildExtensionMedia(true)); gulp.task(watchExtensionMedia); exports.watchExtensionMedia = watchExtensionMedia; const compileExtensionMediaBuildTask = task.define('compile-extension-media-build', () => ext.buildExtensionMedia(false, '.build/extensions')); gulp.task(compileExtensionMediaBuildTask); exports.compileExtensionMediaBuildTask = compileExtensionMediaBuildTask; //#endregion //#region Azure Pipelines /** * Cleans the build directory for extensions */ const cleanExtensionsBuildTask = task.define('clean-extensions-build', util.rimraf('.build/extensions')); exports.cleanExtensionsBuildTask = cleanExtensionsBuildTask; /** * brings in the marketplace extensions for the build */ const bundleMarketplaceExtensionsBuildTask = task.define('bundle-marketplace-extensions-build', () => ext.packageMarketplaceExtensionsStream(false).pipe(gulp.dest('.build'))); /** * Compiles the non-native extensions for the build * @note this does not clean the directory ahead of it. See {@link cleanExtensionsBuildTask} for that. */ const compileNonNativeExtensionsBuildTask = task.define('compile-non-native-extensions-build', task.series( bundleMarketplaceExtensionsBuildTask, task.define('bundle-non-native-extensions-build', () => ext.packageNonNativeLocalExtensionsStream().pipe(gulp.dest('.build'))) )); gulp.task(compileNonNativeExtensionsBuildTask); exports.compileNonNativeExtensionsBuildTask = compileNonNativeExtensionsBuildTask; /** * Compiles the native extensions for the build * @note this does not clean the directory ahead of it. See {@link cleanExtensionsBuildTask} for that. */ const compileNativeExtensionsBuildTask = task.define('compile-native-extensions-build', () => ext.packageNativeLocalExtensionsStream().pipe(gulp.dest('.build'))); gulp.task(compileNativeExtensionsBuildTask); exports.compileNativeExtensionsBuildTask = compileNativeExtensionsBuildTask; /** * Compiles the extensions for the build. * This is essentially a helper task that combines {@link cleanExtensionsBuildTask}, {@link compileNonNativeExtensionsBuildTask} and {@link compileNativeExtensionsBuildTask} */ const compileAllExtensionsBuildTask = task.define('compile-extensions-build', task.series( cleanExtensionsBuildTask, bundleMarketplaceExtensionsBuildTask, task.define('bundle-extensions-build', () => ext.packageAllLocalExtensionsStream(false, false).pipe(gulp.dest('.build'))), )); gulp.task(compileAllExtensionsBuildTask); exports.compileAllExtensionsBuildTask = compileAllExtensionsBuildTask; // This task is run in the compilation stage of the CI pipeline. We only compile the non-native extensions since those can be fully built regardless of platform. // This defers the native extensions to the platform specific stage of the CI pipeline. gulp.task(task.define('extensions-ci', task.series(compileNonNativeExtensionsBuildTask, compileExtensionMediaBuildTask))); const compileExtensionsBuildPullRequestTask = task.define('compile-extensions-build-pr', task.series( cleanExtensionsBuildTask, bundleMarketplaceExtensionsBuildTask, task.define('bundle-extensions-build-pr', () => ext.packageAllLocalExtensionsStream(false, true).pipe(gulp.dest('.build'))), )); gulp.task(compileExtensionsBuildPullRequestTask); // This task is run in the compilation stage of the PR pipeline. We compile all extensions in it to verify compilation. gulp.task(task.define('extensions-ci-pr', task.series(compileExtensionsBuildPullRequestTask, compileExtensionMediaBuildTask))); //#endregion const compileWebExtensionsTask = task.define('compile-web', () => buildWebExtensions(false)); gulp.task(compileWebExtensionsTask); exports.compileWebExtensionsTask = compileWebExtensionsTask; const watchWebExtensionsTask = task.define('watch-web', () => buildWebExtensions(true)); gulp.task(watchWebExtensionsTask); exports.watchWebExtensionsTask = watchWebExtensionsTask; /** * @param {boolean} isWatch */ async function buildWebExtensions(isWatch) { const extensionsPath = path.join(root, 'extensions'); const webpackConfigLocations = await nodeUtil.promisify(glob)( path.join(extensionsPath, '**', 'extension-browser.webpack.config.js'), { ignore: ['**/node_modules'] } ); return ext.webpackExtensions('packaging web extension', isWatch, webpackConfigLocations.map(configPath => ({ configPath }))); } ================================================ FILE: build/gulpfile.hygiene.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const gulp = require('gulp'); const es = require('event-stream'); const path = require('path'); const task = require('./lib/task'); const { hygiene } = require('./hygiene'); /** * @param {string} actualPath */ function checkPackageJSON(actualPath) { const actual = require(path.join(__dirname, '..', actualPath)); const rootPackageJSON = require('../package.json'); const checkIncluded = (set1, set2) => { for (const depName in set1) { const depVersion = set1[depName]; const rootDepVersion = set2[depName]; if (!rootDepVersion) { // missing in root is allowed continue; } if (depVersion !== rootDepVersion) { this.emit( 'error', `The dependency ${depName} in '${actualPath}' (${depVersion}) is different than in the root package.json (${rootDepVersion})` ); } } }; checkIncluded(actual.dependencies, rootPackageJSON.dependencies); checkIncluded(actual.devDependencies, rootPackageJSON.devDependencies); } const checkPackageJSONTask = task.define('check-package-json', () => { return gulp.src('package.json').pipe( es.through(function () { checkPackageJSON.call(this, 'remote/package.json'); checkPackageJSON.call(this, 'remote/web/package.json'); checkPackageJSON.call(this, 'build/package.json'); }) ); }); gulp.task(checkPackageJSONTask); const hygieneTask = task.define('hygiene', task.series(checkPackageJSONTask, () => hygiene(undefined, false))); gulp.task(hygieneTask); ================================================ FILE: build/gulpfile.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; // Increase max listeners for event emitters require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const util = require('./lib/util'); const task = require('./lib/task'); const { transpileClientSWC, transpileTask, compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation'); const { monacoTypecheckTask/* , monacoTypecheckWatchTask */ } = require('./gulpfile.editor'); const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } = require('./gulpfile.extensions'); // API proposal names gulp.task(compileApiProposalNamesTask); gulp.task(watchApiProposalNamesTask); // SWC Client Transpile const transpileClientSWCTask = task.define('transpile-client-esbuild', task.series(util.rimraf('out'), transpileTask('src', 'out', true))); gulp.task(transpileClientSWCTask); // Transpile only const transpileClientTask = task.define('transpile-client', task.series(util.rimraf('out'), transpileTask('src', 'out'))); gulp.task(transpileClientTask); // Fast compile for development time const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), compileApiProposalNamesTask, compileTask('src', 'out', false))); gulp.task(compileClientTask); const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), task.parallel(watchTask('out', false), watchApiProposalNamesTask))); gulp.task(watchClientTask); // All const _compileTask = task.define('compile', task.parallel(monacoTypecheckTask, compileClientTask, compileExtensionsTask, compileExtensionMediaTask)); gulp.task(_compileTask); gulp.task(task.define('watch', task.parallel(/* monacoTypecheckWatchTask, */ watchClientTask, watchExtensionsTask))); // Default gulp.task('default', _compileTask); process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); process.exit(1); }); // Load all the gulpfiles only if running tasks other than the editor tasks require('glob').sync('gulpfile.*.js', { cwd: __dirname }) .forEach(f => require(`./${f}`)); ================================================ FILE: build/gulpfile.reh.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const path = require('path'); const es = require('event-stream'); const util = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const task = require('./lib/task'); const optimize = require('./lib/optimize'); const { inlineMeta } = require('./lib/inlineMeta'); const product = require('../product.json'); const rename = require('gulp-rename'); const replace = require('gulp-replace'); const filter = require('gulp-filter'); const { getProductionDependencies } = require('./lib/dependencies'); const { readISODate } = require('./lib/date'); const vfs = require('vinyl-fs'); const packageJson = require('../package.json'); const flatmap = require('gulp-flatmap'); const gunzip = require('gulp-gunzip'); const File = require('vinyl'); const fs = require('fs'); const glob = require('glob'); const { compileBuildWithManglingTask } = require('./gulpfile.compile'); const { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileExtensionMediaBuildTask } = require('./gulpfile.extensions'); const { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } = require('./gulpfile.vscode.web'); const cp = require('child_process'); const log = require('fancy-log'); const buildfile = require('./buildfile'); const REPO_ROOT = path.dirname(__dirname); const commit = getVersion(REPO_ROOT); const BUILD_ROOT = path.dirname(REPO_ROOT); const REMOTE_FOLDER = path.join(REPO_ROOT, 'remote'); // Targets const BUILD_TARGETS = [ { platform: 'win32', arch: 'x64' }, { platform: 'win32', arch: 'arm64' }, { platform: 'darwin', arch: 'x64' }, { platform: 'darwin', arch: 'arm64' }, { platform: 'linux', arch: 'x64' }, { platform: 'linux', arch: 'armhf' }, { platform: 'linux', arch: 'arm64' }, { platform: 'alpine', arch: 'arm64' }, // legacy: we use to ship only one alpine so it was put in the arch, but now we ship // multiple alpine images and moved to a better model (alpine as the platform) { platform: 'linux', arch: 'alpine' }, ]; const serverResourceIncludes = [ // NLS 'out-build/nls.messages.json', // Process monitor 'out-build/vs/base/node/cpuUsage.sh', 'out-build/vs/base/node/ps.sh', // External Terminal 'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt', // Terminal shell integration 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration.ps1', 'out-build/vs/workbench/contrib/terminal/common/scripts/CodeTabExpansion.psm1', 'out-build/vs/workbench/contrib/terminal/common/scripts/GitTabExpansion.psm1', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration-env.zsh', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration-profile.zsh', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration-rc.zsh', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration-login.zsh', 'out-build/vs/workbench/contrib/terminal/common/scripts/shellIntegration.fish', ]; const serverResourceExcludes = [ '!out-build/vs/**/{electron-sandbox,electron-main,electron-utility}/**', '!out-build/vs/editor/standalone/**', '!out-build/vs/workbench/**/*-tb.png', '!**/test/**' ]; const serverResources = [ ...serverResourceIncludes, ...serverResourceExcludes ]; const serverWithWebResourceIncludes = [ ...serverResourceIncludes, 'out-build/vs/code/browser/workbench/*.html', ...vscodeWebResourceIncludes ]; const serverWithWebResourceExcludes = [ ...serverResourceExcludes, '!out-build/vs/code/**/*-dev.html' ]; const serverWithWebResources = [ ...serverWithWebResourceIncludes, ...serverWithWebResourceExcludes ]; const serverEntryPoints = buildfile.codeServer; const webEntryPoints = [ buildfile.workerEditor, buildfile.workerExtensionHost, buildfile.workerNotebook, buildfile.workerLanguageDetection, buildfile.workerLocalFileSearch, buildfile.workerOutputLinks, buildfile.workerBackgroundTokenization, buildfile.keyboardMaps, buildfile.codeWeb ].flat(); const serverWithWebEntryPoints = [ // Include all of server ...serverEntryPoints, // Include all of web ...webEntryPoints, ].flat(); const bootstrapEntryPoints = [ 'out-build/server-main.js', 'out-build/server-cli.js', 'out-build/bootstrap-fork.js' ]; function getNodeVersion() { const npmrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.npmrc'), 'utf8'); const nodeVersion = /^target="(.*)"$/m.exec(npmrc)[1]; const internalNodeVersion = /^ms_build_id="(.*)"$/m.exec(npmrc)[1]; return { nodeVersion, internalNodeVersion }; } function getNodeChecksum(expectedName) { const nodeJsChecksums = fs.readFileSync(path.join(REPO_ROOT, 'build', 'checksums', 'nodejs.txt'), 'utf8'); for (const line of nodeJsChecksums.split('\n')) { const [checksum, name] = line.split(/\s+/); if (name === expectedName) { return checksum; } } return undefined; } function extractAlpinefromDocker(nodeVersion, platform, arch) { const imageName = arch === 'arm64' ? 'arm64v8/node' : 'node'; log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from docker image ${imageName}`); const contents = cp.execSync(`docker run --rm ${imageName}:${nodeVersion}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' }); return es.readArray([new File({ path: 'node', contents, stat: { mode: parseInt('755', 8) } })]); } const { nodeVersion, internalNodeVersion } = getNodeVersion(); BUILD_TARGETS.forEach(({ platform, arch }) => { gulp.task(task.define(`node-${platform}-${arch}`, () => { const nodePath = path.join('.build', 'node', `v${nodeVersion}`, `${platform}-${arch}`); if (!fs.existsSync(nodePath)) { util.rimraf(nodePath); return nodejs(platform, arch) .pipe(vfs.dest(nodePath)); } return Promise.resolve(null); })); }); const defaultNodeTask = gulp.task(`node-${process.platform}-${process.arch}`); if (defaultNodeTask) { gulp.task(task.define('node', defaultNodeTask)); } function nodejs(platform, arch) { const { fetchUrls, fetchGithub } = require('./lib/fetch'); const untar = require('gulp-untar'); if (arch === 'armhf') { arch = 'armv7l'; } else if (arch === 'alpine') { platform = 'alpine'; arch = 'x64'; } log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from ${product.nodejsRepository}...`); const glibcPrefix = process.env['VSCODE_NODE_GLIBC'] ?? ''; let expectedName; switch (platform) { case 'win32': expectedName = product.nodejsRepository !== 'https://nodejs.org' ? `win-${arch}-node.exe` : `win-${arch}/node.exe`; break; case 'darwin': expectedName = `node-v${nodeVersion}-${platform}-${arch}.tar.gz`; break; case 'linux': expectedName = `node-v${nodeVersion}${glibcPrefix}-${platform}-${arch}.tar.gz`; break; case 'alpine': expectedName = `node-v${nodeVersion}-linux-${arch}-musl.tar.gz`; break; } const checksumSha256 = getNodeChecksum(expectedName); if (checksumSha256) { log(`Using SHA256 checksum for checking integrity: ${checksumSha256}`); } else { log.warn(`Unable to verify integrity of downloaded node.js binary because no SHA256 checksum was found!`); } switch (platform) { case 'win32': return (product.nodejsRepository !== 'https://nodejs.org' ? fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 }) : fetchUrls(`/dist/v${nodeVersion}/win-${arch}/node.exe`, { base: 'https://nodejs.org', checksumSha256 })) .pipe(rename('node.exe')); case 'darwin': case 'linux': return (product.nodejsRepository !== 'https://nodejs.org' ? fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 }) : fetchUrls(`/dist/v${nodeVersion}/node-v${nodeVersion}-${platform}-${arch}.tar.gz`, { base: 'https://nodejs.org', checksumSha256 }) ).pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) .pipe(filter('**/node')) .pipe(util.setExecutableBit('**')) .pipe(rename('node')); case 'alpine': return product.nodejsRepository !== 'https://nodejs.org' ? fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 }) .pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) .pipe(filter('**/node')) .pipe(util.setExecutableBit('**')) .pipe(rename('node')) : extractAlpinefromDocker(nodeVersion, platform, arch); } } function packageTask(type, platform, arch, sourceFolderName, destinationFolderName) { const destination = path.join(BUILD_ROOT, destinationFolderName); return () => { const json = require('gulp-json-editor'); const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) .pipe(util.setExecutableBit(['**/*.sh'])) .pipe(filter(['**', '!**/*.js.map'])); const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const isUIExtension = (manifest) => { switch (manifest.extensionKind) { case 'ui': return true; case 'workspace': return false; default: { if (manifest.main) { return false; } if (manifest.contributes && Object.keys(manifest.contributes).some(key => workspaceExtensionPoints.indexOf(key) !== -1)) { return false; } // Default is UI Extension return true; } } }; const localWorkspaceExtensions = glob.sync('extensions/*/package.json') .filter((extensionPath) => { if (type === 'reh-web') { return true; // web: ship all extensions for now } // Skip shipping UI extensions because the client side will have them anyways // and they'd just increase the download without being used const manifest = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, extensionPath)).toString()); return !isUIExtension(manifest); }).map((extensionPath) => path.basename(path.dirname(extensionPath))) .filter(name => name !== 'vscode-api-tests' && name !== 'vscode-test-resolver'); // Do not ship the test extensions const marketplaceExtensions = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'product.json'), 'utf8')).builtInExtensions .filter(entry => !entry.platforms || new Set(entry.platforms).has(platform)) .filter(entry => !entry.clientOnly) .map(entry => entry.name); const extensionPaths = [...localWorkspaceExtensions, ...marketplaceExtensions] .map(name => `.build/extensions/${name}/**`); const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true }); const sources = es.merge(src, extensions, extensionsCommonDependencies) .pipe(filter(['**', '!**/*.js.map'], { dot: true })); let version = packageJson.version; const quality = product.quality; if (quality && quality !== 'stable') { version += '-' + quality; } const name = product.nameShort; let packageJsonContents; const packageJsonStream = gulp.src(['remote/package.json'], { base: 'remote' }) .pipe(json({ name, version, dependencies: undefined, optionalDependencies: undefined, type: 'module' })) .pipe(es.through(function (file) { packageJsonContents = file.contents.toString(); this.emit('data', file); })); let productJsonContents; const productJsonStream = gulp.src(['product.json'], { base: '.' }) .pipe(json({ commit, date: readISODate('out-build'), version })) .pipe(es.through(function (file) { productJsonContents = file.contents.toString(); this.emit('data', file); })); const license = gulp.src(['remote/LICENSE'], { base: 'remote', allowEmpty: true }); const jsFilter = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path)); const productionDependencies = getProductionDependencies(REMOTE_FOLDER); const dependenciesSrc = productionDependencies.map(d => path.relative(REPO_ROOT, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`, `!${d}/.bin/**`]).flat(); const deps = gulp.src(dependenciesSrc, { base: 'remote', dot: true }) // filter out unnecessary files, no source maps in server build .pipe(filter(['**', '!**/package-lock.json', '!**/*.js.map'])) .pipe(util.cleanNodeModules(path.join(__dirname, '.moduleignore'))) .pipe(util.cleanNodeModules(path.join(__dirname, `.moduleignore.${process.platform}`))) .pipe(jsFilter) .pipe(util.stripSourceMappingURL()) .pipe(jsFilter.restore); const nodePath = `.build/node/v${nodeVersion}/${platform}-${arch}`; const node = gulp.src(`${nodePath}/**`, { base: nodePath, dot: true }); let web = []; if (type === 'reh-web') { web = [ 'resources/server/favicon.ico', 'resources/server/code-192.png', 'resources/server/code-512.png', 'resources/server/manifest.json' ].map(resource => gulp.src(resource, { base: '.' }).pipe(rename(resource))); } const all = es.merge( packageJsonStream, productJsonStream, license, sources, deps, node, ...web ); let result = all .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()); if (platform === 'win32') { result = es.merge(result, gulp.src('resources/server/bin/remote-cli/code.cmd', { base: '.' }) .pipe(replace('@@VERSION@@', version)) .pipe(replace('@@COMMIT@@', commit)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(`bin/remote-cli/${product.applicationName}.cmd`)), gulp.src('resources/server/bin/helpers/browser.cmd', { base: '.' }) .pipe(replace('@@VERSION@@', version)) .pipe(replace('@@COMMIT@@', commit)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(`bin/helpers/browser.cmd`)), gulp.src('resources/server/bin/code-server.cmd', { base: '.' }) .pipe(rename(`bin/${product.serverApplicationName}.cmd`)), ); } else if (platform === 'linux' || platform === 'alpine' || platform === 'darwin') { result = es.merge(result, gulp.src(`resources/server/bin/remote-cli/${platform === 'darwin' ? 'code-darwin.sh' : 'code-linux.sh'}`, { base: '.' }) .pipe(replace('@@VERSION@@', version)) .pipe(replace('@@COMMIT@@', commit)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(`bin/remote-cli/${product.applicationName}`)) .pipe(util.setExecutableBit()), gulp.src(`resources/server/bin/helpers/${platform === 'darwin' ? 'browser-darwin.sh' : 'browser-linux.sh'}`, { base: '.' }) .pipe(replace('@@VERSION@@', version)) .pipe(replace('@@COMMIT@@', commit)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(`bin/helpers/browser.sh`)) .pipe(util.setExecutableBit()), gulp.src(`resources/server/bin/${platform === 'darwin' ? 'code-server-darwin.sh' : 'code-server-linux.sh'}`, { base: '.' }) .pipe(rename(`bin/${product.serverApplicationName}`)) .pipe(util.setExecutableBit()) ); } if (platform === 'linux' || platform === 'alpine') { result = es.merge(result, gulp.src(`resources/server/bin/helpers/check-requirements-linux.sh`, { base: '.' }) .pipe(rename(`bin/helpers/check-requirements.sh`)) .pipe(util.setExecutableBit()) ); } result = inlineMeta(result, { targetPaths: bootstrapEntryPoints, packageJsonFn: () => packageJsonContents, productJsonFn: () => productJsonContents }); return result.pipe(vfs.dest(destination)); }; } /** * @param {object} product The parsed product.json file contents */ function tweakProductForServerWeb(product) { const result = { ...product }; delete result.webEndpointUrlTemplate; return result; } ['reh', 'reh-web'].forEach(type => { const bundleTask = task.define(`bundle-vscode-${type}`, task.series( util.rimraf(`out-vscode-${type}`), optimize.bundleTask( { out: `out-vscode-${type}`, esm: { src: 'out-build', entryPoints: [ ...(type === 'reh' ? serverEntryPoints : serverWithWebEntryPoints), ...bootstrapEntryPoints ], resources: type === 'reh' ? serverResources : serverWithWebResources, fileContentMapper: createVSCodeWebFileContentMapper('.build/extensions', type === 'reh-web' ? tweakProductForServerWeb(product) : product) } } ) )); const minifyTask = task.define(`minify-vscode-${type}`, task.series( bundleTask, util.rimraf(`out-vscode-${type}-min`), optimize.minifyTask(`out-vscode-${type}`, `https://main.vscode-cdn.net/sourcemaps/${commit}/core`) )); gulp.task(minifyTask); BUILD_TARGETS.forEach(buildTarget => { const dashed = (str) => (str ? `-${str}` : ``); const platform = buildTarget.platform; const arch = buildTarget.arch; ['', 'min'].forEach(minified => { const sourceFolderName = `out-vscode-${type}${dashed(minified)}`; const destinationFolderName = `vscode-${type}${dashed(platform)}${dashed(arch)}`; const serverTaskCI = task.define(`vscode-${type}${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series( compileNativeExtensionsBuildTask, gulp.task(`node-${platform}-${arch}`), util.rimraf(path.join(BUILD_ROOT, destinationFolderName)), packageTask(type, platform, arch, sourceFolderName, destinationFolderName) )); gulp.task(serverTaskCI); const serverTask = task.define(`vscode-${type}${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series( compileBuildWithManglingTask, cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileExtensionMediaBuildTask, minified ? minifyTask : bundleTask, serverTaskCI )); gulp.task(serverTask); }); }); }); ================================================ FILE: build/gulpfile.scan.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const path = require('path'); const task = require('./lib/task'); const util = require('./lib/util'); const electron = require('@vscode/gulp-electron'); const { config } = require('./lib/electron'); const filter = require('gulp-filter'); const deps = require('./lib/dependencies'); const { existsSync, readdirSync } = require('fs'); const root = path.dirname(__dirname); const BUILD_TARGETS = [ { platform: 'win32', arch: 'x64' }, { platform: 'win32', arch: 'arm64' }, { platform: 'darwin', arch: null, opts: { stats: true } }, { platform: 'linux', arch: 'x64' }, { platform: 'linux', arch: 'armhf' }, { platform: 'linux', arch: 'arm64' }, ]; // The following files do not have PDBs downloaded for them during the download symbols process. const excludedCheckList = ['d3dcompiler_47.dll']; BUILD_TARGETS.forEach(buildTarget => { const dashed = (/** @type {string | null} */ str) => (str ? `-${str}` : ``); const platform = buildTarget.platform; const arch = buildTarget.arch; const destinationExe = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'bin'); const destinationPdb = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'pdb'); const tasks = []; // removal tasks tasks.push(util.rimraf(destinationExe), util.rimraf(destinationPdb)); // electron tasks.push(() => electron.dest(destinationExe, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch })); // pdbs for windows if (platform === 'win32') { tasks.push( () => electron.dest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, pdbs: true }), () => confirmPdbsExist(destinationExe, destinationPdb) ); } if (platform === 'linux') { tasks.push( () => electron.dest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, symbols: true }) ); } // node modules tasks.push( nodeModules(destinationExe, destinationPdb, platform) ); const setupSymbolsTask = task.define(`vscode-symbols${dashed(platform)}${dashed(arch)}`, task.series(...tasks) ); gulp.task(setupSymbolsTask); }); function getProductionDependencySources() { const productionDependencies = deps.getProductionDependencies(root); return productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat(); } function nodeModules(destinationExe, destinationPdb, platform) { const exe = () => { return gulp.src(getProductionDependencySources(), { base: '.', dot: true }) .pipe(filter([ '**/*.node', // Exclude these paths. // We don't build the prebuilt node files so we don't scan them '!**/prebuilds/**/*.node', // These are 3rd party modules that we should ignore '!**/@parcel/watcher/**/*'])) .pipe(gulp.dest(destinationExe)); }; if (platform === 'win32') { const pdb = () => { return gulp.src(getProductionDependencySources(), { base: '.', dot: true }) .pipe(filter(['**/*.pdb'])) .pipe(gulp.dest(destinationPdb)); }; return gulp.parallel(exe, pdb); } if (platform === 'linux') { const pdb = () => { return gulp.src(getProductionDependencySources(), { base: '.', dot: true }) .pipe(filter(['**/*.sym'])) .pipe(gulp.dest(destinationPdb)); }; return gulp.parallel(exe, pdb); } return exe; } function confirmPdbsExist(destinationExe, destinationPdb) { readdirSync(destinationExe).forEach(file => { if (excludedCheckList.includes(file)) { return; } if (file.endsWith('.dll') || file.endsWith('.exe')) { const pdb = `${file}.pdb`; if (!existsSync(path.join(destinationPdb, pdb))) { throw new Error(`Missing pdb file for ${file}. Tried searching for ${pdb} in ${destinationPdb}.`); } } }); return Promise.resolve(); } ================================================ FILE: build/gulpfile.vscode.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const fs = require('fs'); const path = require('path'); const es = require('event-stream'); const vfs = require('vinyl-fs'); const rename = require('gulp-rename'); const replace = require('gulp-replace'); const filter = require('gulp-filter'); const util = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const { readISODate } = require('./lib/date'); const task = require('./lib/task'); const buildfile = require('./buildfile'); const optimize = require('./lib/optimize'); const { inlineMeta } = require('./lib/inlineMeta'); const root = path.dirname(__dirname); const commit = getVersion(root); const packageJson = require('../package.json'); const product = require('../product.json'); const crypto = require('crypto'); const i18n = require('./lib/i18n'); const { getProductionDependencies } = require('./lib/dependencies'); const { config } = require('./lib/electron'); const createAsar = require('./lib/asar').createAsar; const minimist = require('minimist'); const { compileBuildWithoutManglingTask, compileBuildWithManglingTask } = require('./gulpfile.compile'); const { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask } = require('./gulpfile.extensions'); const { promisify } = require('util'); const glob = promisify(require('glob')); const rcedit = promisify(require('rcedit')); // Build const vscodeEntryPoints = [ buildfile.workerEditor, buildfile.workerExtensionHost, buildfile.workerNotebook, buildfile.workerLanguageDetection, buildfile.workerLocalFileSearch, buildfile.workerProfileAnalysis, buildfile.workerOutputLinks, buildfile.workerBackgroundTokenization, buildfile.workbenchDesktop, buildfile.code ].flat(); const vscodeResourceIncludes = [ // NLS 'out-build/nls.messages.json', 'out-build/nls.keys.json', // Workbench 'out-build/vs/code/electron-sandbox/workbench/workbench.html', // Electron Preload 'out-build/vs/base/parts/sandbox/electron-sandbox/preload.js', 'out-build/vs/base/parts/sandbox/electron-sandbox/preload-aux.js', // Node Scripts 'out-build/vs/base/node/{terminateProcess.sh,cpuUsage.sh,ps.sh}', // Touchbar 'out-build/vs/workbench/browser/parts/editor/media/*.png', 'out-build/vs/workbench/contrib/debug/browser/media/*.png', // External Terminal 'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt', // Terminal shell integration 'out-build/vs/workbench/contrib/terminal/common/scripts/*.fish', 'out-build/vs/workbench/contrib/terminal/common/scripts/*.ps1', 'out-build/vs/workbench/contrib/terminal/common/scripts/*.psm1', 'out-build/vs/workbench/contrib/terminal/common/scripts/*.sh', 'out-build/vs/workbench/contrib/terminal/common/scripts/*.zsh', // Accessibility Signals 'out-build/vs/platform/accessibilitySignal/browser/media/*.mp3', // Welcome 'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}', // Extensions 'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', 'out-build/vs/workbench/services/extensionManagement/common/media/*.{svg,png}', // Webview 'out-build/vs/workbench/contrib/webview/browser/pre/*.{js,html}', // Extension Host Worker 'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html', // Process Explorer 'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.html', // Tree Sitter highlights 'out-build/vs/editor/common/languages/highlights/*.scm', // Tree Sitter injection queries 'out-build/vs/editor/common/languages/injections/*.scm', ]; const vscodeResources = [ // Includes ...vscodeResourceIncludes, // Excludes '!out-build/vs/code/browser/**', '!out-build/vs/editor/standalone/**', '!out-build/vs/code/**/*-dev.html', '!out-build/vs/workbench/contrib/issue/**/*-dev.html', '!**/test/**' ]; const bootstrapEntryPoints = [ 'out-build/main.js', 'out-build/cli.js', 'out-build/bootstrap-fork.js' ]; const bundleVSCodeTask = task.define('bundle-vscode', task.series( util.rimraf('out-vscode'), // Optimize: bundles source files automatically based on // import statements based on the passed in entry points. // In addition, concat window related bootstrap files into // a single file. optimize.bundleTask( { out: 'out-vscode', esm: { src: 'out-build', entryPoints: [ ...vscodeEntryPoints, ...bootstrapEntryPoints ], resources: vscodeResources, fileContentMapper: filePath => { if ( filePath.endsWith('vs/code/electron-sandbox/workbench/workbench.js') || filePath.endsWith('vs/code/electron-sandbox/processExplorer/processExplorer.js')) { return async (content) => { const bootstrapWindowContent = await fs.promises.readFile(path.join(root, 'out-build', 'bootstrap-window.js'), 'utf-8'); return `${bootstrapWindowContent}\n${content}`; // prepend bootstrap-window.js content to entry points that are Electron windows }; } return undefined; }, skipTSBoilerplateRemoval: entryPoint => entryPoint === 'vs/code/electron-sandbox/workbench/workbench' || entryPoint === 'vs/code/electron-sandbox/processExplorer/processExplorer', } } ) )); gulp.task(bundleVSCodeTask); const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; const minifyVSCodeTask = task.define('minify-vscode', task.series( bundleVSCodeTask, util.rimraf('out-vscode-min'), optimize.minifyTask('out-vscode', `${sourceMappingURLBase}/core`) )); gulp.task(minifyVSCodeTask); const coreCI = task.define('core-ci', task.series( gulp.task('compile-build-with-mangling'), task.parallel( gulp.task('minify-vscode'), gulp.task('minify-vscode-reh'), gulp.task('minify-vscode-reh-web'), ) )); gulp.task(coreCI); const coreCIPR = task.define('core-ci-pr', task.series( gulp.task('compile-build-without-mangling'), task.parallel( gulp.task('minify-vscode'), gulp.task('minify-vscode-reh'), gulp.task('minify-vscode-reh-web'), ) )); gulp.task(coreCIPR); /** * Compute checksums for some files. * * @param {string} out The out folder to read the file from. * @param {string[]} filenames The paths to compute a checksum for. * @return {Object} A map of paths to checksums. */ function computeChecksums(out, filenames) { const result = {}; filenames.forEach(function (filename) { const fullPath = path.join(process.cwd(), out, filename); result[filename] = computeChecksum(fullPath); }); return result; } /** * Compute checksum for a file. * * @param {string} filename The absolute path to a filename. * @return {string} The checksum for `filename`. */ function computeChecksum(filename) { const contents = fs.readFileSync(filename); const hash = crypto .createHash('sha256') .update(contents) .digest('base64') .replace(/=+$/, ''); return hash; } function packageTask(platform, arch, sourceFolderName, destinationFolderName, opts) { opts = opts || {}; const destination = path.join(path.dirname(root), destinationFolderName); platform = platform || process.platform; return () => { const electron = require('@vscode/gulp-electron'); const json = require('gulp-json-editor'); const out = sourceFolderName; const checksums = computeChecksums(out, [ 'vs/base/parts/sandbox/electron-sandbox/preload.js', 'vs/workbench/workbench.desktop.main.js', 'vs/workbench/workbench.desktop.main.css', 'vs/workbench/api/node/extensionHostProcess.js', 'vs/code/electron-sandbox/workbench/workbench.html', 'vs/code/electron-sandbox/workbench/workbench.js' ]); const src = gulp.src(out + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + out), 'out'); })) .pipe(util.setExecutableBit(['**/*.sh'])); const platformSpecificBuiltInExtensionsExclusions = product.builtInExtensions.filter(ext => { if (!ext.platforms) { return false; } const set = new Set(ext.platforms); return !set.has(platform); }).map(ext => `!.build/extensions/${ext.name}/**`); const extensions = gulp.src(['.build/extensions/**', ...platformSpecificBuiltInExtensionsExclusions], { base: '.build', dot: true }); const sources = es.merge(src, extensions) .pipe(filter(['**', '!**/*.js.map'], { dot: true })); let version = packageJson.version; const quality = product.quality; if (quality && quality !== 'stable') { version += '-' + quality; } const name = product.nameShort; const packageJsonUpdates = { name, version }; if (platform === 'linux') { packageJsonUpdates.desktopName = `${product.applicationName}.desktop`; } let packageJsonContents; const packageJsonStream = gulp.src(['package.json'], { base: '.' }) .pipe(json(packageJsonUpdates)) .pipe(es.through(function (file) { packageJsonContents = file.contents.toString(); this.emit('data', file); })); let productJsonContents; const productJsonStream = gulp.src(['product.json'], { base: '.' }) .pipe(json({ commit, date: readISODate('out-build'), checksums, version })) .pipe(es.through(function (file) { productJsonContents = file.contents.toString(); this.emit('data', file); })); const license = gulp.src([product.licenseFileName, 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.', allowEmpty: true }); // TODO the API should be copied to `out` during compile, not here const api = gulp.src('src/vscode-dts/vscode.d.ts').pipe(rename('out/vscode-dts/vscode.d.ts')); const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true }); const jsFilter = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path)); const root = path.resolve(path.join(__dirname, '..')); const productionDependencies = getProductionDependencies(root); const dependenciesSrc = productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat().concat('!**/*.mk'); const deps = gulp.src(dependenciesSrc, { base: '.', dot: true }) .pipe(filter(['**', `!**/${config.version}/**`, '!**/bin/darwin-arm64-87/**', '!**/package-lock.json', '!**/yarn.lock', '!**/*.js.map'])) .pipe(util.cleanNodeModules(path.join(__dirname, '.moduleignore'))) .pipe(util.cleanNodeModules(path.join(__dirname, `.moduleignore.${process.platform}`))) .pipe(jsFilter) .pipe(util.rewriteSourceMappingURL(sourceMappingURLBase)) .pipe(jsFilter.restore) .pipe(createAsar(path.join(process.cwd(), 'node_modules'), [ '**/*.node', '**/@vscode/ripgrep/bin/*', '**/node-pty/build/Release/*', '**/node-pty/build/Release/conpty/*', '**/node-pty/lib/worker/conoutSocketWorker.js', '**/node-pty/lib/shared/conout.js', '**/*.wasm', '**/@vscode/vsce-sign/bin/*', ], [ '**/*.mk', '!node_modules/vsda/**' // stay compatible with extensions that depend on us shipping `vsda` into ASAR ], [ 'node_modules/vsda/**' // retain copy of `vsda` in node_modules for internal use ], 'node_modules.asar')); let all = es.merge( packageJsonStream, productJsonStream, license, api, telemetry, sources, deps ); if (platform === 'win32') { all = es.merge(all, gulp.src([ 'resources/win32/bower.ico', 'resources/win32/c.ico', 'resources/win32/config.ico', 'resources/win32/cpp.ico', 'resources/win32/csharp.ico', 'resources/win32/css.ico', 'resources/win32/default.ico', 'resources/win32/go.ico', 'resources/win32/html.ico', 'resources/win32/jade.ico', 'resources/win32/java.ico', 'resources/win32/javascript.ico', 'resources/win32/json.ico', 'resources/win32/less.ico', 'resources/win32/markdown.ico', 'resources/win32/php.ico', 'resources/win32/powershell.ico', 'resources/win32/python.ico', 'resources/win32/react.ico', 'resources/win32/ruby.ico', 'resources/win32/sass.ico', 'resources/win32/shell.ico', 'resources/win32/sql.ico', 'resources/win32/typescript.ico', 'resources/win32/vue.ico', 'resources/win32/xml.ico', 'resources/win32/yaml.ico', 'resources/win32/code_70x70.png', 'resources/win32/code_150x150.png' ], { base: '.' })); } else if (platform === 'linux') { all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' })); } else if (platform === 'darwin') { const shortcut = gulp.src('resources/darwin/bin/code.sh') .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('bin/code')); const policyDest = gulp.src('.build/policies/darwin/**', { base: '.build/policies/darwin' }) .pipe(rename(f => f.dirname = `policies/${f.dirname}`)); all = es.merge(all, shortcut, policyDest); } let result = all .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()) .pipe(filter(['**', '!**/.github/**'], { dot: true })) // https://github.com/microsoft/vscode/issues/116523 .pipe(electron({ ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, ffmpegChromium: false })) .pipe(filter(['**', '!LICENSE', '!version'], { dot: true })); if (platform === 'linux') { result = es.merge(result, gulp.src('resources/completions/bash/code', { base: '.' }) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(function (f) { f.basename = product.applicationName; }))); result = es.merge(result, gulp.src('resources/completions/zsh/_code', { base: '.' }) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename(function (f) { f.basename = '_' + product.applicationName; }))); } if (platform === 'win32') { result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32', allowEmpty: true })); result = es.merge(result, gulp.src('resources/win32/bin/code.cmd', { base: 'resources/win32' }) .pipe(replace('@@NAME@@', product.nameShort)) .pipe(rename(function (f) { f.basename = product.applicationName; }))); result = es.merge(result, gulp.src('resources/win32/bin/code.sh', { base: 'resources/win32' }) .pipe(replace('@@NAME@@', product.nameShort)) .pipe(replace('@@PRODNAME@@', product.nameLong)) .pipe(replace('@@VERSION@@', version)) .pipe(replace('@@COMMIT@@', commit)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(replace('@@SERVERDATAFOLDER@@', product.serverDataFolderName || '.vscode-remote')) .pipe(replace('@@QUALITY@@', quality)) .pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; }))); result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' }) .pipe(rename(product.nameShort + '.VisualElementsManifest.xml'))); result = es.merge(result, gulp.src('.build/policies/win32/**', { base: '.build/policies/win32' }) .pipe(rename(f => f.dirname = `policies/${f.dirname}`))); if (quality === 'insider') { result = es.merge(result, gulp.src('.build/win32/appx/**', { base: '.build/win32' })); } } else if (platform === 'linux') { result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' }) .pipe(replace('@@PRODNAME@@', product.nameLong)) .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('bin/' + product.applicationName))); } result = inlineMeta(result, { targetPaths: bootstrapEntryPoints, packageJsonFn: () => packageJsonContents, productJsonFn: () => productJsonContents }); return result.pipe(vfs.dest(destination)); }; } function patchWin32DependenciesTask(destinationFolderName) { const cwd = path.join(path.dirname(root), destinationFolderName); return async () => { const deps = await glob('**/*.node', { cwd, ignore: 'extensions/node_modules/@parcel/watcher/**' }); const packageJson = JSON.parse(await fs.promises.readFile(path.join(cwd, 'resources', 'app', 'package.json'), 'utf8')); const product = JSON.parse(await fs.promises.readFile(path.join(cwd, 'resources', 'app', 'product.json'), 'utf8')); const baseVersion = packageJson.version.replace(/-.*$/, ''); await Promise.all(deps.map(async dep => { const basename = path.basename(dep); await rcedit(path.join(cwd, dep), { 'file-version': baseVersion, 'version-string': { 'CompanyName': 'Microsoft Corporation', 'FileDescription': product.nameLong, 'FileVersion': packageJson.version, 'InternalName': basename, 'LegalCopyright': 'Copyright (C) 2022 Microsoft. All rights reserved', 'OriginalFilename': basename, 'ProductName': product.nameLong, 'ProductVersion': packageJson.version, } }); })); }; } const buildRoot = path.dirname(root); const BUILD_TARGETS = [ { platform: 'win32', arch: 'x64' }, { platform: 'win32', arch: 'arm64' }, { platform: 'darwin', arch: 'x64', opts: { stats: true } }, { platform: 'darwin', arch: 'arm64', opts: { stats: true } }, { platform: 'linux', arch: 'x64' }, { platform: 'linux', arch: 'armhf' }, { platform: 'linux', arch: 'arm64' }, ]; BUILD_TARGETS.forEach(buildTarget => { const dashed = (str) => (str ? `-${str}` : ``); const platform = buildTarget.platform; const arch = buildTarget.arch; const opts = buildTarget.opts; const [vscode, vscodeMin] = ['', 'min'].map(minified => { const sourceFolderName = `out-vscode${dashed(minified)}`; const destinationFolderName = `VSCode${dashed(platform)}${dashed(arch)}`; const tasks = [ compileNativeExtensionsBuildTask, util.rimraf(path.join(buildRoot, destinationFolderName)), packageTask(platform, arch, sourceFolderName, destinationFolderName, opts) ]; if (platform === 'win32') { tasks.push(patchWin32DependenciesTask(destinationFolderName)); } const vscodeTaskCI = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series(...tasks)); gulp.task(vscodeTaskCI); const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series( minified ? compileBuildWithManglingTask : compileBuildWithoutManglingTask, cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileExtensionMediaBuildTask, minified ? minifyVSCodeTask : bundleVSCodeTask, vscodeTaskCI )); gulp.task(vscodeTask); return vscodeTask; }); if (process.platform === platform && process.arch === arch) { gulp.task(task.define('vscode', task.series(vscode))); gulp.task(task.define('vscode-min', task.series(vscodeMin))); } }); // #region nls const innoSetupConfig = { 'zh-cn': { codePage: 'CP936', defaultInfo: { name: 'Simplified Chinese', id: '$0804', } }, 'zh-tw': { codePage: 'CP950', defaultInfo: { name: 'Traditional Chinese', id: '$0404' } }, 'ko': { codePage: 'CP949', defaultInfo: { name: 'Korean', id: '$0412' } }, 'ja': { codePage: 'CP932' }, 'de': { codePage: 'CP1252' }, 'fr': { codePage: 'CP1252' }, 'es': { codePage: 'CP1252' }, 'ru': { codePage: 'CP1251' }, 'it': { codePage: 'CP1252' }, 'pt-br': { codePage: 'CP1252' }, 'hu': { codePage: 'CP1250' }, 'tr': { codePage: 'CP1254' } }; gulp.task(task.define( 'vscode-translations-export', task.series( coreCI, compileAllExtensionsBuildTask, function () { const pathToMetadata = './out-build/nls.metadata.json'; const pathToExtensions = '.build/extensions/*'; const pathToSetup = 'build/win32/i18n/messages.en.isl'; return es.merge( gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()), gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()), gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions()) ).pipe(vfs.dest('../vscode-translations-export')); } ) )); gulp.task('vscode-translations-import', function () { const options = minimist(process.argv.slice(2), { string: 'location', default: { location: '../vscode-translations-import' } }); return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => { const id = language.id; return gulp.src(`${options.location}/${id}/vscode-setup/messages.xlf`) .pipe(i18n.prepareIslFiles(language, innoSetupConfig[language.id])) .pipe(vfs.dest(`./build/win32/i18n`)); })); }); // #endregion ================================================ FILE: build/gulpfile.vscode.linux.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const replace = require('gulp-replace'); const rename = require('gulp-rename'); const es = require('event-stream'); const vfs = require('vinyl-fs'); const { rimraf } = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const task = require('./lib/task'); const packageJson = require('../package.json'); const product = require('../product.json'); const dependenciesGenerator = require('./linux/dependencies-generator'); const debianRecommendedDependencies = require('./linux/debian/dep-lists').recommendedDeps; const path = require('path'); const cp = require('child_process'); const util = require('util'); const exec = util.promisify(cp.exec); const root = path.dirname(__dirname); const commit = getVersion(root); const linuxPackageRevision = Math.floor(new Date().getTime() / 1000); /** * @param {string} arch */ function getDebPackageArch(arch) { return { x64: 'amd64', armhf: 'armhf', arm64: 'arm64' }[arch]; } function prepareDebPackage(arch) { const binaryDir = '../VSCode-linux-' + arch; const debArch = getDebPackageArch(arch); const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch; return async function () { const dependencies = await dependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch); const desktop = gulp.src('resources/linux/code.desktop', { base: '.' }) .pipe(rename('usr/share/applications/' + product.applicationName + '.desktop')); const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' }) .pipe(rename('usr/share/applications/' + product.applicationName + '-url-handler.desktop')); const desktops = es.merge(desktop, desktopUrlHandler) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME_SHORT@@', product.nameShort)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@EXEC@@', `/usr/share/${product.applicationName}/${product.applicationName}`)) .pipe(replace('@@ICON@@', product.linuxIconName)) .pipe(replace('@@URLPROTOCOL@@', product.urlProtocol)); const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' }) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@LICENSE@@', product.licenseName)) .pipe(rename('usr/share/appdata/' + product.applicationName + '.appdata.xml')); const workspaceMime = gulp.src('resources/linux/code-workspace.xml', { base: '.' }) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('usr/share/mime/packages/' + product.applicationName + '-workspace.xml')); const icon = gulp.src('resources/linux/code.png', { base: '.' }) .pipe(rename('usr/share/pixmaps/' + product.linuxIconName + '.png')); const bash_completion = gulp.src('resources/completions/bash/code') .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('usr/share/bash-completion/completions/' + product.applicationName)); const zsh_completion = gulp.src('resources/completions/zsh/_code') .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('usr/share/zsh/vendor-completions/_' + product.applicationName)); const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; })); let size = 0; const control = code.pipe(es.through( function (f) { size += f.isDirectory() ? 4096 : f.contents.length; }, function () { const that = this; gulp.src('resources/linux/debian/control.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@VERSION@@', packageJson.version + '-' + linuxPackageRevision)) .pipe(replace('@@ARCHITECTURE@@', debArch)) .pipe(replace('@@DEPENDS@@', dependencies.join(', '))) .pipe(replace('@@RECOMMENDS@@', debianRecommendedDependencies.join(', '))) .pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024))) .pipe(rename('DEBIAN/control')) .pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); })); })); const prerm = gulp.src('resources/linux/debian/prerm.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('DEBIAN/prerm')); const postrm = gulp.src('resources/linux/debian/postrm.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('DEBIAN/postrm')); const postinst = gulp.src('resources/linux/debian/postinst.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('DEBIAN/postinst')); const templates = gulp.src('resources/linux/debian/templates.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('DEBIAN/templates')); const all = es.merge(control, templates, postinst, postrm, prerm, desktops, appdata, workspaceMime, icon, bash_completion, zsh_completion, code); return all.pipe(vfs.dest(destination)); }; } /** * @param {string} arch */ function buildDebPackage(arch) { const debArch = getDebPackageArch(arch); const cwd = `.build/linux/deb/${debArch}`; return async () => { await exec(`chmod 755 ${product.applicationName}-${debArch}/DEBIAN/postinst ${product.applicationName}-${debArch}/DEBIAN/prerm ${product.applicationName}-${debArch}/DEBIAN/postrm`, { cwd }); await exec('mkdir -p deb', { cwd }); await exec(`fakeroot dpkg-deb -Zxz -b ${product.applicationName}-${debArch} deb`, { cwd }); }; } /** * @param {string} rpmArch */ function getRpmBuildPath(rpmArch) { return '.build/linux/rpm/' + rpmArch + '/rpmbuild'; } /** * @param {string} arch */ function getRpmPackageArch(arch) { return { x64: 'x86_64', armhf: 'armv7hl', arm64: 'aarch64' }[arch]; } /** * @param {string} arch */ function prepareRpmPackage(arch) { const binaryDir = '../VSCode-linux-' + arch; const rpmArch = getRpmPackageArch(arch); const stripBinary = process.env['STRIP'] ?? '/usr/bin/strip'; return async function () { const dependencies = await dependenciesGenerator.getDependencies('rpm', binaryDir, product.applicationName, rpmArch); const desktop = gulp.src('resources/linux/code.desktop', { base: '.' }) .pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop')); const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' }) .pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '-url-handler.desktop')); const desktops = es.merge(desktop, desktopUrlHandler) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME_SHORT@@', product.nameShort)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@EXEC@@', `/usr/share/${product.applicationName}/${product.applicationName}`)) .pipe(replace('@@ICON@@', product.linuxIconName)) .pipe(replace('@@URLPROTOCOL@@', product.urlProtocol)); const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' }) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@LICENSE@@', product.licenseName)) .pipe(rename('BUILD/usr/share/appdata/' + product.applicationName + '.appdata.xml')); const workspaceMime = gulp.src('resources/linux/code-workspace.xml', { base: '.' }) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('BUILD/usr/share/mime/packages/' + product.applicationName + '-workspace.xml')); const icon = gulp.src('resources/linux/code.png', { base: '.' }) .pipe(rename('BUILD/usr/share/pixmaps/' + product.linuxIconName + '.png')); const bash_completion = gulp.src('resources/completions/bash/code') .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('BUILD/usr/share/bash-completion/completions/' + product.applicationName)); const zsh_completion = gulp.src('resources/completions/zsh/_code') .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('BUILD/usr/share/zsh/site-functions/_' + product.applicationName)); const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; })); const spec = gulp.src('resources/linux/rpm/code.spec.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@ICON@@', product.linuxIconName)) .pipe(replace('@@VERSION@@', packageJson.version)) .pipe(replace('@@RELEASE@@', linuxPackageRevision)) .pipe(replace('@@ARCHITECTURE@@', rpmArch)) .pipe(replace('@@LICENSE@@', product.licenseName)) .pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@')) .pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@')) .pipe(replace('@@DEPENDENCIES@@', dependencies.join(', '))) .pipe(replace('@@STRIP@@', stripBinary)) .pipe(rename('SPECS/' + product.applicationName + '.spec')); const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' }) .pipe(rename('SOURCES/' + product.applicationName + '.xpm')); const all = es.merge(code, desktops, appdata, workspaceMime, icon, bash_completion, zsh_completion, spec, specIcon); return all.pipe(vfs.dest(getRpmBuildPath(rpmArch))); }; } /** * @param {string} arch */ function buildRpmPackage(arch) { const rpmArch = getRpmPackageArch(arch); const rpmBuildPath = getRpmBuildPath(rpmArch); const rpmOut = `${rpmBuildPath}/RPMS/${rpmArch}`; const destination = `.build/linux/rpm/${rpmArch}`; return async () => { await exec(`mkdir -p ${destination}`); await exec(`HOME="$(pwd)/${destination}" rpmbuild -bb ${rpmBuildPath}/SPECS/${product.applicationName}.spec --target=${rpmArch}`); await exec(`cp "${rpmOut}/$(ls ${rpmOut})" ${destination}/`); }; } /** * @param {string} arch */ function getSnapBuildPath(arch) { return `.build/linux/snap/${arch}/${product.applicationName}-${arch}`; } /** * @param {string} arch */ function prepareSnapPackage(arch) { const binaryDir = '../VSCode-linux-' + arch; const destination = getSnapBuildPath(arch); return function () { // A desktop file that is placed in snap/gui will be placed into meta/gui verbatim. const desktop = gulp.src('resources/linux/code.desktop', { base: '.' }) .pipe(rename(`snap/gui/${product.applicationName}.desktop`)); // A desktop file that is placed in snap/gui will be placed into meta/gui verbatim. const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' }) .pipe(rename(`snap/gui/${product.applicationName}-url-handler.desktop`)); const desktops = es.merge(desktop, desktopUrlHandler) .pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME_SHORT@@', product.nameShort)) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@EXEC@@', `${product.applicationName} --force-user-env`)) .pipe(replace('@@ICON@@', `\${SNAP}/meta/gui/${product.linuxIconName}.png`)) .pipe(replace('@@URLPROTOCOL@@', product.urlProtocol)); // An icon that is placed in snap/gui will be placed into meta/gui verbatim. const icon = gulp.src('resources/linux/code.png', { base: '.' }) .pipe(rename(`snap/gui/${product.linuxIconName}.png`)); const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = `usr/share/${product.applicationName}/${p.dirname}`; })); const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@VERSION@@', commit.substr(0, 8))) // Possible run-on values https://snapcraft.io/docs/architectures .pipe(replace('@@ARCHITECTURE@@', arch === 'x64' ? 'amd64' : arch)) .pipe(rename('snap/snapcraft.yaml')); const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' }) .pipe(rename('electron-launch')); const all = es.merge(desktops, icon, code, snapcraft, electronLaunch); return all.pipe(vfs.dest(destination)); }; } /** * @param {string} arch */ function buildSnapPackage(arch) { const cwd = getSnapBuildPath(arch); return () => exec('snapcraft', { cwd }); } const BUILD_TARGETS = [ { arch: 'x64' }, { arch: 'armhf' }, { arch: 'arm64' }, ]; BUILD_TARGETS.forEach(({ arch }) => { const debArch = getDebPackageArch(arch); const prepareDebTask = task.define(`vscode-linux-${arch}-prepare-deb`, task.series(rimraf(`.build/linux/deb/${debArch}`), prepareDebPackage(arch))); gulp.task(prepareDebTask); const buildDebTask = task.define(`vscode-linux-${arch}-build-deb`, buildDebPackage(arch)); gulp.task(buildDebTask); const rpmArch = getRpmPackageArch(arch); const prepareRpmTask = task.define(`vscode-linux-${arch}-prepare-rpm`, task.series(rimraf(`.build/linux/rpm/${rpmArch}`), prepareRpmPackage(arch))); gulp.task(prepareRpmTask); const buildRpmTask = task.define(`vscode-linux-${arch}-build-rpm`, buildRpmPackage(arch)); gulp.task(buildRpmTask); const prepareSnapTask = task.define(`vscode-linux-${arch}-prepare-snap`, task.series(rimraf(`.build/linux/snap/${arch}`), prepareSnapPackage(arch))); gulp.task(prepareSnapTask); const buildSnapTask = task.define(`vscode-linux-${arch}-build-snap`, task.series(prepareSnapTask, buildSnapPackage(arch))); gulp.task(buildSnapTask); }); ================================================ FILE: build/gulpfile.vscode.web.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const path = require('path'); const es = require('event-stream'); const util = require('./lib/util'); const { getVersion } = require('./lib/getVersion'); const task = require('./lib/task'); const optimize = require('./lib/optimize'); const { readISODate } = require('./lib/date'); const product = require('../product.json'); const rename = require('gulp-rename'); const filter = require('gulp-filter'); const { getProductionDependencies } = require('./lib/dependencies'); const vfs = require('vinyl-fs'); const packageJson = require('../package.json'); const { compileBuildWithManglingTask } = require('./gulpfile.compile'); const extensions = require('./lib/extensions'); const VinylFile = require('vinyl'); const REPO_ROOT = path.dirname(__dirname); const BUILD_ROOT = path.dirname(REPO_ROOT); const WEB_FOLDER = path.join(REPO_ROOT, 'remote', 'web'); const commit = getVersion(REPO_ROOT); const quality = product.quality; const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version; const vscodeWebResourceIncludes = [ // NLS 'out-build/nls.messages.js', // Accessibility Signals 'out-build/vs/platform/accessibilitySignal/browser/media/*.mp3', // Welcome 'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}', // Extensions 'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', 'out-build/vs/workbench/services/extensionManagement/common/media/*.{svg,png}', // Webview 'out-build/vs/workbench/contrib/webview/browser/pre/*.{js,html}', // Tree Sitter highlights 'out-build/vs/editor/common/languages/highlights/*.scm', // Tree Sitter injections 'out-build/vs/editor/common/languages/injections/*.scm', // Extension Host Worker 'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html', ]; exports.vscodeWebResourceIncludes = vscodeWebResourceIncludes; const vscodeWebResources = [ // Includes ...vscodeWebResourceIncludes, // Excludes '!out-build/vs/**/{node,electron-sandbox,electron-main,electron-utility}/**', '!out-build/vs/editor/standalone/**', '!out-build/vs/workbench/**/*-tb.png', '!out-build/vs/code/**/*-dev.html', '!**/test/**' ]; const buildfile = require('./buildfile'); const vscodeWebEntryPoints = [ buildfile.workerEditor, buildfile.workerExtensionHost, buildfile.workerNotebook, buildfile.workerLanguageDetection, buildfile.workerLocalFileSearch, buildfile.workerOutputLinks, buildfile.workerBackgroundTokenization, buildfile.keyboardMaps, buildfile.workbenchWeb, buildfile.entrypoint('vs/workbench/workbench.web.main.internal') // TODO@esm remove line when we stop supporting web-amd-esm-bridge ].flat(); /** * @param extensionsRoot {string} The location where extension will be read from * @param {object} product The parsed product.json file contents */ const createVSCodeWebFileContentMapper = (extensionsRoot, product) => { return path => { if (path.endsWith('vs/platform/product/common/product.js')) { return content => { const productConfiguration = JSON.stringify({ ...product, version, commit, date: readISODate('out-build') }); return content.replace('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/', () => productConfiguration.substr(1, productConfiguration.length - 2) /* without { and }*/); }; } else if (path.endsWith('vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js')) { return content => { const builtinExtensions = JSON.stringify(extensions.scanBuiltinExtensions(extensionsRoot)); return content.replace('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/', () => builtinExtensions.substr(1, builtinExtensions.length - 2) /* without [ and ]*/); }; } return undefined; }; }; exports.createVSCodeWebFileContentMapper = createVSCodeWebFileContentMapper; const bundleVSCodeWebTask = task.define('bundle-vscode-web', task.series( util.rimraf('out-vscode-web'), optimize.bundleTask( { out: 'out-vscode-web', esm: { src: 'out-build', entryPoints: vscodeWebEntryPoints, resources: vscodeWebResources, fileContentMapper: createVSCodeWebFileContentMapper('.build/web/extensions', product) } } ) )); const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series( bundleVSCodeWebTask, util.rimraf('out-vscode-web-min'), optimize.minifyTask('out-vscode-web', `https://main.vscode-cdn.net/sourcemaps/${commit}/core`) )); gulp.task(minifyVSCodeWebTask); function packageTask(sourceFolderName, destinationFolderName) { const destination = path.join(BUILD_ROOT, destinationFolderName); return () => { const json = require('gulp-json-editor'); const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })); const extensions = gulp.src('.build/web/extensions/**', { base: '.build/web', dot: true }); const loader = gulp.src('build/loader.min', { base: 'build', dot: true }).pipe(rename('out/vs/loader.js')); // TODO@esm remove line when we stop supporting web-amd-esm-bridge const sources = es.merge(src, extensions, loader) .pipe(filter(['**', '!**/*.js.map'], { dot: true })) // TODO@esm remove me once we stop supporting our web-esm-bridge .pipe(es.through(function (file) { if (file.relative === 'out/vs/workbench/workbench.web.main.internal.css') { this.emit('data', new VinylFile({ contents: file.contents, path: file.path.replace('workbench.web.main.internal.css', 'workbench.web.main.css'), base: file.base })); } this.emit('data', file); })); const name = product.nameShort; const packageJsonStream = gulp.src(['remote/web/package.json'], { base: 'remote/web' }) .pipe(json({ name, version })); const license = gulp.src(['remote/LICENSE'], { base: 'remote', allowEmpty: true }); const productionDependencies = getProductionDependencies(WEB_FOLDER); const dependenciesSrc = productionDependencies.map(d => path.relative(REPO_ROOT, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`, `!${d}/.bin/**`]).flat(); const deps = gulp.src(dependenciesSrc, { base: 'remote/web', dot: true }) .pipe(filter(['**', '!**/package-lock.json'])) .pipe(util.cleanNodeModules(path.join(__dirname, '.webignore'))); const favicon = gulp.src('resources/server/favicon.ico', { base: 'resources/server' }); const manifest = gulp.src('resources/server/manifest.json', { base: 'resources/server' }); const pwaicons = es.merge( gulp.src('resources/server/code-192.png', { base: 'resources/server' }), gulp.src('resources/server/code-512.png', { base: 'resources/server' }) ); const all = es.merge( packageJsonStream, license, sources, deps, favicon, manifest, pwaicons ); const result = all .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()); return result.pipe(vfs.dest(destination)); }; } const compileWebExtensionsBuildTask = task.define('compile-web-extensions-build', task.series( task.define('clean-web-extensions-build', util.rimraf('.build/web/extensions')), task.define('bundle-web-extensions-build', () => extensions.packageAllLocalExtensionsStream(true, false).pipe(gulp.dest('.build/web'))), task.define('bundle-marketplace-web-extensions-build', () => extensions.packageMarketplaceExtensionsStream(true).pipe(gulp.dest('.build/web'))), task.define('bundle-web-extension-media-build', () => extensions.buildExtensionMedia(false, '.build/web/extensions')), )); gulp.task(compileWebExtensionsBuildTask); const dashed = (/** @type {string} */ str) => (str ? `-${str}` : ``); ['', 'min'].forEach(minified => { const sourceFolderName = `out-vscode-web${dashed(minified)}`; const destinationFolderName = `vscode-web`; const vscodeWebTaskCI = task.define(`vscode-web${dashed(minified)}-ci`, task.series( compileWebExtensionsBuildTask, minified ? minifyVSCodeWebTask : bundleVSCodeWebTask, util.rimraf(path.join(BUILD_ROOT, destinationFolderName)), packageTask(sourceFolderName, destinationFolderName) )); gulp.task(vscodeWebTaskCI); const vscodeWebTask = task.define(`vscode-web${dashed(minified)}`, task.series( compileBuildWithManglingTask, vscodeWebTaskCI )); gulp.task(vscodeWebTask); }); ================================================ FILE: build/gulpfile.vscode.win32.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const gulp = require('gulp'); const path = require('path'); const fs = require('fs'); const assert = require('assert'); const cp = require('child_process'); const util = require('./lib/util'); const task = require('./lib/task'); const pkg = require('../package.json'); const product = require('../product.json'); const vfs = require('vinyl-fs'); const rcedit = require('rcedit'); const repoPath = path.dirname(__dirname); const buildPath = (/** @type {string} */ arch) => path.join(path.dirname(repoPath), `VSCode-win32-${arch}`); const setupDir = (/** @type {string} */ arch, /** @type {string} */ target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`); const issPath = path.join(__dirname, 'win32', 'code.iss'); const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup'))), 'bin', 'ISCC.exe'); const signWin32Path = path.join(repoPath, 'build', 'azure-pipelines', 'common', 'sign-win32'); function packageInnoSetup(iss, options, cb) { options = options || {}; const definitions = options.definitions || {}; if (process.argv.some(arg => arg === '--debug-inno')) { definitions['Debug'] = 'true'; } if (process.argv.some(arg => arg === '--sign')) { definitions['Sign'] = 'true'; } const keys = Object.keys(definitions); keys.forEach(key => assert(typeof definitions[key] === 'string', `Missing value for '${key}' in Inno Setup package step`)); const defs = keys.map(key => `/d${key}=${definitions[key]}`); const args = [ iss, ...defs, `/sesrp=node ${signWin32Path} $f` ]; cp.spawn(innoSetupPath, args, { stdio: ['ignore', 'inherit', 'inherit'] }) .on('error', cb) .on('exit', code => { if (code === 0) { cb(null); } else { cb(new Error(`InnoSetup returned exit code: ${code}`)); } }); } /** * @param {string} arch * @param {string} target */ function buildWin32Setup(arch, target) { if (target !== 'system' && target !== 'user') { throw new Error('Invalid setup target'); } return cb => { const x64AppId = target === 'system' ? product.win32x64AppId : product.win32x64UserAppId; const arm64AppId = target === 'system' ? product.win32arm64AppId : product.win32arm64UserAppId; const sourcePath = buildPath(arch); const outputPath = setupDir(arch, target); fs.mkdirSync(outputPath, { recursive: true }); const originalProductJsonPath = path.join(sourcePath, 'resources/app/product.json'); const productJsonPath = path.join(outputPath, 'product.json'); const productJson = JSON.parse(fs.readFileSync(originalProductJsonPath, 'utf8')); productJson['target'] = target; fs.writeFileSync(productJsonPath, JSON.stringify(productJson, undefined, '\t')); const quality = product.quality || 'dev'; const definitions = { NameLong: product.nameLong, NameShort: product.nameShort, DirName: product.win32DirName, Version: pkg.version, RawVersion: pkg.version.replace(/-\w+$/, ''), NameVersion: product.win32NameVersion + (target === 'user' ? ' (User)' : ''), ExeBasename: product.nameShort, RegValueName: product.win32RegValueName, ShellNameShort: product.win32ShellNameShort, AppMutex: product.win32MutexName, TunnelMutex: product.win32TunnelMutex, TunnelServiceMutex: product.win32TunnelServiceMutex, TunnelApplicationName: product.tunnelApplicationName, ApplicationName: product.applicationName, Arch: arch, AppId: { 'x64': x64AppId, 'arm64': arm64AppId }[arch], IncompatibleTargetAppId: { 'x64': product.win32x64AppId, 'arm64': product.win32arm64AppId }[arch], AppUserId: product.win32AppUserModelId, ArchitecturesAllowed: { 'x64': 'x64', 'arm64': 'arm64' }[arch], ArchitecturesInstallIn64BitMode: { 'x64': 'x64', 'arm64': 'arm64' }[arch], SourceDir: sourcePath, RepoDir: repoPath, OutputDir: outputPath, InstallTarget: target, ProductJsonPath: productJsonPath, Quality: quality }; if (quality === 'insider') { definitions['AppxPackage'] = `code_insiders_explorer_${arch}.appx`; definitions['AppxPackageFullname'] = `Microsoft.${product.win32RegValueName}_1.0.0.0_neutral__8wekyb3d8bbwe`; } packageInnoSetup(issPath, { definitions }, cb); }; } /** * @param {string} arch * @param {string} target */ function defineWin32SetupTasks(arch, target) { const cleanTask = util.rimraf(setupDir(arch, target)); gulp.task(task.define(`vscode-win32-${arch}-${target}-setup`, task.series(cleanTask, buildWin32Setup(arch, target)))); } defineWin32SetupTasks('x64', 'system'); defineWin32SetupTasks('arm64', 'system'); defineWin32SetupTasks('x64', 'user'); defineWin32SetupTasks('arm64', 'user'); /** * @param {string} arch */ function copyInnoUpdater(arch) { return () => { return gulp.src('build/win32/{inno_updater.exe,vcruntime140.dll}', { base: 'build/win32' }) .pipe(vfs.dest(path.join(buildPath(arch), 'tools'))); }; } /** * @param {string} executablePath */ function updateIcon(executablePath) { return cb => { const icon = path.join(repoPath, 'resources', 'win32', 'code.ico'); rcedit(executablePath, { icon }, cb); }; } gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), updateIcon(path.join(buildPath('x64'), 'tools', 'inno_updater.exe'))))); gulp.task(task.define('vscode-win32-arm64-inno-updater', task.series(copyInnoUpdater('arm64'), updateIcon(path.join(buildPath('arm64'), 'tools', 'inno_updater.exe'))))); ================================================ FILE: build/hygiene.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const filter = require('gulp-filter'); const es = require('event-stream'); const VinylFile = require('vinyl'); const vfs = require('vinyl-fs'); const path = require('path'); const fs = require('fs'); const pall = require('p-all'); const { all, copyrightFilter, unicodeFilter, indentationFilter, tsFormattingFilter, eslintFilter, stylelintFilter } = require('./filters'); const copyrightHeaderLines = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', ]; function hygiene(some, linting = true) { const eslint = require('./gulp-eslint'); const gulpstylelint = require('./stylelint'); const formatter = require('./lib/formatter'); let errorCount = 0; const productJson = es.through(function (file) { const product = JSON.parse(file.contents.toString('utf8')); if (product.extensionsGallery) { console.error(`product.json: Contains 'extensionsGallery'`); errorCount++; } this.emit('data', file); }); const unicode = es.through(function (file) { const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; const allowInComments = lines.some(line => /allow-any-unicode-comment-file/.test(line)); let skipNext = false; lines.forEach((line, i) => { if (/allow-any-unicode-next-line/.test(line)) { skipNext = true; return; } if (skipNext) { skipNext = false; return; } // If unicode is allowed in comments, trim the comment from the line if (allowInComments) { if (line.match(/\s+(\*)/)) { // Naive multi-line comment check line = ''; } else { const index = line.indexOf('\/\/'); line = index === -1 ? line : line.substring(0, index); } } // Please do not add symbols that resemble ASCII letters! // eslint-disable-next-line no-misleading-character-class const m = /([^\t\n\r\x20-\x7E⊃⊇✔︎✓🎯⚠️🛑🔴🚗🚙🚕🎉✨❗⇧⌥⌘×÷¦⋯…↑↓→→←↔⟷·•●◆▼⟪⟫┌└├⏎↩√φ]+)/g.exec(line); if (m) { console.error( file.relative + `(${i + 1},${m.index + 1}): Unexpected unicode character: "${m[0]}" (charCode: ${m[0].charCodeAt(0)}). To suppress, use // allow-any-unicode-next-line` ); errorCount++; } }); this.emit('data', file); }); const indentation = es.through(function (file) { const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; lines.forEach((line, i) => { if (/^\s*$/.test(line)) { // empty or whitespace lines are OK } else if (/^[\t]*[^\s]/.test(line)) { // good indent } else if (/^[\t]* \*/.test(line)) { // block comment using an extra space } else { console.error( file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation' ); errorCount++; } }); this.emit('data', file); }); const copyrights = es.through(function (file) { const lines = file.__lines; for (let i = 0; i < copyrightHeaderLines.length; i++) { if (lines[i] !== copyrightHeaderLines[i]) { console.error(file.relative + ': Missing or bad copyright statement'); errorCount++; break; } } this.emit('data', file); }); const formatting = es.map(function (file, cb) { try { const rawInput = file.contents.toString('utf8'); const rawOutput = formatter.format(file.path, rawInput); const original = rawInput.replace(/\r\n/gm, '\n'); const formatted = rawOutput.replace(/\r\n/gm, '\n'); if (original !== formatted) { console.error( `File not formatted. Run the 'Format Document' command to fix it:`, file.relative ); errorCount++; } cb(null, file); } catch (err) { cb(err); } }); let input; if (Array.isArray(some) || typeof some === 'string' || !some) { const options = { base: '.', follow: true, allowEmpty: true }; if (some) { input = vfs.src(some, options).pipe(filter(all)); // split this up to not unnecessarily filter all a second time } else { input = vfs.src(all, options); } } else { input = some; } const productJsonFilter = filter('product.json', { restore: true }); const snapshotFilter = filter(['**', '!**/*.snap', '!**/*.snap.actual']); const yarnLockFilter = filter(['**', '!**/yarn.lock']); const unicodeFilterStream = filter(unicodeFilter, { restore: true }); const result = input .pipe(filter((f) => !f.stat.isDirectory())) .pipe(snapshotFilter) .pipe(yarnLockFilter) .pipe(productJsonFilter) .pipe(process.env['BUILD_SOURCEVERSION'] ? es.through() : productJson) .pipe(productJsonFilter.restore) .pipe(unicodeFilterStream) .pipe(unicode) .pipe(unicodeFilterStream.restore) .pipe(filter(indentationFilter)) .pipe(indentation) .pipe(filter(copyrightFilter)) .pipe(copyrights); const streams = [ result.pipe(filter(tsFormattingFilter)).pipe(formatting) ]; if (linting) { streams.push( result .pipe(filter(eslintFilter)) .pipe( eslint((results) => { errorCount += results.warningCount; errorCount += results.errorCount; }) ) ); streams.push( result.pipe(filter(stylelintFilter)).pipe(gulpstylelint(((message, isError) => { if (isError) { console.error(message); errorCount++; } else { console.warn(message); } }))) ); } let count = 0; return es.merge(...streams).pipe( es.through( function (data) { count++; if (process.env['TRAVIS'] && count % 10 === 0) { process.stdout.write('.'); } this.emit('data', data); }, function () { process.stdout.write('\n'); if (errorCount > 0) { this.emit( 'error', 'Hygiene failed with ' + errorCount + ` errors. Check 'build / gulpfile.hygiene.js'.` ); } else { this.emit('end'); } } ) ); } module.exports.hygiene = hygiene; function createGitIndexVinyls(paths) { const cp = require('child_process'); const repositoryPath = process.cwd(); const fns = paths.map((relativePath) => () => new Promise((c, e) => { const fullPath = path.join(repositoryPath, relativePath); fs.stat(fullPath, (err, stat) => { if (err && err.code === 'ENOENT') { // ignore deletions return c(null); } else if (err) { return e(err); } cp.exec( process.platform === 'win32' ? `git show :${relativePath}` : `git show ':${relativePath}'`, { maxBuffer: stat.size, encoding: 'buffer' }, (err, out) => { if (err) { return e(err); } c( new VinylFile({ path: fullPath, base: repositoryPath, contents: out, stat, }) ); } ); }); }) ); return pall(fns, { concurrency: 4 }).then((r) => r.filter((p) => !!p)); } // Void - NO PRE COMMIT HOOKS!!!! for now... - Void team // // this allows us to run hygiene as a git pre-commit hook // if (require.main === module) { // const cp = require('child_process'); // process.on('unhandledRejection', (reason, p) => { // console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); // process.exit(1); // }); // if (process.argv.length > 2) { // hygiene(process.argv.slice(2)).on('error', (err) => { // console.error(); // console.error(err); // process.exit(1); // }); // } else { // cp.exec( // 'git diff --cached --name-only', // { maxBuffer: 2000 * 1024 }, // (err, out) => { // if (err) { // console.error(); // console.error(err); // process.exit(1); // } // const some = out.split(/\r?\n/).filter((l) => !!l); // if (some.length > 0) { // console.log('Reading git index versions...'); // createGitIndexVinyls(some) // .then( // (vinyls) => // new Promise((c, e) => // hygiene(es.readArray(vinyls).pipe(filter(all))) // .on('end', () => c()) // .on('error', e) // ) // ) // .catch((err) => { // console.error(); // console.error(err); // process.exit(1); // }); // } // } // ); // } // } ================================================ FILE: build/lib/asar.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAsar = createAsar; const path_1 = __importDefault(require("path")); const event_stream_1 = __importDefault(require("event-stream")); const pickle = require('chromium-pickle-js'); const Filesystem = require('asar/lib/filesystem'); const vinyl_1 = __importDefault(require("vinyl")); const minimatch_1 = __importDefault(require("minimatch")); function createAsar(folderPath, unpackGlobs, skipGlobs, duplicateGlobs, destFilename) { const shouldUnpackFile = (file) => { for (let i = 0; i < unpackGlobs.length; i++) { if ((0, minimatch_1.default)(file.relative, unpackGlobs[i])) { return true; } } return false; }; const shouldSkipFile = (file) => { for (const skipGlob of skipGlobs) { if ((0, minimatch_1.default)(file.relative, skipGlob)) { return true; } } return false; }; // Files that should be duplicated between // node_modules.asar and node_modules const shouldDuplicateFile = (file) => { for (const duplicateGlob of duplicateGlobs) { if ((0, minimatch_1.default)(file.relative, duplicateGlob)) { return true; } } return false; }; const filesystem = new Filesystem(folderPath); const out = []; // Keep track of pending inserts let pendingInserts = 0; let onFileInserted = () => { pendingInserts--; }; // Do not insert twice the same directory const seenDir = {}; const insertDirectoryRecursive = (dir) => { if (seenDir[dir]) { return; } let lastSlash = dir.lastIndexOf('/'); if (lastSlash === -1) { lastSlash = dir.lastIndexOf('\\'); } if (lastSlash !== -1) { insertDirectoryRecursive(dir.substring(0, lastSlash)); } seenDir[dir] = true; filesystem.insertDirectory(dir); }; const insertDirectoryForFile = (file) => { let lastSlash = file.lastIndexOf('/'); if (lastSlash === -1) { lastSlash = file.lastIndexOf('\\'); } if (lastSlash !== -1) { insertDirectoryRecursive(file.substring(0, lastSlash)); } }; const insertFile = (relativePath, stat, shouldUnpack) => { insertDirectoryForFile(relativePath); pendingInserts++; // Do not pass `onFileInserted` directly because it gets overwritten below. // Create a closure capturing `onFileInserted`. filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}).then(() => onFileInserted(), () => onFileInserted()); }; return event_stream_1.default.through(function (file) { if (file.stat.isDirectory()) { return; } if (!file.stat.isFile()) { throw new Error(`unknown item in stream!`); } if (shouldSkipFile(file)) { this.queue(new vinyl_1.default({ base: '.', path: file.path, stat: file.stat, contents: file.contents })); return; } if (shouldDuplicateFile(file)) { this.queue(new vinyl_1.default({ base: '.', path: file.path, stat: file.stat, contents: file.contents })); } const shouldUnpack = shouldUnpackFile(file); insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack); if (shouldUnpack) { // The file goes outside of xx.asar, in a folder xx.asar.unpacked const relative = path_1.default.relative(folderPath, file.path); this.queue(new vinyl_1.default({ base: '.', path: path_1.default.join(destFilename + '.unpacked', relative), stat: file.stat, contents: file.contents })); } else { // The file goes inside of xx.asar out.push(file.contents); } }, function () { const finish = () => { { const headerPickle = pickle.createEmpty(); headerPickle.writeString(JSON.stringify(filesystem.header)); const headerBuf = headerPickle.toBuffer(); const sizePickle = pickle.createEmpty(); sizePickle.writeUInt32(headerBuf.length); const sizeBuf = sizePickle.toBuffer(); out.unshift(headerBuf); out.unshift(sizeBuf); } const contents = Buffer.concat(out); out.length = 0; this.queue(new vinyl_1.default({ base: '.', path: destFilename, contents: contents })); this.queue(null); }; // Call finish() only when all file inserts have finished... if (pendingInserts === 0) { finish(); } else { onFileInserted = () => { pendingInserts--; if (pendingInserts === 0) { finish(); } }; } }); } //# sourceMappingURL=asar.js.map ================================================ FILE: build/lib/asar.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import es from 'event-stream'; const pickle = require('chromium-pickle-js'); const Filesystem = require('asar/lib/filesystem'); import VinylFile from 'vinyl'; import minimatch from 'minimatch'; declare class AsarFilesystem { readonly header: unknown; constructor(src: string); insertDirectory(path: string, shouldUnpack?: boolean): unknown; insertFile(path: string, shouldUnpack: boolean, file: { stat: { size: number; mode: number } }, options: {}): Promise; } export function createAsar(folderPath: string, unpackGlobs: string[], skipGlobs: string[], duplicateGlobs: string[], destFilename: string): NodeJS.ReadWriteStream { const shouldUnpackFile = (file: VinylFile): boolean => { for (let i = 0; i < unpackGlobs.length; i++) { if (minimatch(file.relative, unpackGlobs[i])) { return true; } } return false; }; const shouldSkipFile = (file: VinylFile): boolean => { for (const skipGlob of skipGlobs) { if (minimatch(file.relative, skipGlob)) { return true; } } return false; }; // Files that should be duplicated between // node_modules.asar and node_modules const shouldDuplicateFile = (file: VinylFile): boolean => { for (const duplicateGlob of duplicateGlobs) { if (minimatch(file.relative, duplicateGlob)) { return true; } } return false; }; const filesystem = new Filesystem(folderPath); const out: Buffer[] = []; // Keep track of pending inserts let pendingInserts = 0; let onFileInserted = () => { pendingInserts--; }; // Do not insert twice the same directory const seenDir: { [key: string]: boolean } = {}; const insertDirectoryRecursive = (dir: string) => { if (seenDir[dir]) { return; } let lastSlash = dir.lastIndexOf('/'); if (lastSlash === -1) { lastSlash = dir.lastIndexOf('\\'); } if (lastSlash !== -1) { insertDirectoryRecursive(dir.substring(0, lastSlash)); } seenDir[dir] = true; filesystem.insertDirectory(dir); }; const insertDirectoryForFile = (file: string) => { let lastSlash = file.lastIndexOf('/'); if (lastSlash === -1) { lastSlash = file.lastIndexOf('\\'); } if (lastSlash !== -1) { insertDirectoryRecursive(file.substring(0, lastSlash)); } }; const insertFile = (relativePath: string, stat: { size: number; mode: number }, shouldUnpack: boolean) => { insertDirectoryForFile(relativePath); pendingInserts++; // Do not pass `onFileInserted` directly because it gets overwritten below. // Create a closure capturing `onFileInserted`. filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}).then(() => onFileInserted(), () => onFileInserted()); }; return es.through(function (file) { if (file.stat.isDirectory()) { return; } if (!file.stat.isFile()) { throw new Error(`unknown item in stream!`); } if (shouldSkipFile(file)) { this.queue(new VinylFile({ base: '.', path: file.path, stat: file.stat, contents: file.contents })); return; } if (shouldDuplicateFile(file)) { this.queue(new VinylFile({ base: '.', path: file.path, stat: file.stat, contents: file.contents })); } const shouldUnpack = shouldUnpackFile(file); insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack); if (shouldUnpack) { // The file goes outside of xx.asar, in a folder xx.asar.unpacked const relative = path.relative(folderPath, file.path); this.queue(new VinylFile({ base: '.', path: path.join(destFilename + '.unpacked', relative), stat: file.stat, contents: file.contents })); } else { // The file goes inside of xx.asar out.push(file.contents); } }, function () { const finish = () => { { const headerPickle = pickle.createEmpty(); headerPickle.writeString(JSON.stringify(filesystem.header)); const headerBuf = headerPickle.toBuffer(); const sizePickle = pickle.createEmpty(); sizePickle.writeUInt32(headerBuf.length); const sizeBuf = sizePickle.toBuffer(); out.unshift(headerBuf); out.unshift(sizeBuf); } const contents = Buffer.concat(out); out.length = 0; this.queue(new VinylFile({ base: '.', path: destFilename, contents: contents })); this.queue(null); }; // Call finish() only when all file inserts have finished... if (pendingInserts === 0) { finish(); } else { onFileInserted = () => { pendingInserts--; if (pendingInserts === 0) { finish(); } }; } }); } ================================================ FILE: build/lib/builtInExtensions.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getExtensionStream = getExtensionStream; exports.getBuiltInExtensions = getBuiltInExtensions; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const os_1 = __importDefault(require("os")); const rimraf_1 = __importDefault(require("rimraf")); const event_stream_1 = __importDefault(require("event-stream")); const gulp_rename_1 = __importDefault(require("gulp-rename")); const vinyl_fs_1 = __importDefault(require("vinyl-fs")); const ext = __importStar(require("./extensions")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const productjson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions = productjson.builtInExtensions || []; const webBuiltInExtensions = productjson.webBuiltInExtensions || []; const controlFilePath = path_1.default.join(os_1.default.homedir(), '.vscode-oss-dev', 'extensions', 'control.json'); const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE']; function log(...messages) { if (ENABLE_LOGGING) { (0, fancy_log_1.default)(...messages); } } function getExtensionPath(extension) { return path_1.default.join(root, '.build', 'builtInExtensions', extension.name); } function isUpToDate(extension) { const packagePath = path_1.default.join(getExtensionPath(extension), 'package.json'); if (!fs_1.default.existsSync(packagePath)) { return false; } const packageContents = fs_1.default.readFileSync(packagePath, { encoding: 'utf8' }); try { const diskVersion = JSON.parse(packageContents).version; return (diskVersion === extension.version); } catch (err) { return false; } } function getExtensionDownloadStream(extension) { let input; if (extension.vsix) { input = ext.fromVsix(path_1.default.join(root, extension.vsix), extension); } else if (productjson.extensionsGallery?.serviceUrl) { input = ext.fromMarketplace(productjson.extensionsGallery.serviceUrl, extension); } else { input = ext.fromGithub(extension); } return input.pipe((0, gulp_rename_1.default)(p => p.dirname = `${extension.name}/${p.dirname}`)); } function getExtensionStream(extension) { // if the extension exists on disk, use those files instead of downloading anew if (isUpToDate(extension)) { log('[extensions]', `${extension.name}@${extension.version} up to date`, ansi_colors_1.default.green('✔︎')); return vinyl_fs_1.default.src(['**'], { cwd: getExtensionPath(extension), dot: true }) .pipe((0, gulp_rename_1.default)(p => p.dirname = `${extension.name}/${p.dirname}`)); } return getExtensionDownloadStream(extension); } function syncMarketplaceExtension(extension) { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansi_colors_1.default.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); if (isUpToDate(extension)) { log(source, `${extension.name}@${extension.version}`, ansi_colors_1.default.green('✔︎')); return event_stream_1.default.readArray([]); } rimraf_1.default.sync(getExtensionPath(extension)); return getExtensionDownloadStream(extension) .pipe(vinyl_fs_1.default.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansi_colors_1.default.green('✔︎'))); } function syncExtension(extension, controlState) { if (extension.platforms) { const platforms = new Set(extension.platforms); if (!platforms.has(process.platform)) { log(ansi_colors_1.default.gray('[skip]'), `${extension.name}@${extension.version}: Platform '${process.platform}' not supported: [${extension.platforms}]`, ansi_colors_1.default.green('✔︎')); return event_stream_1.default.readArray([]); } } switch (controlState) { case 'disabled': log(ansi_colors_1.default.blue('[disabled]'), ansi_colors_1.default.gray(extension.name)); return event_stream_1.default.readArray([]); case 'marketplace': return syncMarketplaceExtension(extension); default: if (!fs_1.default.existsSync(controlState)) { log(ansi_colors_1.default.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); return event_stream_1.default.readArray([]); } else if (!fs_1.default.existsSync(path_1.default.join(controlState, 'package.json'))) { log(ansi_colors_1.default.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); return event_stream_1.default.readArray([]); } log(ansi_colors_1.default.blue('[local]'), `${extension.name}: ${ansi_colors_1.default.cyan(controlState)}`, ansi_colors_1.default.green('✔︎')); return event_stream_1.default.readArray([]); } } function readControlFile() { try { return JSON.parse(fs_1.default.readFileSync(controlFilePath, 'utf8')); } catch (err) { return {}; } } function writeControlFile(control) { fs_1.default.mkdirSync(path_1.default.dirname(controlFilePath), { recursive: true }); fs_1.default.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } function getBuiltInExtensions() { log('Synchronizing built-in extensions...'); log(`You can manage built-in extensions with the ${ansi_colors_1.default.cyan('--builtin')} flag`); const control = readControlFile(); const streams = []; for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { const controlState = control[extension.name] || 'marketplace'; control[extension.name] = controlState; streams.push(syncExtension(extension, controlState)); } writeControlFile(control); return new Promise((resolve, reject) => { event_stream_1.default.merge(streams) .on('error', reject) .on('end', resolve); }); } if (require.main === module) { getBuiltInExtensions().then(() => process.exit(0)).catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=builtInExtensions.js.map ================================================ FILE: build/lib/builtInExtensions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import os from 'os'; import rimraf from 'rimraf'; import es from 'event-stream'; import rename from 'gulp-rename'; import vfs from 'vinyl-fs'; import * as ext from './extensions'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import { Stream } from 'stream'; export interface IExtensionDefinition { name: string; version: string; sha256: string; repo: string; platforms?: string[]; vsix?: string; metadata: { id: string; publisherId: { publisherId: string; publisherName: string; displayName: string; flags: string; }; publisherDisplayName: string; }; } const root = path.dirname(path.dirname(__dirname)); const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions = productjson.builtInExtensions || []; const webBuiltInExtensions = productjson.webBuiltInExtensions || []; const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json'); const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE']; function log(...messages: string[]): void { if (ENABLE_LOGGING) { fancyLog(...messages); } } function getExtensionPath(extension: IExtensionDefinition): string { return path.join(root, '.build', 'builtInExtensions', extension.name); } function isUpToDate(extension: IExtensionDefinition): boolean { const packagePath = path.join(getExtensionPath(extension), 'package.json'); if (!fs.existsSync(packagePath)) { return false; } const packageContents = fs.readFileSync(packagePath, { encoding: 'utf8' }); try { const diskVersion = JSON.parse(packageContents).version; return (diskVersion === extension.version); } catch (err) { return false; } } function getExtensionDownloadStream(extension: IExtensionDefinition) { let input: Stream; if (extension.vsix) { input = ext.fromVsix(path.join(root, extension.vsix), extension); } else if (productjson.extensionsGallery?.serviceUrl) { input = ext.fromMarketplace(productjson.extensionsGallery.serviceUrl, extension); } else { input = ext.fromGithub(extension); } return input.pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } export function getExtensionStream(extension: IExtensionDefinition) { // if the extension exists on disk, use those files instead of downloading anew if (isUpToDate(extension)) { log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } return getExtensionDownloadStream(extension); } function syncMarketplaceExtension(extension: IExtensionDefinition): Stream { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); if (isUpToDate(extension)) { log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); return es.readArray([]); } rimraf.sync(getExtensionPath(extension)); return getExtensionDownloadStream(extension) .pipe(vfs.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); } function syncExtension(extension: IExtensionDefinition, controlState: 'disabled' | 'marketplace'): Stream { if (extension.platforms) { const platforms = new Set(extension.platforms); if (!platforms.has(process.platform)) { log(ansiColors.gray('[skip]'), `${extension.name}@${extension.version}: Platform '${process.platform}' not supported: [${extension.platforms}]`, ansiColors.green('✔︎')); return es.readArray([]); } } switch (controlState) { case 'disabled': log(ansiColors.blue('[disabled]'), ansiColors.gray(extension.name)); return es.readArray([]); case 'marketplace': return syncMarketplaceExtension(extension); default: if (!fs.existsSync(controlState)) { log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); return es.readArray([]); } else if (!fs.existsSync(path.join(controlState, 'package.json'))) { log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); return es.readArray([]); } log(ansiColors.blue('[local]'), `${extension.name}: ${ansiColors.cyan(controlState)}`, ansiColors.green('✔︎')); return es.readArray([]); } } interface IControlFile { [name: string]: 'disabled' | 'marketplace'; } function readControlFile(): IControlFile { try { return JSON.parse(fs.readFileSync(controlFilePath, 'utf8')); } catch (err) { return {}; } } function writeControlFile(control: IControlFile): void { fs.mkdirSync(path.dirname(controlFilePath), { recursive: true }); fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } export function getBuiltInExtensions(): Promise { log('Synchronizing built-in extensions...'); log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`); const control = readControlFile(); const streams: Stream[] = []; for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { const controlState = control[extension.name] || 'marketplace'; control[extension.name] = controlState; streams.push(syncExtension(extension, controlState)); } writeControlFile(control); return new Promise((resolve, reject) => { es.merge(streams) .on('error', reject) .on('end', resolve); }); } if (require.main === module) { getBuiltInExtensions().then(() => process.exit(0)).catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/lib/builtInExtensionsCG.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const url_1 = __importDefault(require("url")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const rootCG = path_1.default.join(root, 'extensionsCG'); const productjson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions = productjson.builtInExtensions || []; const webBuiltInExtensions = productjson.webBuiltInExtensions || []; const token = process.env['GITHUB_TOKEN']; const contentBasePath = 'raw.githubusercontent.com'; const contentFileNames = ['package.json', 'package-lock.json']; async function downloadExtensionDetails(extension) { const extensionLabel = `${extension.name}@${extension.version}`; const repository = url_1.default.parse(extension.repo).path.substr(1); const repositoryContentBaseUrl = `https://${token ? `${token}@` : ''}${contentBasePath}/${repository}/v${extension.version}`; async function getContent(fileName) { try { const response = await fetch(`${repositoryContentBaseUrl}/${fileName}`); if (response.ok) { return { fileName, body: Buffer.from(await response.arrayBuffer()) }; } else if (response.status === 404) { return { fileName, body: undefined }; } else { return { fileName, body: null }; } } catch (e) { return { fileName, body: null }; } } const promises = contentFileNames.map(getContent); console.log(extensionLabel); const results = await Promise.all(promises); for (const result of results) { if (result.body) { const extensionFolder = path_1.default.join(rootCG, extension.name); fs_1.default.mkdirSync(extensionFolder, { recursive: true }); fs_1.default.writeFileSync(path_1.default.join(extensionFolder, result.fileName), result.body); console.log(` - ${result.fileName} ${ansi_colors_1.default.green('✔︎')}`); } else if (result.body === undefined) { console.log(` - ${result.fileName} ${ansi_colors_1.default.yellow('⚠️')}`); } else { console.log(` - ${result.fileName} ${ansi_colors_1.default.red('🛑')}`); } } // Validation if (!results.find(r => r.fileName === 'package.json')?.body) { // throw new Error(`The "package.json" file could not be found for the built-in extension - ${extensionLabel}`); } if (!results.find(r => r.fileName === 'package-lock.json')?.body) { // throw new Error(`The "package-lock.json" could not be found for the built-in extension - ${extensionLabel}`); } } async function main() { for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { await downloadExtensionDetails(extension); } } main().then(() => { console.log(`Built-in extensions component data downloaded ${ansi_colors_1.default.green('✔︎')}`); process.exit(0); }, err => { console.log(`Built-in extensions component data could not be downloaded ${ansi_colors_1.default.red('🛑')}`); console.error(err); process.exit(1); }); //# sourceMappingURL=builtInExtensionsCG.js.map ================================================ FILE: build/lib/builtInExtensionsCG.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import url from 'url'; import ansiColors from 'ansi-colors'; import { IExtensionDefinition } from './builtInExtensions'; const root = path.dirname(path.dirname(__dirname)); const rootCG = path.join(root, 'extensionsCG'); const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions = productjson.builtInExtensions || []; const webBuiltInExtensions = productjson.webBuiltInExtensions || []; const token = process.env['GITHUB_TOKEN']; const contentBasePath = 'raw.githubusercontent.com'; const contentFileNames = ['package.json', 'package-lock.json']; async function downloadExtensionDetails(extension: IExtensionDefinition): Promise { const extensionLabel = `${extension.name}@${extension.version}`; const repository = url.parse(extension.repo).path!.substr(1); const repositoryContentBaseUrl = `https://${token ? `${token}@` : ''}${contentBasePath}/${repository}/v${extension.version}`; async function getContent(fileName: string): Promise<{ fileName: string; body: Buffer | undefined | null }> { try { const response = await fetch(`${repositoryContentBaseUrl}/${fileName}`); if (response.ok) { return { fileName, body: Buffer.from(await response.arrayBuffer()) }; } else if (response.status === 404) { return { fileName, body: undefined }; } else { return { fileName, body: null }; } } catch (e) { return { fileName, body: null }; } } const promises = contentFileNames.map(getContent); console.log(extensionLabel); const results = await Promise.all(promises); for (const result of results) { if (result.body) { const extensionFolder = path.join(rootCG, extension.name); fs.mkdirSync(extensionFolder, { recursive: true }); fs.writeFileSync(path.join(extensionFolder, result.fileName), result.body); console.log(` - ${result.fileName} ${ansiColors.green('✔︎')}`); } else if (result.body === undefined) { console.log(` - ${result.fileName} ${ansiColors.yellow('⚠️')}`); } else { console.log(` - ${result.fileName} ${ansiColors.red('🛑')}`); } } // Validation if (!results.find(r => r.fileName === 'package.json')?.body) { // throw new Error(`The "package.json" file could not be found for the built-in extension - ${extensionLabel}`); } if (!results.find(r => r.fileName === 'package-lock.json')?.body) { // throw new Error(`The "package-lock.json" could not be found for the built-in extension - ${extensionLabel}`); } } async function main(): Promise { for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { await downloadExtensionDetails(extension); } } main().then(() => { console.log(`Built-in extensions component data downloaded ${ansiColors.green('✔︎')}`); process.exit(0); }, err => { console.log(`Built-in extensions component data could not be downloaded ${ansiColors.red('🛑')}`); console.error(err); process.exit(1); }); ================================================ FILE: build/lib/bundle.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.removeAllTSBoilerplate = removeAllTSBoilerplate; function removeAllTSBoilerplate(source) { const seen = new Array(BOILERPLATE.length).fill(true, 0, BOILERPLATE.length); return removeDuplicateTSBoilerplate(source, seen); } // Taken from typescript compiler => emitFiles const BOILERPLATE = [ { start: /^var __extends/, end: /^}\)\(\);$/ }, { start: /^var __assign/, end: /^};$/ }, { start: /^var __decorate/, end: /^};$/ }, { start: /^var __metadata/, end: /^};$/ }, { start: /^var __param/, end: /^};$/ }, { start: /^var __awaiter/, end: /^};$/ }, { start: /^var __generator/, end: /^};$/ }, { start: /^var __createBinding/, end: /^}\)\);$/ }, { start: /^var __setModuleDefault/, end: /^}\);$/ }, { start: /^var __importStar/, end: /^};$/ }, { start: /^var __addDisposableResource/, end: /^};$/ }, { start: /^var __disposeResources/, end: /^}\);$/ }, ]; function removeDuplicateTSBoilerplate(source, SEEN_BOILERPLATE = []) { const lines = source.split(/\r\n|\n|\r/); const newLines = []; let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (IS_REMOVING_BOILERPLATE) { newLines.push(''); if (END_BOILERPLATE.test(line)) { IS_REMOVING_BOILERPLATE = false; } } else { for (let j = 0; j < BOILERPLATE.length; j++) { const boilerplate = BOILERPLATE[j]; if (boilerplate.start.test(line)) { if (SEEN_BOILERPLATE[j]) { IS_REMOVING_BOILERPLATE = true; END_BOILERPLATE = boilerplate.end; } else { SEEN_BOILERPLATE[j] = true; } } } if (IS_REMOVING_BOILERPLATE) { newLines.push(''); } else { newLines.push(line); } } } return newLines.join('\n'); } //# sourceMappingURL=bundle.js.map ================================================ FILE: build/lib/bundle.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export interface IEntryPoint { name: string; include?: string[]; dest?: string; } export function removeAllTSBoilerplate(source: string) { const seen = new Array(BOILERPLATE.length).fill(true, 0, BOILERPLATE.length); return removeDuplicateTSBoilerplate(source, seen); } // Taken from typescript compiler => emitFiles const BOILERPLATE = [ { start: /^var __extends/, end: /^}\)\(\);$/ }, { start: /^var __assign/, end: /^};$/ }, { start: /^var __decorate/, end: /^};$/ }, { start: /^var __metadata/, end: /^};$/ }, { start: /^var __param/, end: /^};$/ }, { start: /^var __awaiter/, end: /^};$/ }, { start: /^var __generator/, end: /^};$/ }, { start: /^var __createBinding/, end: /^}\)\);$/ }, { start: /^var __setModuleDefault/, end: /^}\);$/ }, { start: /^var __importStar/, end: /^};$/ }, { start: /^var __addDisposableResource/, end: /^};$/ }, { start: /^var __disposeResources/, end: /^}\);$/ }, ]; function removeDuplicateTSBoilerplate(source: string, SEEN_BOILERPLATE: boolean[] = []): string { const lines = source.split(/\r\n|\n|\r/); const newLines: string[] = []; let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE: RegExp; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (IS_REMOVING_BOILERPLATE) { newLines.push(''); if (END_BOILERPLATE!.test(line)) { IS_REMOVING_BOILERPLATE = false; } } else { for (let j = 0; j < BOILERPLATE.length; j++) { const boilerplate = BOILERPLATE[j]; if (boilerplate.start.test(line)) { if (SEEN_BOILERPLATE[j]) { IS_REMOVING_BOILERPLATE = true; END_BOILERPLATE = boilerplate.end; } else { SEEN_BOILERPLATE[j] = true; } } } if (IS_REMOVING_BOILERPLATE) { newLines.push(''); } else { newLines.push(line); } } } return newLines.join('\n'); } ================================================ FILE: build/lib/compilation.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.watchApiProposalNamesTask = exports.compileApiProposalNamesTask = void 0; exports.createCompile = createCompile; exports.transpileTask = transpileTask; exports.compileTask = compileTask; exports.watchTask = watchTask; const event_stream_1 = __importDefault(require("event-stream")); const fs_1 = __importDefault(require("fs")); const gulp_1 = __importDefault(require("gulp")); const path_1 = __importDefault(require("path")); const monacodts = __importStar(require("./monaco-api")); const nls = __importStar(require("./nls")); const reporter_1 = require("./reporter"); const util = __importStar(require("./util")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const os_1 = __importDefault(require("os")); const vinyl_1 = __importDefault(require("vinyl")); const task = __importStar(require("./task")); const index_1 = require("./mangle/index"); const postcss_1 = require("./postcss"); const ts = require("typescript"); const watch = require('./watch'); // --- gulp-tsb: compile and transpile -------------------------------- const reporter = (0, reporter_1.createReporter)(); function getTypeScriptCompilerOptions(src) { const rootDir = path_1.default.join(__dirname, `../../${src}`); const options = {}; options.verbose = false; options.sourceMap = true; if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry options.sourceMap = false; } options.rootDir = rootDir; options.baseUrl = rootDir; options.sourceRoot = util.toFileUri(rootDir); options.newLine = /\r\n/.test(fs_1.default.readFileSync(__filename, 'utf8')) ? 0 : 1; return options; } function createCompile(src, { build, emitError, transpileOnly, preserveEnglish }) { const tsb = require('./tsb'); const sourcemaps = require('gulp-sourcemaps'); const projectPath = path_1.default.join(__dirname, '../../', src, 'tsconfig.json'); const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) }; if (!build) { overrideOptions.inlineSourceMap = true; } const compilation = tsb.create(projectPath, overrideOptions, { verbose: false, transpileOnly: Boolean(transpileOnly), transpileWithSwc: typeof transpileOnly !== 'boolean' && transpileOnly.esbuild }, err => reporter(err)); function pipeline(token) { const bom = require('gulp-bom'); const tsFilter = util.filter(data => /\.ts$/.test(data.path)); const isUtf8Test = (f) => /(\/|\\)test(\/|\\).*utf8/.test(f.path); const isRuntimeJs = (f) => f.path.endsWith('.js') && !f.path.includes('fixtures'); const isCSS = (f) => f.path.endsWith('.css') && !f.path.includes('fixtures'); const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path))); const postcssNesting = require('postcss-nesting'); const input = event_stream_1.default.through(); const output = input .pipe(util.$if(isUtf8Test, bom())) // this is required to preserve BOM in test files that loose it otherwise .pipe(util.$if(!build && isRuntimeJs, util.appendOwnPathSourceURL())) .pipe(util.$if(isCSS, (0, postcss_1.gulpPostcss)([postcssNesting()], err => reporter(String(err))))) .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation(token)) .pipe(noDeclarationsFilter) .pipe(util.$if(build, nls.nls({ preserveEnglish }))) .pipe(noDeclarationsFilter.restore) .pipe(util.$if(!transpileOnly, sourcemaps.write('.', { addComment: false, includeContent: !!build, sourceRoot: overrideOptions.sourceRoot }))) .pipe(tsFilter.restore) .pipe(reporter.end(!!emitError)); return event_stream_1.default.duplex(input, output); } pipeline.tsProjectSrc = () => { return compilation.src({ base: src }); }; pipeline.projectPath = projectPath; return pipeline; } function transpileTask(src, out, esbuild) { const task = () => { const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild }, preserveEnglish: false }); const srcPipe = gulp_1.default.src(`${src}/**`, { base: `${src}` }); return srcPipe .pipe(transpile()) .pipe(gulp_1.default.dest(out)); }; task.taskName = `transpile-${path_1.default.basename(src)}`; return task; } function compileTask(src, out, build, options = {}) { const task = () => { if (os_1.default.totalmem() < 4_000_000_000) { throw new Error('compilation requires 4GB of RAM'); } const compile = createCompile(src, { build, emitError: true, transpileOnly: false, preserveEnglish: !!options.preserveEnglish }); const srcPipe = gulp_1.default.src(`${src}/**`, { base: `${src}` }); const generator = new MonacoGenerator(false); if (src === 'src') { generator.execute(); } // mangle: TypeScript to TypeScript let mangleStream = event_stream_1.default.through(); if (build && !options.disableMangle) { let ts2tsMangler = new index_1.Mangler(compile.projectPath, (...data) => (0, fancy_log_1.default)(ansi_colors_1.default.blue('[mangler]'), ...data), { mangleExports: true, manglePrivateFields: true }); const newContentsByFileName = ts2tsMangler.computeNewFileContents(new Set(['saveState'])); mangleStream = event_stream_1.default.through(async function write(data) { const tsNormalPath = ts.normalizePath(data.path); const newContents = (await newContentsByFileName).get(tsNormalPath); if (newContents !== undefined) { data.contents = Buffer.from(newContents.out); data.sourceMap = newContents.sourceMap && JSON.parse(newContents.sourceMap); } this.push(data); }, async function end() { // free resources (await newContentsByFileName).clear(); this.push(null); ts2tsMangler = undefined; }); } return srcPipe .pipe(mangleStream) .pipe(generator.stream) .pipe(compile()) .pipe(gulp_1.default.dest(out)); }; task.taskName = `compile-${path_1.default.basename(src)}`; return task; } function watchTask(out, build, srcPath = 'src') { const task = () => { const compile = createCompile(srcPath, { build, emitError: false, transpileOnly: false, preserveEnglish: false }); const src = gulp_1.default.src(`${srcPath}/**`, { base: srcPath }); const watchSrc = watch(`${srcPath}/**`, { base: srcPath, readDelay: 200 }); const generator = new MonacoGenerator(true); generator.execute(); return watchSrc .pipe(generator.stream) .pipe(util.incremental(compile, src, true)) .pipe(gulp_1.default.dest(out)); }; task.taskName = `watch-${path_1.default.basename(out)}`; return task; } const REPO_SRC_FOLDER = path_1.default.join(__dirname, '../../src'); class MonacoGenerator { _isWatch; stream; _watchedFiles; _fsProvider; _declarationResolver; constructor(isWatch) { this._isWatch = isWatch; this.stream = event_stream_1.default.through(); this._watchedFiles = {}; const onWillReadFile = (moduleId, filePath) => { if (!this._isWatch) { return; } if (this._watchedFiles[filePath]) { return; } this._watchedFiles[filePath] = true; fs_1.default.watchFile(filePath, () => { this._declarationResolver.invalidateCache(moduleId); this._executeSoon(); }); }; this._fsProvider = new class extends monacodts.FSProvider { readFileSync(moduleId, filePath) { onWillReadFile(moduleId, filePath); return super.readFileSync(moduleId, filePath); } }; this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider); if (this._isWatch) { fs_1.default.watchFile(monacodts.RECIPE_PATH, () => { this._executeSoon(); }); } } _executeSoonTimer = null; _executeSoon() { if (this._executeSoonTimer !== null) { clearTimeout(this._executeSoonTimer); this._executeSoonTimer = null; } this._executeSoonTimer = setTimeout(() => { this._executeSoonTimer = null; this.execute(); }, 20); } _run() { const r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { // The build must always be able to generate the monaco.d.ts throw new Error(`monaco.d.ts generation error - Cannot continue`); } return r; } _log(message, ...rest) { (0, fancy_log_1.default)(ansi_colors_1.default.cyan('[monaco.d.ts]'), message, ...rest); } execute() { const startTime = Date.now(); const result = this._run(); if (!result) { // nothing really changed return; } if (result.isTheSame) { return; } fs_1.default.writeFileSync(result.filePath, result.content); fs_1.default.writeFileSync(path_1.default.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums); this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`); if (!this._isWatch) { this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.'); } } } function generateApiProposalNames() { let eol; try { const src = fs_1.default.readFileSync('src/vs/platform/extensions/common/extensionsApiProposals.ts', 'utf-8'); const match = /\r?\n/m.exec(src); eol = match ? match[0] : os_1.default.EOL; } catch { eol = os_1.default.EOL; } const pattern = /vscode\.proposed\.([a-zA-Z\d]+)\.d\.ts$/; const versionPattern = /^\s*\/\/\s*version\s*:\s*(\d+)\s*$/mi; const proposals = new Map(); const input = event_stream_1.default.through(); const output = input .pipe(util.filter((f) => pattern.test(f.path))) .pipe(event_stream_1.default.through((f) => { const name = path_1.default.basename(f.path); const match = pattern.exec(name); if (!match) { return; } const proposalName = match[1]; const contents = f.contents.toString('utf8'); const versionMatch = versionPattern.exec(contents); const version = versionMatch ? versionMatch[1] : undefined; proposals.set(proposalName, { proposal: `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.${proposalName}.d.ts`, version: version ? parseInt(version) : undefined }); }, function () { const names = [...proposals.keys()].sort(); const contents = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', '', '// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.', '', 'const _allApiProposals = {', `${names.map(proposalName => { const proposal = proposals.get(proposalName); return `\t${proposalName}: {${eol}\t\tproposal: '${proposal.proposal}',${eol}${proposal.version ? `\t\tversion: ${proposal.version}${eol}` : ''}\t}`; }).join(`,${eol}`)}`, '};', 'export const allApiProposals = Object.freeze<{ [proposalName: string]: Readonly<{ proposal: string; version?: number }> }>(_allApiProposals);', 'export type ApiProposalName = keyof typeof _allApiProposals;', '', ].join(eol); this.emit('data', new vinyl_1.default({ path: 'vs/platform/extensions/common/extensionsApiProposals.ts', contents: Buffer.from(contents) })); this.emit('end'); })); return event_stream_1.default.duplex(input, output); } const apiProposalNamesReporter = (0, reporter_1.createReporter)('api-proposal-names'); exports.compileApiProposalNamesTask = task.define('compile-api-proposal-names', () => { return gulp_1.default.src('src/vscode-dts/**') .pipe(generateApiProposalNames()) .pipe(gulp_1.default.dest('src')) .pipe(apiProposalNamesReporter.end(true)); }); exports.watchApiProposalNamesTask = task.define('watch-api-proposal-names', () => { const task = () => gulp_1.default.src('src/vscode-dts/**') .pipe(generateApiProposalNames()) .pipe(apiProposalNamesReporter.end(true)); return watch('src/vscode-dts/**', { readDelay: 200 }) .pipe(util.debounce(task)) .pipe(gulp_1.default.dest('src')); }); //# sourceMappingURL=compilation.js.map ================================================ FILE: build/lib/compilation.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import fs from 'fs'; import gulp from 'gulp'; import path from 'path'; import * as monacodts from './monaco-api'; import * as nls from './nls'; import { createReporter } from './reporter'; import * as util from './util'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import os from 'os'; import File from 'vinyl'; import * as task from './task'; import { Mangler } from './mangle/index'; import { RawSourceMap } from 'source-map'; import { gulpPostcss } from './postcss'; import ts = require('typescript'); const watch = require('./watch'); // --- gulp-tsb: compile and transpile -------------------------------- const reporter = createReporter(); function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions { const rootDir = path.join(__dirname, `../../${src}`); const options: ts.CompilerOptions = {}; options.verbose = false; options.sourceMap = true; if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry options.sourceMap = false; } options.rootDir = rootDir; options.baseUrl = rootDir; options.sourceRoot = util.toFileUri(rootDir); options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1; return options; } interface ICompileTaskOptions { readonly build: boolean; readonly emitError: boolean; readonly transpileOnly: boolean | { esbuild: boolean }; readonly preserveEnglish: boolean; } export function createCompile(src: string, { build, emitError, transpileOnly, preserveEnglish }: ICompileTaskOptions) { const tsb = require('./tsb') as typeof import('./tsb'); const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps'); const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json'); const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) }; if (!build) { overrideOptions.inlineSourceMap = true; } const compilation = tsb.create(projectPath, overrideOptions, { verbose: false, transpileOnly: Boolean(transpileOnly), transpileWithSwc: typeof transpileOnly !== 'boolean' && transpileOnly.esbuild }, err => reporter(err)); function pipeline(token?: util.ICancellationToken) { const bom = require('gulp-bom') as typeof import('gulp-bom'); const tsFilter = util.filter(data => /\.ts$/.test(data.path)); const isUtf8Test = (f: File) => /(\/|\\)test(\/|\\).*utf8/.test(f.path); const isRuntimeJs = (f: File) => f.path.endsWith('.js') && !f.path.includes('fixtures'); const isCSS = (f: File) => f.path.endsWith('.css') && !f.path.includes('fixtures'); const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path))); const postcssNesting = require('postcss-nesting'); const input = es.through(); const output = input .pipe(util.$if(isUtf8Test, bom())) // this is required to preserve BOM in test files that loose it otherwise .pipe(util.$if(!build && isRuntimeJs, util.appendOwnPathSourceURL())) .pipe(util.$if(isCSS, gulpPostcss([postcssNesting()], err => reporter(String(err))))) .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation(token)) .pipe(noDeclarationsFilter) .pipe(util.$if(build, nls.nls({ preserveEnglish }))) .pipe(noDeclarationsFilter.restore) .pipe(util.$if(!transpileOnly, sourcemaps.write('.', { addComment: false, includeContent: !!build, sourceRoot: overrideOptions.sourceRoot }))) .pipe(tsFilter.restore) .pipe(reporter.end(!!emitError)); return es.duplex(input, output); } pipeline.tsProjectSrc = () => { return compilation.src({ base: src }); }; pipeline.projectPath = projectPath; return pipeline; } export function transpileTask(src: string, out: string, esbuild: boolean): task.StreamTask { const task = () => { const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild }, preserveEnglish: false }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); return srcPipe .pipe(transpile()) .pipe(gulp.dest(out)); }; task.taskName = `transpile-${path.basename(src)}`; return task; } export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean; preserveEnglish?: boolean } = {}): task.StreamTask { const task = () => { if (os.totalmem() < 4_000_000_000) { throw new Error('compilation requires 4GB of RAM'); } const compile = createCompile(src, { build, emitError: true, transpileOnly: false, preserveEnglish: !!options.preserveEnglish }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); const generator = new MonacoGenerator(false); if (src === 'src') { generator.execute(); } // mangle: TypeScript to TypeScript let mangleStream = es.through(); if (build && !options.disableMangle) { let ts2tsMangler = new Mangler(compile.projectPath, (...data) => fancyLog(ansiColors.blue('[mangler]'), ...data), { mangleExports: true, manglePrivateFields: true }); const newContentsByFileName = ts2tsMangler.computeNewFileContents(new Set(['saveState'])); mangleStream = es.through(async function write(data: File & { sourceMap?: RawSourceMap }) { type TypeScriptExt = typeof ts & { normalizePath(path: string): string }; const tsNormalPath = (ts).normalizePath(data.path); const newContents = (await newContentsByFileName).get(tsNormalPath); if (newContents !== undefined) { data.contents = Buffer.from(newContents.out); data.sourceMap = newContents.sourceMap && JSON.parse(newContents.sourceMap); } this.push(data); }, async function end() { // free resources (await newContentsByFileName).clear(); this.push(null); (ts2tsMangler) = undefined; }); } return srcPipe .pipe(mangleStream) .pipe(generator.stream) .pipe(compile()) .pipe(gulp.dest(out)); }; task.taskName = `compile-${path.basename(src)}`; return task; } export function watchTask(out: string, build: boolean, srcPath: string = 'src'): task.StreamTask { const task = () => { const compile = createCompile(srcPath, { build, emitError: false, transpileOnly: false, preserveEnglish: false }); const src = gulp.src(`${srcPath}/**`, { base: srcPath }); const watchSrc = watch(`${srcPath}/**`, { base: srcPath, readDelay: 200 }); const generator = new MonacoGenerator(true); generator.execute(); return watchSrc .pipe(generator.stream) .pipe(util.incremental(compile, src, true)) .pipe(gulp.dest(out)); }; task.taskName = `watch-${path.basename(out)}`; return task; } const REPO_SRC_FOLDER = path.join(__dirname, '../../src'); class MonacoGenerator { private readonly _isWatch: boolean; public readonly stream: NodeJS.ReadWriteStream; private readonly _watchedFiles: { [filePath: string]: boolean }; private readonly _fsProvider: monacodts.FSProvider; private readonly _declarationResolver: monacodts.DeclarationResolver; constructor(isWatch: boolean) { this._isWatch = isWatch; this.stream = es.through(); this._watchedFiles = {}; const onWillReadFile = (moduleId: string, filePath: string) => { if (!this._isWatch) { return; } if (this._watchedFiles[filePath]) { return; } this._watchedFiles[filePath] = true; fs.watchFile(filePath, () => { this._declarationResolver.invalidateCache(moduleId); this._executeSoon(); }); }; this._fsProvider = new class extends monacodts.FSProvider { public readFileSync(moduleId: string, filePath: string): Buffer { onWillReadFile(moduleId, filePath); return super.readFileSync(moduleId, filePath); } }; this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider); if (this._isWatch) { fs.watchFile(monacodts.RECIPE_PATH, () => { this._executeSoon(); }); } } private _executeSoonTimer: NodeJS.Timeout | null = null; private _executeSoon(): void { if (this._executeSoonTimer !== null) { clearTimeout(this._executeSoonTimer); this._executeSoonTimer = null; } this._executeSoonTimer = setTimeout(() => { this._executeSoonTimer = null; this.execute(); }, 20); } private _run(): monacodts.IMonacoDeclarationResult | null { const r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { // The build must always be able to generate the monaco.d.ts throw new Error(`monaco.d.ts generation error - Cannot continue`); } return r; } private _log(message: any, ...rest: any[]): void { fancyLog(ansiColors.cyan('[monaco.d.ts]'), message, ...rest); } public execute(): void { const startTime = Date.now(); const result = this._run(); if (!result) { // nothing really changed return; } if (result.isTheSame) { return; } fs.writeFileSync(result.filePath, result.content); fs.writeFileSync(path.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums); this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`); if (!this._isWatch) { this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.'); } } } function generateApiProposalNames() { let eol: string; try { const src = fs.readFileSync('src/vs/platform/extensions/common/extensionsApiProposals.ts', 'utf-8'); const match = /\r?\n/m.exec(src); eol = match ? match[0] : os.EOL; } catch { eol = os.EOL; } const pattern = /vscode\.proposed\.([a-zA-Z\d]+)\.d\.ts$/; const versionPattern = /^\s*\/\/\s*version\s*:\s*(\d+)\s*$/mi; const proposals = new Map(); const input = es.through(); const output = input .pipe(util.filter((f: File) => pattern.test(f.path))) .pipe(es.through((f: File) => { const name = path.basename(f.path); const match = pattern.exec(name); if (!match) { return; } const proposalName = match[1]; const contents = f.contents.toString('utf8'); const versionMatch = versionPattern.exec(contents); const version = versionMatch ? versionMatch[1] : undefined; proposals.set(proposalName, { proposal: `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.${proposalName}.d.ts`, version: version ? parseInt(version) : undefined }); }, function () { const names = [...proposals.keys()].sort(); const contents = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', '', '// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.', '', 'const _allApiProposals = {', `${names.map(proposalName => { const proposal = proposals.get(proposalName)!; return `\t${proposalName}: {${eol}\t\tproposal: '${proposal.proposal}',${eol}${proposal.version ? `\t\tversion: ${proposal.version}${eol}` : ''}\t}`; }).join(`,${eol}`)}`, '};', 'export const allApiProposals = Object.freeze<{ [proposalName: string]: Readonly<{ proposal: string; version?: number }> }>(_allApiProposals);', 'export type ApiProposalName = keyof typeof _allApiProposals;', '', ].join(eol); this.emit('data', new File({ path: 'vs/platform/extensions/common/extensionsApiProposals.ts', contents: Buffer.from(contents) })); this.emit('end'); })); return es.duplex(input, output); } const apiProposalNamesReporter = createReporter('api-proposal-names'); export const compileApiProposalNamesTask = task.define('compile-api-proposal-names', () => { return gulp.src('src/vscode-dts/**') .pipe(generateApiProposalNames()) .pipe(gulp.dest('src')) .pipe(apiProposalNamesReporter.end(true)); }); export const watchApiProposalNamesTask = task.define('watch-api-proposal-names', () => { const task = () => gulp.src('src/vscode-dts/**') .pipe(generateApiProposalNames()) .pipe(apiProposalNamesReporter.end(true)); return watch('src/vscode-dts/**', { readDelay: 200 }) .pipe(util.debounce(task)) .pipe(gulp.dest('src')); }); ================================================ FILE: build/lib/date.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.writeISODate = writeISODate; exports.readISODate = readISODate; const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const root = path_1.default.join(__dirname, '..', '..'); /** * Writes a `outDir/date` file with the contents of the build * so that other tasks during the build process can use it and * all use the same date. */ function writeISODate(outDir) { const result = () => new Promise((resolve, _) => { const outDirectory = path_1.default.join(root, outDir); fs_1.default.mkdirSync(outDirectory, { recursive: true }); const date = new Date().toISOString(); fs_1.default.writeFileSync(path_1.default.join(outDirectory, 'date'), date, 'utf8'); resolve(); }); result.taskName = 'build-date-file'; return result; } function readISODate(outDir) { const outDirectory = path_1.default.join(root, outDir); return fs_1.default.readFileSync(path_1.default.join(outDirectory, 'date'), 'utf8'); } //# sourceMappingURL=date.js.map ================================================ FILE: build/lib/date.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import fs from 'fs'; const root = path.join(__dirname, '..', '..'); /** * Writes a `outDir/date` file with the contents of the build * so that other tasks during the build process can use it and * all use the same date. */ export function writeISODate(outDir: string) { const result = () => new Promise((resolve, _) => { const outDirectory = path.join(root, outDir); fs.mkdirSync(outDirectory, { recursive: true }); const date = new Date().toISOString(); fs.writeFileSync(path.join(outDirectory, 'date'), date, 'utf8'); resolve(); }); result.taskName = 'build-date-file'; return result; } export function readISODate(outDir: string): string { const outDirectory = path.join(root, outDir); return fs.readFileSync(path.join(outDirectory, 'date'), 'utf8'); } ================================================ FILE: build/lib/dependencies.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getProductionDependencies = getProductionDependencies; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const child_process_1 = __importDefault(require("child_process")); const root = fs_1.default.realpathSync(path_1.default.dirname(path_1.default.dirname(__dirname))); function getNpmProductionDependencies(folder) { let raw; try { raw = child_process_1.default.execSync('npm ls --all --omit=dev --parseable', { cwd: folder, encoding: 'utf8', env: { ...process.env, NODE_ENV: 'production' }, stdio: [null, null, null] }); } catch (err) { const regex = /^npm ERR! .*$/gm; let match; while (match = regex.exec(err.message)) { if (/ELSPROBLEMS/.test(match[0])) { continue; } else if (/invalid: xterm/.test(match[0])) { continue; } else if (/A complete log of this run/.test(match[0])) { continue; } else { throw err; } } raw = err.stdout; } return raw.split(/\r?\n/).filter(line => { return !!line.trim() && path_1.default.relative(root, line) !== path_1.default.relative(root, folder); }); } function getProductionDependencies(folderPath) { const result = getNpmProductionDependencies(folderPath); // Account for distro npm dependencies const realFolderPath = fs_1.default.realpathSync(folderPath); const relativeFolderPath = path_1.default.relative(root, realFolderPath); const distroFolderPath = `${root}/.build/distro/npm/${relativeFolderPath}`; if (fs_1.default.existsSync(distroFolderPath)) { result.push(...getNpmProductionDependencies(distroFolderPath)); } return [...new Set(result)]; } if (require.main === module) { console.log(JSON.stringify(getProductionDependencies(root), null, ' ')); } //# sourceMappingURL=dependencies.js.map ================================================ FILE: build/lib/dependencies.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import cp from 'child_process'; const root = fs.realpathSync(path.dirname(path.dirname(__dirname))); function getNpmProductionDependencies(folder: string): string[] { let raw: string; try { raw = cp.execSync('npm ls --all --omit=dev --parseable', { cwd: folder, encoding: 'utf8', env: { ...process.env, NODE_ENV: 'production' }, stdio: [null, null, null] }); } catch (err) { const regex = /^npm ERR! .*$/gm; let match: RegExpExecArray | null; while (match = regex.exec(err.message)) { if (/ELSPROBLEMS/.test(match[0])) { continue; } else if (/invalid: xterm/.test(match[0])) { continue; } else if (/A complete log of this run/.test(match[0])) { continue; } else { throw err; } } raw = err.stdout; } return raw.split(/\r?\n/).filter(line => { return !!line.trim() && path.relative(root, line) !== path.relative(root, folder); }); } export function getProductionDependencies(folderPath: string): string[] { const result = getNpmProductionDependencies(folderPath); // Account for distro npm dependencies const realFolderPath = fs.realpathSync(folderPath); const relativeFolderPath = path.relative(root, realFolderPath); const distroFolderPath = `${root}/.build/distro/npm/${relativeFolderPath}`; if (fs.existsSync(distroFolderPath)) { result.push(...getNpmProductionDependencies(distroFolderPath)); } return [...new Set(result)]; } if (require.main === module) { console.log(JSON.stringify(getProductionDependencies(root), null, ' ')); } ================================================ FILE: build/lib/electron.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.config = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const vinyl_fs_1 = __importDefault(require("vinyl-fs")); const gulp_filter_1 = __importDefault(require("gulp-filter")); const util = __importStar(require("./util")); const getVersion_1 = require("./getVersion"); function isDocumentSuffix(str) { return str === 'document' || str === 'script' || str === 'file' || str === 'source code'; } const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const product = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'product.json'), 'utf8')); const commit = (0, getVersion_1.getVersion)(root); function createTemplate(input) { return (params) => { return input.replace(/<%=\s*([^\s]+)\s*%>/g, (match, key) => { return params[key] || match; }); }; } const darwinCreditsTemplate = product.darwinCredits && createTemplate(fs_1.default.readFileSync(path_1.default.join(root, product.darwinCredits), 'utf8')); /** * Generate a `DarwinDocumentType` given a list of file extensions, an icon name, and an optional suffix or file type name. * @param extensions A list of file extensions, such as `['bat', 'cmd']` * @param icon A sentence-cased file type name that matches the lowercase name of a darwin icon resource. * For example, `'HTML'` instead of `'html'`, or `'Java'` instead of `'java'`. * This parameter is lowercased before it is used to reference an icon file. * @param nameOrSuffix An optional suffix or a string to use as the file type. If a suffix is provided, * it is used with the icon parameter to generate a file type string. If nothing is provided, * `'document'` is used with the icon parameter to generate file type string. * * For example, if you call `darwinBundleDocumentType(..., 'HTML')`, the resulting file type is `"HTML document"`, * and the `'html'` darwin icon is used. * * If you call `darwinBundleDocumentType(..., 'Javascript', 'file')`, the resulting file type is `"Javascript file"`. * and the `'javascript'` darwin icon is used. * * If you call `darwinBundleDocumentType(..., 'bat', 'Windows command script')`, the file type is `"Windows command script"`, * and the `'bat'` darwin icon is used. */ function darwinBundleDocumentType(extensions, icon, nameOrSuffix, utis) { // If given a suffix, generate a name from it. If not given anything, default to 'document' if (isDocumentSuffix(nameOrSuffix) || !nameOrSuffix) { nameOrSuffix = icon.charAt(0).toUpperCase() + icon.slice(1) + ' ' + (nameOrSuffix ?? 'document'); } return { name: nameOrSuffix, role: 'Editor', ostypes: ['TEXT', 'utxt', 'TUTX', '****'], extensions, iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', utis }; } /** * Generate several `DarwinDocumentType`s with unique names and a shared icon. * @param types A map of file type names to their associated file extensions. * @param icon A darwin icon resource to use. For example, `'HTML'` would refer to `resources/darwin/html.icns` * * Examples: * ``` * darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' },'c') * darwinBundleDocumentTypes({ 'React source code': ['jsx', 'tsx'] }, 'react') * ``` */ function darwinBundleDocumentTypes(types, icon) { return Object.keys(types).map((name) => { const extensions = types[name]; return { name, role: 'Editor', ostypes: ['TEXT', 'utxt', 'TUTX', '****'], extensions: Array.isArray(extensions) ? extensions : [extensions], iconFile: 'resources/darwin/' + icon + '.icns' }; }); } const { electronVersion, msBuildId } = util.getElectronVersion(); exports.config = { version: electronVersion, tag: product.electronRepository ? `v${electronVersion}-${msBuildId}` : undefined, productAppName: product.nameLong, companyName: 'Microsoft Corporation', copyright: 'Copyright (C) 2024 Microsoft. All rights reserved', darwinIcon: 'resources/darwin/code.icns', darwinBundleIdentifier: product.darwinBundleIdentifier, darwinApplicationCategoryType: 'public.app-category.developer-tools', darwinHelpBookFolder: 'VS Code HelpBook', darwinHelpBookName: 'VS Code HelpBook', darwinBundleDocumentTypes: [ ...darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' }, 'c'), ...darwinBundleDocumentTypes({ 'Git configuration file': ['gitattributes', 'gitconfig', 'gitignore'] }, 'config'), ...darwinBundleDocumentTypes({ 'HTML template document': ['asp', 'aspx', 'cshtml', 'jshtm', 'jsp', 'phtml', 'shtml'] }, 'html'), darwinBundleDocumentType(['bat', 'cmd'], 'bat', 'Windows command script'), darwinBundleDocumentType(['bowerrc'], 'Bower'), darwinBundleDocumentType(['config', 'editorconfig', 'ini', 'cfg'], 'config', 'Configuration file'), darwinBundleDocumentType(['hh', 'hpp', 'hxx', 'h++'], 'cpp', 'C++ header file'), darwinBundleDocumentType(['cc', 'cpp', 'cxx', 'c++'], 'cpp', 'C++ source code'), darwinBundleDocumentType(['m'], 'default', 'Objective-C source code'), darwinBundleDocumentType(['mm'], 'cpp', 'Objective-C++ source code'), darwinBundleDocumentType(['cs', 'csx'], 'csharp', 'C# source code'), darwinBundleDocumentType(['css'], 'css', 'CSS'), darwinBundleDocumentType(['go'], 'go', 'Go source code'), darwinBundleDocumentType(['htm', 'html', 'xhtml'], 'HTML'), darwinBundleDocumentType(['jade'], 'Jade'), darwinBundleDocumentType(['jav', 'java'], 'Java'), darwinBundleDocumentType(['js', 'jscsrc', 'jshintrc', 'mjs', 'cjs'], 'Javascript', 'file'), darwinBundleDocumentType(['json'], 'JSON'), darwinBundleDocumentType(['less'], 'Less'), darwinBundleDocumentType(['markdown', 'md', 'mdoc', 'mdown', 'mdtext', 'mdtxt', 'mdwn', 'mkd', 'mkdn'], 'Markdown'), darwinBundleDocumentType(['php'], 'PHP', 'source code'), darwinBundleDocumentType(['ps1', 'psd1', 'psm1'], 'Powershell', 'script'), darwinBundleDocumentType(['py', 'pyi'], 'Python', 'script'), darwinBundleDocumentType(['gemspec', 'rb', 'erb'], 'Ruby', 'source code'), darwinBundleDocumentType(['scss', 'sass'], 'SASS', 'file'), darwinBundleDocumentType(['sql'], 'SQL', 'script'), darwinBundleDocumentType(['ts'], 'TypeScript', 'file'), darwinBundleDocumentType(['tsx', 'jsx'], 'React', 'source code'), darwinBundleDocumentType(['vue'], 'Vue', 'source code'), darwinBundleDocumentType(['ascx', 'csproj', 'dtd', 'plist', 'wxi', 'wxl', 'wxs', 'xml', 'xaml'], 'XML'), darwinBundleDocumentType(['eyaml', 'eyml', 'yaml', 'yml'], 'YAML'), darwinBundleDocumentType([ 'bash', 'bash_login', 'bash_logout', 'bash_profile', 'bashrc', 'profile', 'rhistory', 'rprofile', 'sh', 'zlogin', 'zlogout', 'zprofile', 'zsh', 'zshenv', 'zshrc' ], 'Shell', 'script'), // Default icon with specified names ...darwinBundleDocumentTypes({ 'Clojure source code': ['clj', 'cljs', 'cljx', 'clojure'], 'VS Code workspace file': 'code-workspace', 'CoffeeScript source code': 'coffee', 'Comma Separated Values': 'csv', 'CMake script': 'cmake', 'Dart script': 'dart', 'Diff file': 'diff', 'Dockerfile': 'dockerfile', 'Gradle file': 'gradle', 'Groovy script': 'groovy', 'Makefile': ['makefile', 'mk'], 'Lua script': 'lua', 'Pug document': 'pug', 'Jupyter': 'ipynb', 'Lockfile': 'lock', 'Log file': 'log', 'Plain Text File': 'txt', 'Xcode project file': 'xcodeproj', 'Xcode workspace file': 'xcworkspace', 'Visual Basic script': 'vb', 'R source code': 'r', 'Rust source code': 'rs', 'Restructured Text document': 'rst', 'LaTeX document': ['tex', 'cls'], 'F# source code': 'fs', 'F# signature file': 'fsi', 'F# script': ['fsx', 'fsscript'], 'SVG document': ['svg'], 'TOML document': 'toml', 'Swift source code': 'swift', }, 'default'), // Default icon with default name darwinBundleDocumentType([ 'containerfile', 'ctp', 'dot', 'edn', 'handlebars', 'hbs', 'ml', 'mli', 'pl', 'pl6', 'pm', 'pm6', 'pod', 'pp', 'properties', 'psgi', 'rt', 't' ], 'default', product.nameLong + ' document'), // Folder support () darwinBundleDocumentType([], 'default', 'Folder', ['public.folder']) ], darwinBundleURLTypes: [{ role: 'Viewer', name: product.nameLong, urlSchemes: [product.urlProtocol] }], darwinForceDarkModeSupport: true, darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined, linuxExecutableName: product.applicationName, winIcon: 'resources/win32/code.ico', token: process.env['GITHUB_TOKEN'], repo: product.electronRepository || undefined, validateChecksum: true, checksumFile: path_1.default.join(root, 'build', 'checksums', 'electron.txt'), }; function getElectron(arch) { return () => { const electron = require('@vscode/gulp-electron'); const json = require('gulp-json-editor'); const electronOpts = { ...exports.config, platform: process.platform, arch: arch === 'armhf' ? 'arm' : arch, ffmpegChromium: false, keepDefaultApp: true }; return vinyl_fs_1.default.src('package.json') .pipe(json({ name: product.nameShort })) .pipe(electron(electronOpts)) .pipe((0, gulp_filter_1.default)(['**', '!**/app/package.json'])) .pipe(vinyl_fs_1.default.dest('.build/electron')); }; } async function main(arch = process.arch) { const version = electronVersion; const electronPath = path_1.default.join(root, '.build', 'electron'); const versionFile = path_1.default.join(electronPath, 'version'); const isUpToDate = fs_1.default.existsSync(versionFile) && fs_1.default.readFileSync(versionFile, 'utf8') === `${version}`; if (!isUpToDate) { await util.rimraf(electronPath)(); await util.streamToPromise(getElectron(arch)()); } } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=electron.js.map ================================================ FILE: build/lib/electron.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import vfs from 'vinyl-fs'; import filter from 'gulp-filter'; import * as util from './util'; import { getVersion } from './getVersion'; type DarwinDocumentSuffix = 'document' | 'script' | 'file' | 'source code'; type DarwinDocumentType = { name: string; role: string; ostypes: string[]; extensions: string[]; iconFile: string; utis?: string[]; }; function isDocumentSuffix(str?: string): str is DarwinDocumentSuffix { return str === 'document' || str === 'script' || str === 'file' || str === 'source code'; } const root = path.dirname(path.dirname(__dirname)); const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8')); const commit = getVersion(root); function createTemplate(input: string): (params: Record) => string { return (params: Record) => { return input.replace(/<%=\s*([^\s]+)\s*%>/g, (match, key) => { return params[key] || match; }); }; } const darwinCreditsTemplate = product.darwinCredits && createTemplate(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8')); /** * Generate a `DarwinDocumentType` given a list of file extensions, an icon name, and an optional suffix or file type name. * @param extensions A list of file extensions, such as `['bat', 'cmd']` * @param icon A sentence-cased file type name that matches the lowercase name of a darwin icon resource. * For example, `'HTML'` instead of `'html'`, or `'Java'` instead of `'java'`. * This parameter is lowercased before it is used to reference an icon file. * @param nameOrSuffix An optional suffix or a string to use as the file type. If a suffix is provided, * it is used with the icon parameter to generate a file type string. If nothing is provided, * `'document'` is used with the icon parameter to generate file type string. * * For example, if you call `darwinBundleDocumentType(..., 'HTML')`, the resulting file type is `"HTML document"`, * and the `'html'` darwin icon is used. * * If you call `darwinBundleDocumentType(..., 'Javascript', 'file')`, the resulting file type is `"Javascript file"`. * and the `'javascript'` darwin icon is used. * * If you call `darwinBundleDocumentType(..., 'bat', 'Windows command script')`, the file type is `"Windows command script"`, * and the `'bat'` darwin icon is used. */ function darwinBundleDocumentType(extensions: string[], icon: string, nameOrSuffix?: string | DarwinDocumentSuffix, utis?: string[]): DarwinDocumentType { // If given a suffix, generate a name from it. If not given anything, default to 'document' if (isDocumentSuffix(nameOrSuffix) || !nameOrSuffix) { nameOrSuffix = icon.charAt(0).toUpperCase() + icon.slice(1) + ' ' + (nameOrSuffix ?? 'document'); } return { name: nameOrSuffix, role: 'Editor', ostypes: ['TEXT', 'utxt', 'TUTX', '****'], extensions, iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', utis }; } /** * Generate several `DarwinDocumentType`s with unique names and a shared icon. * @param types A map of file type names to their associated file extensions. * @param icon A darwin icon resource to use. For example, `'HTML'` would refer to `resources/darwin/html.icns` * * Examples: * ``` * darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' },'c') * darwinBundleDocumentTypes({ 'React source code': ['jsx', 'tsx'] }, 'react') * ``` */ function darwinBundleDocumentTypes(types: { [name: string]: string | string[] }, icon: string): DarwinDocumentType[] { return Object.keys(types).map((name: string): DarwinDocumentType => { const extensions = types[name]; return { name, role: 'Editor', ostypes: ['TEXT', 'utxt', 'TUTX', '****'], extensions: Array.isArray(extensions) ? extensions : [extensions], iconFile: 'resources/darwin/' + icon + '.icns' }; }); } const { electronVersion, msBuildId } = util.getElectronVersion(); export const config = { version: electronVersion, tag: product.electronRepository ? `v${electronVersion}-${msBuildId}` : undefined, productAppName: product.nameLong, companyName: 'Microsoft Corporation', copyright: 'Copyright (C) 2024 Microsoft. All rights reserved', darwinIcon: 'resources/darwin/code.icns', darwinBundleIdentifier: product.darwinBundleIdentifier, darwinApplicationCategoryType: 'public.app-category.developer-tools', darwinHelpBookFolder: 'VS Code HelpBook', darwinHelpBookName: 'VS Code HelpBook', darwinBundleDocumentTypes: [ ...darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' }, 'c'), ...darwinBundleDocumentTypes({ 'Git configuration file': ['gitattributes', 'gitconfig', 'gitignore'] }, 'config'), ...darwinBundleDocumentTypes({ 'HTML template document': ['asp', 'aspx', 'cshtml', 'jshtm', 'jsp', 'phtml', 'shtml'] }, 'html'), darwinBundleDocumentType(['bat', 'cmd'], 'bat', 'Windows command script'), darwinBundleDocumentType(['bowerrc'], 'Bower'), darwinBundleDocumentType(['config', 'editorconfig', 'ini', 'cfg'], 'config', 'Configuration file'), darwinBundleDocumentType(['hh', 'hpp', 'hxx', 'h++'], 'cpp', 'C++ header file'), darwinBundleDocumentType(['cc', 'cpp', 'cxx', 'c++'], 'cpp', 'C++ source code'), darwinBundleDocumentType(['m'], 'default', 'Objective-C source code'), darwinBundleDocumentType(['mm'], 'cpp', 'Objective-C++ source code'), darwinBundleDocumentType(['cs', 'csx'], 'csharp', 'C# source code'), darwinBundleDocumentType(['css'], 'css', 'CSS'), darwinBundleDocumentType(['go'], 'go', 'Go source code'), darwinBundleDocumentType(['htm', 'html', 'xhtml'], 'HTML'), darwinBundleDocumentType(['jade'], 'Jade'), darwinBundleDocumentType(['jav', 'java'], 'Java'), darwinBundleDocumentType(['js', 'jscsrc', 'jshintrc', 'mjs', 'cjs'], 'Javascript', 'file'), darwinBundleDocumentType(['json'], 'JSON'), darwinBundleDocumentType(['less'], 'Less'), darwinBundleDocumentType(['markdown', 'md', 'mdoc', 'mdown', 'mdtext', 'mdtxt', 'mdwn', 'mkd', 'mkdn'], 'Markdown'), darwinBundleDocumentType(['php'], 'PHP', 'source code'), darwinBundleDocumentType(['ps1', 'psd1', 'psm1'], 'Powershell', 'script'), darwinBundleDocumentType(['py', 'pyi'], 'Python', 'script'), darwinBundleDocumentType(['gemspec', 'rb', 'erb'], 'Ruby', 'source code'), darwinBundleDocumentType(['scss', 'sass'], 'SASS', 'file'), darwinBundleDocumentType(['sql'], 'SQL', 'script'), darwinBundleDocumentType(['ts'], 'TypeScript', 'file'), darwinBundleDocumentType(['tsx', 'jsx'], 'React', 'source code'), darwinBundleDocumentType(['vue'], 'Vue', 'source code'), darwinBundleDocumentType(['ascx', 'csproj', 'dtd', 'plist', 'wxi', 'wxl', 'wxs', 'xml', 'xaml'], 'XML'), darwinBundleDocumentType(['eyaml', 'eyml', 'yaml', 'yml'], 'YAML'), darwinBundleDocumentType([ 'bash', 'bash_login', 'bash_logout', 'bash_profile', 'bashrc', 'profile', 'rhistory', 'rprofile', 'sh', 'zlogin', 'zlogout', 'zprofile', 'zsh', 'zshenv', 'zshrc' ], 'Shell', 'script'), // Default icon with specified names ...darwinBundleDocumentTypes({ 'Clojure source code': ['clj', 'cljs', 'cljx', 'clojure'], 'VS Code workspace file': 'code-workspace', 'CoffeeScript source code': 'coffee', 'Comma Separated Values': 'csv', 'CMake script': 'cmake', 'Dart script': 'dart', 'Diff file': 'diff', 'Dockerfile': 'dockerfile', 'Gradle file': 'gradle', 'Groovy script': 'groovy', 'Makefile': ['makefile', 'mk'], 'Lua script': 'lua', 'Pug document': 'pug', 'Jupyter': 'ipynb', 'Lockfile': 'lock', 'Log file': 'log', 'Plain Text File': 'txt', 'Xcode project file': 'xcodeproj', 'Xcode workspace file': 'xcworkspace', 'Visual Basic script': 'vb', 'R source code': 'r', 'Rust source code': 'rs', 'Restructured Text document': 'rst', 'LaTeX document': ['tex', 'cls'], 'F# source code': 'fs', 'F# signature file': 'fsi', 'F# script': ['fsx', 'fsscript'], 'SVG document': ['svg'], 'TOML document': 'toml', 'Swift source code': 'swift', }, 'default'), // Default icon with default name darwinBundleDocumentType([ 'containerfile', 'ctp', 'dot', 'edn', 'handlebars', 'hbs', 'ml', 'mli', 'pl', 'pl6', 'pm', 'pm6', 'pod', 'pp', 'properties', 'psgi', 'rt', 't' ], 'default', product.nameLong + ' document'), // Folder support () darwinBundleDocumentType([], 'default', 'Folder', ['public.folder']) ], darwinBundleURLTypes: [{ role: 'Viewer', name: product.nameLong, urlSchemes: [product.urlProtocol] }], darwinForceDarkModeSupport: true, darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined, linuxExecutableName: product.applicationName, winIcon: 'resources/win32/code.ico', token: process.env['GITHUB_TOKEN'], repo: product.electronRepository || undefined, validateChecksum: true, checksumFile: path.join(root, 'build', 'checksums', 'electron.txt'), }; function getElectron(arch: string): () => NodeJS.ReadWriteStream { return () => { const electron = require('@vscode/gulp-electron'); const json = require('gulp-json-editor') as typeof import('gulp-json-editor'); const electronOpts = { ...config, platform: process.platform, arch: arch === 'armhf' ? 'arm' : arch, ffmpegChromium: false, keepDefaultApp: true }; return vfs.src('package.json') .pipe(json({ name: product.nameShort })) .pipe(electron(electronOpts)) .pipe(filter(['**', '!**/app/package.json'])) .pipe(vfs.dest('.build/electron')); }; } async function main(arch: string = process.arch): Promise { const version = electronVersion; const electronPath = path.join(root, '.build', 'electron'); const versionFile = path.join(electronPath, 'version'); const isUpToDate = fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf8') === `${version}`; if (!isUpToDate) { await util.rimraf(electronPath)(); await util.streamToPromise(getElectron(arch)()); } } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/lib/extensions.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fromMarketplace = fromMarketplace; exports.fromVsix = fromVsix; exports.fromGithub = fromGithub; exports.packageNonNativeLocalExtensionsStream = packageNonNativeLocalExtensionsStream; exports.packageNativeLocalExtensionsStream = packageNativeLocalExtensionsStream; exports.packageAllLocalExtensionsStream = packageAllLocalExtensionsStream; exports.packageMarketplaceExtensionsStream = packageMarketplaceExtensionsStream; exports.scanBuiltinExtensions = scanBuiltinExtensions; exports.translatePackageJSON = translatePackageJSON; exports.webpackExtensions = webpackExtensions; exports.buildExtensionMedia = buildExtensionMedia; const event_stream_1 = __importDefault(require("event-stream")); const fs_1 = __importDefault(require("fs")); const child_process_1 = __importDefault(require("child_process")); const glob_1 = __importDefault(require("glob")); const gulp_1 = __importDefault(require("gulp")); const path_1 = __importDefault(require("path")); const crypto_1 = __importDefault(require("crypto")); const vinyl_1 = __importDefault(require("vinyl")); const stats_1 = require("./stats"); const util2 = __importStar(require("./util")); const vzip = require('gulp-vinyl-zip'); const gulp_filter_1 = __importDefault(require("gulp-filter")); const gulp_rename_1 = __importDefault(require("gulp-rename")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const gulp_buffer_1 = __importDefault(require("gulp-buffer")); const jsoncParser = __importStar(require("jsonc-parser")); const dependencies_1 = require("./dependencies"); const builtInExtensions_1 = require("./builtInExtensions"); const getVersion_1 = require("./getVersion"); const fetch_1 = require("./fetch"); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const commit = (0, getVersion_1.getVersion)(root); const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; function minifyExtensionResources(input) { const jsonFilter = (0, gulp_filter_1.default)(['**/*.json', '**/*.code-snippets'], { restore: true }); return input .pipe(jsonFilter) .pipe((0, gulp_buffer_1.default)()) .pipe(event_stream_1.default.mapSync((f) => { const errors = []; const value = jsoncParser.parse(f.contents.toString('utf8'), errors, { allowTrailingComma: true }); if (errors.length === 0) { // file parsed OK => just stringify to drop whitespace and comments f.contents = Buffer.from(JSON.stringify(value)); } return f; })) .pipe(jsonFilter.restore); } function updateExtensionPackageJSON(input, update) { const packageJsonFilter = (0, gulp_filter_1.default)('extensions/*/package.json', { restore: true }); return input .pipe(packageJsonFilter) .pipe((0, gulp_buffer_1.default)()) .pipe(event_stream_1.default.mapSync((f) => { const data = JSON.parse(f.contents.toString('utf8')); f.contents = Buffer.from(JSON.stringify(update(data))); return f; })) .pipe(packageJsonFilter.restore); } function fromLocal(extensionPath, forWeb, disableMangle) { const webpackConfigFileName = forWeb ? 'extension-browser.webpack.config.js' : 'extension.webpack.config.js'; const isWebPacked = fs_1.default.existsSync(path_1.default.join(extensionPath, webpackConfigFileName)); let input = isWebPacked ? fromLocalWebpack(extensionPath, webpackConfigFileName, disableMangle) : fromLocalNormal(extensionPath); if (isWebPacked) { input = updateExtensionPackageJSON(input, (data) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; if (data.main) { data.main = data.main.replace('/out/', '/dist/'); } return data; }); } return input; } function fromLocalWebpack(extensionPath, webpackConfigFileName, disableMangle) { const vsce = require('@vscode/vsce'); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); const result = event_stream_1.default.through(); const packagedDependencies = []; const packageJsonConfig = require(path_1.default.join(extensionPath, 'package.json')); if (packageJsonConfig.dependencies) { const webpackRootConfig = require(path_1.default.join(extensionPath, webpackConfigFileName)); for (const key in webpackRootConfig.externals) { if (key in packageJsonConfig.dependencies) { packagedDependencies.push(key); } } } // TODO: add prune support based on packagedDependencies to vsce.PackageManager.Npm similar // to vsce.PackageManager.Yarn. // A static analysis showed there are no webpack externals that are dependencies of the current // local extensions so we can use the vsce.PackageManager.None config to ignore dependencies list // as a temporary workaround. vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.None, packagedDependencies }).then(fileNames => { const files = fileNames .map(fileName => path_1.default.join(extensionPath, fileName)) .map(filePath => new vinyl_1.default({ path: filePath, stat: fs_1.default.statSync(filePath), base: extensionPath, contents: fs_1.default.createReadStream(filePath) })); // check for a webpack configuration files, then invoke webpack // and merge its output with the files stream. const webpackConfigLocations = glob_1.default.sync(path_1.default.join(extensionPath, '**', webpackConfigFileName), { ignore: ['**/node_modules'] }); const webpackStreams = webpackConfigLocations.flatMap(webpackConfigPath => { const webpackDone = (err, stats) => { (0, fancy_log_1.default)(`Bundled extension: ${ansi_colors_1.default.yellow(path_1.default.join(path_1.default.basename(extensionPath), path_1.default.relative(extensionPath, webpackConfigPath)))}...`); if (err) { result.emit('error', err); } const { compilation } = stats; if (compilation.errors.length > 0) { result.emit('error', compilation.errors.join('\n')); } if (compilation.warnings.length > 0) { result.emit('error', compilation.warnings.join('\n')); } }; const exportedConfig = require(webpackConfigPath); return (Array.isArray(exportedConfig) ? exportedConfig : [exportedConfig]).map(config => { const webpackConfig = { ...config, ...{ mode: 'production' } }; if (disableMangle) { if (Array.isArray(config.module.rules)) { for (const rule of config.module.rules) { if (Array.isArray(rule.use)) { for (const use of rule.use) { if (String(use.loader).endsWith('mangle-loader.js')) { use.options.disabled = true; } } } } } } const relativeOutputPath = path_1.default.relative(extensionPath, webpackConfig.output.path); return webpackGulp(webpackConfig, webpack, webpackDone) .pipe(event_stream_1.default.through(function (data) { data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); })) .pipe(event_stream_1.default.through(function (data) { // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up if (path_1.default.extname(data.basename) === '.js') { const contents = data.contents.toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path_1.default.basename(extensionPath)}/${relativeOutputPath}/${g1}`; }), 'utf8'); } this.emit('data', data); })); }); }); event_stream_1.default.merge(...webpackStreams, event_stream_1.default.readArray(files)) // .pipe(es.through(function (data) { // // debug // console.log('out', data.path, data.contents.length); // this.emit('data', data); // })) .pipe(result); }).catch(err => { console.error(extensionPath); console.error(packagedDependencies); result.emit('error', err); }); return result.pipe((0, stats_1.createStatsStream)(path_1.default.basename(extensionPath))); } function fromLocalNormal(extensionPath) { const vsce = require('@vscode/vsce'); const result = event_stream_1.default.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Npm }) .then(fileNames => { const files = fileNames .map(fileName => path_1.default.join(extensionPath, fileName)) .map(filePath => new vinyl_1.default({ path: filePath, stat: fs_1.default.statSync(filePath), base: extensionPath, contents: fs_1.default.createReadStream(filePath) })); event_stream_1.default.readArray(files).pipe(result); }) .catch(err => result.emit('error', err)); return result.pipe((0, stats_1.createStatsStream)(path_1.default.basename(extensionPath))); } const userAgent = 'VSCode Build'; const baseHeaders = { 'X-Market-Client-Id': 'VSCode Build', 'User-Agent': userAgent, 'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2', }; function fromMarketplace(serviceUrl, { name: extensionName, version, sha256, metadata }) { const json = require('gulp-json-editor'); const [publisher, name] = extensionName.split('.'); const url = `${serviceUrl}/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`; (0, fancy_log_1.default)('Downloading extension:', ansi_colors_1.default.yellow(`${extensionName}@${version}`), '...'); const packageJsonFilter = (0, gulp_filter_1.default)('package.json', { restore: true }); return (0, fetch_1.fetchUrls)('', { base: url, nodeFetchOptions: { headers: baseHeaders }, checksumSha256: sha256 }) .pipe(vzip.src()) .pipe((0, gulp_filter_1.default)('extension/**')) .pipe((0, gulp_rename_1.default)(p => p.dirname = p.dirname.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe((0, gulp_buffer_1.default)()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } function fromVsix(vsixPath, { name: extensionName, version, sha256, metadata }) { const json = require('gulp-json-editor'); (0, fancy_log_1.default)('Using local VSIX for extension:', ansi_colors_1.default.yellow(`${extensionName}@${version}`), '...'); const packageJsonFilter = (0, gulp_filter_1.default)('package.json', { restore: true }); return gulp_1.default.src(vsixPath) .pipe((0, gulp_buffer_1.default)()) .pipe(event_stream_1.default.mapSync((f) => { const hash = crypto_1.default.createHash('sha256'); hash.update(f.contents); const checksum = hash.digest('hex'); if (checksum !== sha256) { throw new Error(`Checksum mismatch for ${vsixPath} (expected ${sha256}, actual ${checksum}))`); } return f; })) .pipe(vzip.src()) .pipe((0, gulp_filter_1.default)('extension/**')) .pipe((0, gulp_rename_1.default)(p => p.dirname = p.dirname.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe((0, gulp_buffer_1.default)()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } function fromGithub({ name, version, repo, sha256, metadata }) { const json = require('gulp-json-editor'); (0, fancy_log_1.default)('Downloading extension from GH:', ansi_colors_1.default.yellow(`${name}@${version}`), '...'); const packageJsonFilter = (0, gulp_filter_1.default)('package.json', { restore: true }); return (0, fetch_1.fetchGithub)(new URL(repo).pathname, { version, name: name => name.endsWith('.vsix'), checksumSha256: sha256 }) .pipe((0, gulp_buffer_1.default)()) .pipe(vzip.src()) .pipe((0, gulp_filter_1.default)('extension/**')) .pipe((0, gulp_rename_1.default)(p => p.dirname = p.dirname.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe((0, gulp_buffer_1.default)()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } /** * All extensions that are known to have some native component and thus must be built on the * platform that is being built. */ const nativeExtensions = [ 'microsoft-authentication', ]; const excludedExtensions = [ 'vscode-api-tests', 'vscode-colorize-tests', 'vscode-colorize-perf-tests', 'vscode-test-resolver', 'ms-vscode.node-debug', 'ms-vscode.node-debug2', ]; const marketplaceWebExtensionsExclude = new Set([ 'ms-vscode.node-debug', 'ms-vscode.node-debug2', 'ms-vscode.js-debug-companion', 'ms-vscode.js-debug', 'ms-vscode.vscode-js-profile-table' ]); const productJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions = productJson.builtInExtensions || []; const webBuiltInExtensions = productJson.webBuiltInExtensions || []; /** * Loosely based on `getExtensionKind` from `src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts` */ function isWebExtension(manifest) { if (Boolean(manifest.browser)) { return true; } if (Boolean(manifest.main)) { return false; } // neither browser nor main if (typeof manifest.extensionKind !== 'undefined') { const extensionKind = Array.isArray(manifest.extensionKind) ? manifest.extensionKind : [manifest.extensionKind]; if (extensionKind.indexOf('web') >= 0) { return true; } } if (typeof manifest.contributes !== 'undefined') { for (const id of ['debuggers', 'terminal', 'typescriptServerPlugins']) { if (manifest.contributes.hasOwnProperty(id)) { return false; } } } return true; } /** * Package local extensions that are known to not have native dependencies. Mutually exclusive to {@link packageNativeLocalExtensionsStream}. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ function packageNonNativeLocalExtensionsStream(forWeb, disableMangle) { return doPackageLocalExtensionsStream(forWeb, disableMangle, false); } /** * Package local extensions that are known to have native dependencies. Mutually exclusive to {@link packageNonNativeLocalExtensionsStream}. * @note it's possible that the extension does not have native dependencies for the current platform, especially if building for the web, * but we simplify the logic here by having a flat list of extensions (See {@link nativeExtensions}) that are known to have native * dependencies on some platform and thus should be packaged on the platform that they are building for. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ function packageNativeLocalExtensionsStream(forWeb, disableMangle) { return doPackageLocalExtensionsStream(forWeb, disableMangle, true); } /** * Package all the local extensions... both those that are known to have native dependencies and those that are not. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ function packageAllLocalExtensionsStream(forWeb, disableMangle) { return event_stream_1.default.merge([ packageNonNativeLocalExtensionsStream(forWeb, disableMangle), packageNativeLocalExtensionsStream(forWeb, disableMangle) ]); } /** * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @param native build the extensions that are marked as having native dependencies */ function doPackageLocalExtensionsStream(forWeb, disableMangle, native) { const nativeExtensionsSet = new Set(nativeExtensions); const localExtensionsDescriptions = (glob_1.default.sync('extensions/*/package.json') .map(manifestPath => { const absoluteManifestPath = path_1.default.join(root, manifestPath); const extensionPath = path_1.default.dirname(path_1.default.join(root, manifestPath)); const extensionName = path_1.default.basename(extensionPath); return { name: extensionName, path: extensionPath, manifestPath: absoluteManifestPath }; }) .filter(({ name }) => native ? nativeExtensionsSet.has(name) : !nativeExtensionsSet.has(name)) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)) .filter(({ manifestPath }) => (forWeb ? isWebExtension(require(manifestPath)) : true))); const localExtensionsStream = minifyExtensionResources(event_stream_1.default.merge(...localExtensionsDescriptions.map(extension => { return fromLocal(extension.path, forWeb, disableMangle) .pipe((0, gulp_rename_1.default)(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); }))); let result; if (forWeb) { result = localExtensionsStream; } else { // also include shared production node modules const productionDependencies = (0, dependencies_1.getProductionDependencies)('extensions/'); const dependenciesSrc = productionDependencies.map(d => path_1.default.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat(); result = event_stream_1.default.merge(localExtensionsStream, gulp_1.default.src(dependenciesSrc, { base: '.' }) .pipe(util2.cleanNodeModules(path_1.default.join(root, 'build', '.moduleignore'))) .pipe(util2.cleanNodeModules(path_1.default.join(root, 'build', `.moduleignore.${process.platform}`)))); } return (result .pipe(util2.setExecutableBit(['**/*.sh']))); } function packageMarketplaceExtensionsStream(forWeb) { const marketplaceExtensionsDescriptions = [ ...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)), ...(forWeb ? webBuiltInExtensions : []) ]; const marketplaceExtensionsStream = minifyExtensionResources(event_stream_1.default.merge(...marketplaceExtensionsDescriptions .map(extension => { const src = (0, builtInExtensions_1.getExtensionStream)(extension).pipe((0, gulp_rename_1.default)(p => p.dirname = `extensions/${p.dirname}`)); return updateExtensionPackageJSON(src, (data) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; return data; }); }))); return (marketplaceExtensionsStream .pipe(util2.setExecutableBit(['**/*.sh']))); } function scanBuiltinExtensions(extensionsRoot, exclude = []) { const scannedExtensions = []; try { const extensionsFolders = fs_1.default.readdirSync(extensionsRoot); for (const extensionFolder of extensionsFolders) { if (exclude.indexOf(extensionFolder) >= 0) { continue; } const packageJSONPath = path_1.default.join(extensionsRoot, extensionFolder, 'package.json'); if (!fs_1.default.existsSync(packageJSONPath)) { continue; } const packageJSON = JSON.parse(fs_1.default.readFileSync(packageJSONPath).toString('utf8')); if (!isWebExtension(packageJSON)) { continue; } const children = fs_1.default.readdirSync(path_1.default.join(extensionsRoot, extensionFolder)); const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; const packageNLS = packageNLSPath ? JSON.parse(fs_1.default.readFileSync(path_1.default.join(extensionsRoot, extensionFolder, packageNLSPath)).toString()) : undefined; const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; scannedExtensions.push({ extensionPath: extensionFolder, packageJSON, packageNLS, readmePath: readme ? path_1.default.join(extensionFolder, readme) : undefined, changelogPath: changelog ? path_1.default.join(extensionFolder, changelog) : undefined, }); } return scannedExtensions; } catch (ex) { return scannedExtensions; } } function translatePackageJSON(packageJSON, packageNLSPath) { const CharCode_PC = '%'.charCodeAt(0); const packageNls = JSON.parse(fs_1.default.readFileSync(packageNLSPath).toString()); const translate = (obj) => { for (const key in obj) { const val = obj[key]; if (Array.isArray(val)) { val.forEach(translate); } else if (val && typeof val === 'object') { translate(val); } else if (typeof val === 'string' && val.charCodeAt(0) === CharCode_PC && val.charCodeAt(val.length - 1) === CharCode_PC) { const translated = packageNls[val.substr(1, val.length - 2)]; if (translated) { obj[key] = typeof translated === 'string' ? translated : (typeof translated.message === 'string' ? translated.message : val); } } } }; translate(packageJSON); return packageJSON; } const extensionsPath = path_1.default.join(root, 'extensions'); // Additional projects to run esbuild on. These typically build code for webviews const esbuildMediaScripts = [ 'markdown-language-features/esbuild-notebook.js', 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; async function webpackExtensions(taskName, isWatch, webpackConfigLocations) { const webpack = require('webpack'); const webpackConfigs = []; for (const { configPath, outputRoot } of webpackConfigLocations) { const configOrFnOrArray = require(configPath); function addConfig(configOrFnOrArray) { for (const configOrFn of Array.isArray(configOrFnOrArray) ? configOrFnOrArray : [configOrFnOrArray]) { const config = typeof configOrFn === 'function' ? configOrFn({}, {}) : configOrFn; if (outputRoot) { config.output.path = path_1.default.join(outputRoot, path_1.default.relative(path_1.default.dirname(configPath), config.output.path)); } webpackConfigs.push(config); } } addConfig(configOrFnOrArray); } function reporter(fullStats) { if (Array.isArray(fullStats.children)) { for (const stats of fullStats.children) { const outputPath = stats.outputPath; if (outputPath) { const relativePath = path_1.default.relative(extensionsPath, outputPath).replace(/\\/g, '/'); const match = relativePath.match(/[^\/]+(\/server|\/client)?/); (0, fancy_log_1.default)(`Finished ${ansi_colors_1.default.green(taskName)} ${ansi_colors_1.default.cyan(match[0])} with ${stats.errors.length} errors.`); } if (Array.isArray(stats.errors)) { stats.errors.forEach((error) => { fancy_log_1.default.error(error); }); } if (Array.isArray(stats.warnings)) { stats.warnings.forEach((warning) => { fancy_log_1.default.warn(warning); }); } } } } return new Promise((resolve, reject) => { if (isWatch) { webpack(webpackConfigs).watch({}, (err, stats) => { if (err) { reject(); } else { reporter(stats?.toJson()); } }); } else { webpack(webpackConfigs).run((err, stats) => { if (err) { fancy_log_1.default.error(err); reject(); } else { reporter(stats?.toJson()); resolve(); } }); } }); } async function esbuildExtensions(taskName, isWatch, scripts) { function reporter(stdError, script) { const matches = (stdError || '').match(/\> (.+): error: (.+)?/g); (0, fancy_log_1.default)(`Finished ${ansi_colors_1.default.green(taskName)} ${script} with ${matches ? matches.length : 0} errors.`); for (const match of matches || []) { fancy_log_1.default.error(match); } } const tasks = scripts.map(({ script, outputRoot }) => { return new Promise((resolve, reject) => { const args = [script]; if (isWatch) { args.push('--watch'); } if (outputRoot) { args.push('--outputRoot', outputRoot); } const proc = child_process_1.default.execFile(process.argv[0], args, {}, (error, _stdout, stderr) => { if (error) { return reject(error); } reporter(stderr, script); return resolve(); }); proc.stdout.on('data', (data) => { (0, fancy_log_1.default)(`${ansi_colors_1.default.green(taskName)}: ${data.toString('utf8')}`); }); }); }); return Promise.all(tasks); } async function buildExtensionMedia(isWatch, outputRoot) { return esbuildExtensions('esbuilding extension media', isWatch, esbuildMediaScripts.map(p => ({ script: path_1.default.join(extensionsPath, p), outputRoot: outputRoot ? path_1.default.join(root, outputRoot, path_1.default.dirname(p)) : undefined }))); } //# sourceMappingURL=extensions.js.map ================================================ FILE: build/lib/extensions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import fs from 'fs'; import cp from 'child_process'; import glob from 'glob'; import gulp from 'gulp'; import path from 'path'; import crypto from 'crypto'; import { Stream } from 'stream'; import File from 'vinyl'; import { createStatsStream } from './stats'; import * as util2 from './util'; const vzip = require('gulp-vinyl-zip'); import filter from 'gulp-filter'; import rename from 'gulp-rename'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import buffer from 'gulp-buffer'; import * as jsoncParser from 'jsonc-parser'; import webpack from 'webpack'; import { getProductionDependencies } from './dependencies'; import { IExtensionDefinition, getExtensionStream } from './builtInExtensions'; import { getVersion } from './getVersion'; import { fetchUrls, fetchGithub } from './fetch'; const root = path.dirname(path.dirname(__dirname)); const commit = getVersion(root); const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; function minifyExtensionResources(input: Stream): Stream { const jsonFilter = filter(['**/*.json', '**/*.code-snippets'], { restore: true }); return input .pipe(jsonFilter) .pipe(buffer()) .pipe(es.mapSync((f: File) => { const errors: jsoncParser.ParseError[] = []; const value = jsoncParser.parse(f.contents.toString('utf8'), errors, { allowTrailingComma: true }); if (errors.length === 0) { // file parsed OK => just stringify to drop whitespace and comments f.contents = Buffer.from(JSON.stringify(value)); } return f; })) .pipe(jsonFilter.restore); } function updateExtensionPackageJSON(input: Stream, update: (data: any) => any): Stream { const packageJsonFilter = filter('extensions/*/package.json', { restore: true }); return input .pipe(packageJsonFilter) .pipe(buffer()) .pipe(es.mapSync((f: File) => { const data = JSON.parse(f.contents.toString('utf8')); f.contents = Buffer.from(JSON.stringify(update(data))); return f; })) .pipe(packageJsonFilter.restore); } function fromLocal(extensionPath: string, forWeb: boolean, disableMangle: boolean): Stream { const webpackConfigFileName = forWeb ? 'extension-browser.webpack.config.js' : 'extension.webpack.config.js'; const isWebPacked = fs.existsSync(path.join(extensionPath, webpackConfigFileName)); let input = isWebPacked ? fromLocalWebpack(extensionPath, webpackConfigFileName, disableMangle) : fromLocalNormal(extensionPath); if (isWebPacked) { input = updateExtensionPackageJSON(input, (data: any) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; if (data.main) { data.main = data.main.replace('/out/', '/dist/'); } return data; }); } return input; } function fromLocalWebpack(extensionPath: string, webpackConfigFileName: string, disableMangle: boolean): Stream { const vsce = require('@vscode/vsce') as typeof import('@vscode/vsce'); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); const result = es.through(); const packagedDependencies: string[] = []; const packageJsonConfig = require(path.join(extensionPath, 'package.json')); if (packageJsonConfig.dependencies) { const webpackRootConfig = require(path.join(extensionPath, webpackConfigFileName)); for (const key in webpackRootConfig.externals) { if (key in packageJsonConfig.dependencies) { packagedDependencies.push(key); } } } // TODO: add prune support based on packagedDependencies to vsce.PackageManager.Npm similar // to vsce.PackageManager.Yarn. // A static analysis showed there are no webpack externals that are dependencies of the current // local extensions so we can use the vsce.PackageManager.None config to ignore dependencies list // as a temporary workaround. vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.None, packagedDependencies }).then(fileNames => { const files = fileNames .map(fileName => path.join(extensionPath, fileName)) .map(filePath => new File({ path: filePath, stat: fs.statSync(filePath), base: extensionPath, contents: fs.createReadStream(filePath) as any })); // check for a webpack configuration files, then invoke webpack // and merge its output with the files stream. const webpackConfigLocations = (glob.sync( path.join(extensionPath, '**', webpackConfigFileName), { ignore: ['**/node_modules'] } )); const webpackStreams = webpackConfigLocations.flatMap(webpackConfigPath => { const webpackDone = (err: any, stats: any) => { fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`); if (err) { result.emit('error', err); } const { compilation } = stats; if (compilation.errors.length > 0) { result.emit('error', compilation.errors.join('\n')); } if (compilation.warnings.length > 0) { result.emit('error', compilation.warnings.join('\n')); } }; const exportedConfig = require(webpackConfigPath); return (Array.isArray(exportedConfig) ? exportedConfig : [exportedConfig]).map(config => { const webpackConfig = { ...config, ...{ mode: 'production' } }; if (disableMangle) { if (Array.isArray(config.module.rules)) { for (const rule of config.module.rules) { if (Array.isArray(rule.use)) { for (const use of rule.use) { if (String(use.loader).endsWith('mangle-loader.js')) { use.options.disabled = true; } } } } } } const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path); return webpackGulp(webpackConfig, webpack, webpackDone) .pipe(es.through(function (data) { data.stat = data.stat || {}; data.base = extensionPath; this.emit('data', data); })) .pipe(es.through(function (data: File) { // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up if (path.extname(data.basename) === '.js') { const contents = (data.contents).toString('utf8'); data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; }), 'utf8'); } this.emit('data', data); })); }); }); es.merge(...webpackStreams, es.readArray(files)) // .pipe(es.through(function (data) { // // debug // console.log('out', data.path, data.contents.length); // this.emit('data', data); // })) .pipe(result); }).catch(err => { console.error(extensionPath); console.error(packagedDependencies); result.emit('error', err); }); return result.pipe(createStatsStream(path.basename(extensionPath))); } function fromLocalNormal(extensionPath: string): Stream { const vsce = require('@vscode/vsce') as typeof import('@vscode/vsce'); const result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Npm }) .then(fileNames => { const files = fileNames .map(fileName => path.join(extensionPath, fileName)) .map(filePath => new File({ path: filePath, stat: fs.statSync(filePath), base: extensionPath, contents: fs.createReadStream(filePath) as any })); es.readArray(files).pipe(result); }) .catch(err => result.emit('error', err)); return result.pipe(createStatsStream(path.basename(extensionPath))); } const userAgent = 'VSCode Build'; const baseHeaders = { 'X-Market-Client-Id': 'VSCode Build', 'User-Agent': userAgent, 'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2', }; export function fromMarketplace(serviceUrl: string, { name: extensionName, version, sha256, metadata }: IExtensionDefinition): Stream { const json = require('gulp-json-editor') as typeof import('gulp-json-editor'); const [publisher, name] = extensionName.split('.'); const url = `${serviceUrl}/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`; fancyLog('Downloading extension:', ansiColors.yellow(`${extensionName}@${version}`), '...'); const packageJsonFilter = filter('package.json', { restore: true }); return fetchUrls('', { base: url, nodeFetchOptions: { headers: baseHeaders }, checksumSha256: sha256 }) .pipe(vzip.src()) .pipe(filter('extension/**')) .pipe(rename(p => p.dirname = p.dirname!.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe(buffer()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } export function fromVsix(vsixPath: string, { name: extensionName, version, sha256, metadata }: IExtensionDefinition): Stream { const json = require('gulp-json-editor') as typeof import('gulp-json-editor'); fancyLog('Using local VSIX for extension:', ansiColors.yellow(`${extensionName}@${version}`), '...'); const packageJsonFilter = filter('package.json', { restore: true }); return gulp.src(vsixPath) .pipe(buffer()) .pipe(es.mapSync((f: File) => { const hash = crypto.createHash('sha256'); hash.update(f.contents as Buffer); const checksum = hash.digest('hex'); if (checksum !== sha256) { throw new Error(`Checksum mismatch for ${vsixPath} (expected ${sha256}, actual ${checksum}))`); } return f; })) .pipe(vzip.src()) .pipe(filter('extension/**')) .pipe(rename(p => p.dirname = p.dirname!.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe(buffer()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } export function fromGithub({ name, version, repo, sha256, metadata }: IExtensionDefinition): Stream { const json = require('gulp-json-editor') as typeof import('gulp-json-editor'); fancyLog('Downloading extension from GH:', ansiColors.yellow(`${name}@${version}`), '...'); const packageJsonFilter = filter('package.json', { restore: true }); return fetchGithub(new URL(repo).pathname, { version, name: name => name.endsWith('.vsix'), checksumSha256: sha256 }) .pipe(buffer()) .pipe(vzip.src()) .pipe(filter('extension/**')) .pipe(rename(p => p.dirname = p.dirname!.replace(/^extension\/?/, ''))) .pipe(packageJsonFilter) .pipe(buffer()) .pipe(json({ __metadata: metadata })) .pipe(packageJsonFilter.restore); } /** * All extensions that are known to have some native component and thus must be built on the * platform that is being built. */ const nativeExtensions = [ 'microsoft-authentication', ]; const excludedExtensions = [ 'vscode-api-tests', 'vscode-colorize-tests', 'vscode-colorize-perf-tests', 'vscode-test-resolver', 'ms-vscode.node-debug', 'ms-vscode.node-debug2', ]; const marketplaceWebExtensionsExclude = new Set([ 'ms-vscode.node-debug', 'ms-vscode.node-debug2', 'ms-vscode.js-debug-companion', 'ms-vscode.js-debug', 'ms-vscode.vscode-js-profile-table' ]); const productJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8')); const builtInExtensions: IExtensionDefinition[] = productJson.builtInExtensions || []; const webBuiltInExtensions: IExtensionDefinition[] = productJson.webBuiltInExtensions || []; type ExtensionKind = 'ui' | 'workspace' | 'web'; interface IExtensionManifest { main?: string; browser?: string; extensionKind?: ExtensionKind | ExtensionKind[]; extensionPack?: string[]; extensionDependencies?: string[]; contributes?: { [id: string]: any }; } /** * Loosely based on `getExtensionKind` from `src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts` */ function isWebExtension(manifest: IExtensionManifest): boolean { if (Boolean(manifest.browser)) { return true; } if (Boolean(manifest.main)) { return false; } // neither browser nor main if (typeof manifest.extensionKind !== 'undefined') { const extensionKind = Array.isArray(manifest.extensionKind) ? manifest.extensionKind : [manifest.extensionKind]; if (extensionKind.indexOf('web') >= 0) { return true; } } if (typeof manifest.contributes !== 'undefined') { for (const id of ['debuggers', 'terminal', 'typescriptServerPlugins']) { if (manifest.contributes.hasOwnProperty(id)) { return false; } } } return true; } /** * Package local extensions that are known to not have native dependencies. Mutually exclusive to {@link packageNativeLocalExtensionsStream}. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ export function packageNonNativeLocalExtensionsStream(forWeb: boolean, disableMangle: boolean): Stream { return doPackageLocalExtensionsStream(forWeb, disableMangle, false); } /** * Package local extensions that are known to have native dependencies. Mutually exclusive to {@link packageNonNativeLocalExtensionsStream}. * @note it's possible that the extension does not have native dependencies for the current platform, especially if building for the web, * but we simplify the logic here by having a flat list of extensions (See {@link nativeExtensions}) that are known to have native * dependencies on some platform and thus should be packaged on the platform that they are building for. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ export function packageNativeLocalExtensionsStream(forWeb: boolean, disableMangle: boolean): Stream { return doPackageLocalExtensionsStream(forWeb, disableMangle, true); } /** * Package all the local extensions... both those that are known to have native dependencies and those that are not. * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @returns a stream */ export function packageAllLocalExtensionsStream(forWeb: boolean, disableMangle: boolean): Stream { return es.merge([ packageNonNativeLocalExtensionsStream(forWeb, disableMangle), packageNativeLocalExtensionsStream(forWeb, disableMangle) ]); } /** * @param forWeb build the extensions that have web targets * @param disableMangle disable the mangler * @param native build the extensions that are marked as having native dependencies */ function doPackageLocalExtensionsStream(forWeb: boolean, disableMangle: boolean, native: boolean): Stream { const nativeExtensionsSet = new Set(nativeExtensions); const localExtensionsDescriptions = ( (glob.sync('extensions/*/package.json')) .map(manifestPath => { const absoluteManifestPath = path.join(root, manifestPath); const extensionPath = path.dirname(path.join(root, manifestPath)); const extensionName = path.basename(extensionPath); return { name: extensionName, path: extensionPath, manifestPath: absoluteManifestPath }; }) .filter(({ name }) => native ? nativeExtensionsSet.has(name) : !nativeExtensionsSet.has(name)) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)) .filter(({ manifestPath }) => (forWeb ? isWebExtension(require(manifestPath)) : true)) ); const localExtensionsStream = minifyExtensionResources( es.merge( ...localExtensionsDescriptions.map(extension => { return fromLocal(extension.path, forWeb, disableMangle) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); }) ) ); let result: Stream; if (forWeb) { result = localExtensionsStream; } else { // also include shared production node modules const productionDependencies = getProductionDependencies('extensions/'); const dependenciesSrc = productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat(); result = es.merge( localExtensionsStream, gulp.src(dependenciesSrc, { base: '.' }) .pipe(util2.cleanNodeModules(path.join(root, 'build', '.moduleignore'))) .pipe(util2.cleanNodeModules(path.join(root, 'build', `.moduleignore.${process.platform}`)))); } return ( result .pipe(util2.setExecutableBit(['**/*.sh'])) ); } export function packageMarketplaceExtensionsStream(forWeb: boolean): Stream { const marketplaceExtensionsDescriptions = [ ...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)), ...(forWeb ? webBuiltInExtensions : []) ]; const marketplaceExtensionsStream = minifyExtensionResources( es.merge( ...marketplaceExtensionsDescriptions .map(extension => { const src = getExtensionStream(extension).pipe(rename(p => p.dirname = `extensions/${p.dirname}`)); return updateExtensionPackageJSON(src, (data: any) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; return data; }); }) ) ); return ( marketplaceExtensionsStream .pipe(util2.setExecutableBit(['**/*.sh'])) ); } export interface IScannedBuiltinExtension { extensionPath: string; packageJSON: any; packageNLS?: any; readmePath?: string; changelogPath?: string; } export function scanBuiltinExtensions(extensionsRoot: string, exclude: string[] = []): IScannedBuiltinExtension[] { const scannedExtensions: IScannedBuiltinExtension[] = []; try { const extensionsFolders = fs.readdirSync(extensionsRoot); for (const extensionFolder of extensionsFolders) { if (exclude.indexOf(extensionFolder) >= 0) { continue; } const packageJSONPath = path.join(extensionsRoot, extensionFolder, 'package.json'); if (!fs.existsSync(packageJSONPath)) { continue; } const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); if (!isWebExtension(packageJSON)) { continue; } const children = fs.readdirSync(path.join(extensionsRoot, extensionFolder)); const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(extensionsRoot, extensionFolder, packageNLSPath)).toString()) : undefined; const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; scannedExtensions.push({ extensionPath: extensionFolder, packageJSON, packageNLS, readmePath: readme ? path.join(extensionFolder, readme) : undefined, changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined, }); } return scannedExtensions; } catch (ex) { return scannedExtensions; } } export function translatePackageJSON(packageJSON: string, packageNLSPath: string) { interface NLSFormat { [key: string]: string | { message: string; comment: string[] }; } const CharCode_PC = '%'.charCodeAt(0); const packageNls: NLSFormat = JSON.parse(fs.readFileSync(packageNLSPath).toString()); const translate = (obj: any) => { for (const key in obj) { const val = obj[key]; if (Array.isArray(val)) { val.forEach(translate); } else if (val && typeof val === 'object') { translate(val); } else if (typeof val === 'string' && val.charCodeAt(0) === CharCode_PC && val.charCodeAt(val.length - 1) === CharCode_PC) { const translated = packageNls[val.substr(1, val.length - 2)]; if (translated) { obj[key] = typeof translated === 'string' ? translated : (typeof translated.message === 'string' ? translated.message : val); } } } }; translate(packageJSON); return packageJSON; } const extensionsPath = path.join(root, 'extensions'); // Additional projects to run esbuild on. These typically build code for webviews const esbuildMediaScripts = [ 'markdown-language-features/esbuild-notebook.js', 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; export async function webpackExtensions(taskName: string, isWatch: boolean, webpackConfigLocations: { configPath: string; outputRoot?: string }[]) { const webpack = require('webpack') as typeof import('webpack'); const webpackConfigs: webpack.Configuration[] = []; for (const { configPath, outputRoot } of webpackConfigLocations) { const configOrFnOrArray = require(configPath); function addConfig(configOrFnOrArray: webpack.Configuration | ((env: unknown, args: unknown) => webpack.Configuration) | webpack.Configuration[]) { for (const configOrFn of Array.isArray(configOrFnOrArray) ? configOrFnOrArray : [configOrFnOrArray]) { const config = typeof configOrFn === 'function' ? configOrFn({}, {}) : configOrFn; if (outputRoot) { config.output!.path = path.join(outputRoot, path.relative(path.dirname(configPath), config.output!.path!)); } webpackConfigs.push(config); } } addConfig(configOrFnOrArray); } function reporter(fullStats: any) { if (Array.isArray(fullStats.children)) { for (const stats of fullStats.children) { const outputPath = stats.outputPath; if (outputPath) { const relativePath = path.relative(extensionsPath, outputPath).replace(/\\/g, '/'); const match = relativePath.match(/[^\/]+(\/server|\/client)?/); fancyLog(`Finished ${ansiColors.green(taskName)} ${ansiColors.cyan(match![0])} with ${stats.errors.length} errors.`); } if (Array.isArray(stats.errors)) { stats.errors.forEach((error: any) => { fancyLog.error(error); }); } if (Array.isArray(stats.warnings)) { stats.warnings.forEach((warning: any) => { fancyLog.warn(warning); }); } } } } return new Promise((resolve, reject) => { if (isWatch) { webpack(webpackConfigs).watch({}, (err, stats) => { if (err) { reject(); } else { reporter(stats?.toJson()); } }); } else { webpack(webpackConfigs).run((err, stats) => { if (err) { fancyLog.error(err); reject(); } else { reporter(stats?.toJson()); resolve(); } }); } }); } async function esbuildExtensions(taskName: string, isWatch: boolean, scripts: { script: string; outputRoot?: string }[]) { function reporter(stdError: string, script: string) { const matches = (stdError || '').match(/\> (.+): error: (.+)?/g); fancyLog(`Finished ${ansiColors.green(taskName)} ${script} with ${matches ? matches.length : 0} errors.`); for (const match of matches || []) { fancyLog.error(match); } } const tasks = scripts.map(({ script, outputRoot }) => { return new Promise((resolve, reject) => { const args = [script]; if (isWatch) { args.push('--watch'); } if (outputRoot) { args.push('--outputRoot', outputRoot); } const proc = cp.execFile(process.argv[0], args, {}, (error, _stdout, stderr) => { if (error) { return reject(error); } reporter(stderr, script); return resolve(); }); proc.stdout!.on('data', (data) => { fancyLog(`${ansiColors.green(taskName)}: ${data.toString('utf8')}`); }); }); }); return Promise.all(tasks); } export async function buildExtensionMedia(isWatch: boolean, outputRoot?: string) { return esbuildExtensions('esbuilding extension media', isWatch, esbuildMediaScripts.map(p => ({ script: path.join(extensionsPath, p), outputRoot: outputRoot ? path.join(root, outputRoot, path.dirname(p)) : undefined }))); } ================================================ FILE: build/lib/fetch.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchUrls = fetchUrls; exports.fetchUrl = fetchUrl; exports.fetchGithub = fetchGithub; const event_stream_1 = __importDefault(require("event-stream")); const vinyl_1 = __importDefault(require("vinyl")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const crypto_1 = __importDefault(require("crypto")); const through2_1 = __importDefault(require("through2")); function fetchUrls(urls, options) { if (options === undefined) { options = {}; } if (typeof options.base !== 'string' && options.base !== null) { options.base = '/'; } if (!Array.isArray(urls)) { urls = [urls]; } return event_stream_1.default.readArray(urls).pipe(event_stream_1.default.map((data, cb) => { const url = [options.base, data].join(''); fetchUrl(url, options).then(file => { cb(undefined, file); }, error => { cb(error); }); })); } async function fetchUrl(url, options, retries = 10, retryDelay = 1000) { const verbose = !!options.verbose || !!process.env['CI'] || !!process.env['BUILD_ARTIFACTSTAGINGDIRECTORY']; try { let startTime = 0; if (verbose) { (0, fancy_log_1.default)(`Start fetching ${ansi_colors_1.default.magenta(url)}${retries !== 10 ? ` (${10 - retries} retry)` : ''}`); startTime = new Date().getTime(); } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 30 * 1000); try { const response = await fetch(url, { ...options.nodeFetchOptions, signal: controller.signal /* Typings issue with lib.dom.d.ts */ }); if (verbose) { (0, fancy_log_1.default)(`Fetch completed: Status ${response.status}. Took ${ansi_colors_1.default.magenta(`${new Date().getTime() - startTime} ms`)}`); } if (response.ok && (response.status >= 200 && response.status < 300)) { const contents = Buffer.from(await response.arrayBuffer()); if (options.checksumSha256) { const actualSHA256Checksum = crypto_1.default.createHash('sha256').update(contents).digest('hex'); if (actualSHA256Checksum !== options.checksumSha256) { throw new Error(`Checksum mismatch for ${ansi_colors_1.default.cyan(url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); } else if (verbose) { (0, fancy_log_1.default)(`Verified SHA256 checksums match for ${ansi_colors_1.default.cyan(url)}`); } } else if (verbose) { (0, fancy_log_1.default)(`Skipping checksum verification for ${ansi_colors_1.default.cyan(url)} because no expected checksum was provided`); } if (verbose) { (0, fancy_log_1.default)(`Fetched response body buffer: ${ansi_colors_1.default.magenta(`${contents.byteLength} bytes`)}`); } return new vinyl_1.default({ cwd: '/', base: options.base, path: url, contents }); } let err = `Request ${ansi_colors_1.default.magenta(url)} failed with status code: ${response.status}`; if (response.status === 403) { err += ' (you may be rate limited)'; } throw new Error(err); } finally { clearTimeout(timeout); } } catch (e) { if (verbose) { (0, fancy_log_1.default)(`Fetching ${ansi_colors_1.default.cyan(url)} failed: ${e}`); } if (retries > 0) { await new Promise(resolve => setTimeout(resolve, retryDelay)); return fetchUrl(url, options, retries - 1, retryDelay); } throw e; } } const ghApiHeaders = { Accept: 'application/vnd.github.v3+json', 'User-Agent': 'VSCode Build', }; if (process.env.GITHUB_TOKEN) { ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); } const ghDownloadHeaders = { ...ghApiHeaders, Accept: 'application/octet-stream', }; /** * @param repo for example `Microsoft/vscode` * @param version for example `16.17.1` - must be a valid releases tag * @param assetName for example (name) => name === `win-x64-node.exe` - must be an asset that exists * @returns a stream with the asset as file */ function fetchGithub(repo, options) { return fetchUrls(`/repos/${repo.replace(/^\/|\/$/g, '')}/releases/tags/v${options.version}`, { base: 'https://api.github.com', verbose: options.verbose, nodeFetchOptions: { headers: ghApiHeaders } }).pipe(through2_1.default.obj(async function (file, _enc, callback) { const assetFilter = typeof options.name === 'string' ? (name) => name === options.name : options.name; const asset = JSON.parse(file.contents.toString()).assets.find((a) => assetFilter(a.name)); if (!asset) { return callback(new Error(`Could not find asset in release of ${repo} @ ${options.version}`)); } try { callback(null, await fetchUrl(asset.url, { nodeFetchOptions: { headers: ghDownloadHeaders }, verbose: options.verbose, checksumSha256: options.checksumSha256 })); } catch (error) { callback(error); } })); } //# sourceMappingURL=fetch.js.map ================================================ FILE: build/lib/fetch.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import VinylFile from 'vinyl'; import log from 'fancy-log'; import ansiColors from 'ansi-colors'; import crypto from 'crypto'; import through2 from 'through2'; import { Stream } from 'stream'; export interface IFetchOptions { base?: string; nodeFetchOptions?: RequestInit; verbose?: boolean; checksumSha256?: string; } export function fetchUrls(urls: string[] | string, options: IFetchOptions): es.ThroughStream { if (options === undefined) { options = {}; } if (typeof options.base !== 'string' && options.base !== null) { options.base = '/'; } if (!Array.isArray(urls)) { urls = [urls]; } return es.readArray(urls).pipe(es.map((data: string, cb) => { const url = [options.base, data].join(''); fetchUrl(url, options).then(file => { cb(undefined, file); }, error => { cb(error); }); })); } export async function fetchUrl(url: string, options: IFetchOptions, retries = 10, retryDelay = 1000): Promise { const verbose = !!options.verbose || !!process.env['CI'] || !!process.env['BUILD_ARTIFACTSTAGINGDIRECTORY']; try { let startTime = 0; if (verbose) { log(`Start fetching ${ansiColors.magenta(url)}${retries !== 10 ? ` (${10 - retries} retry)` : ''}`); startTime = new Date().getTime(); } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 30 * 1000); try { const response = await fetch(url, { ...options.nodeFetchOptions, signal: controller.signal as any /* Typings issue with lib.dom.d.ts */ }); if (verbose) { log(`Fetch completed: Status ${response.status}. Took ${ansiColors.magenta(`${new Date().getTime() - startTime} ms`)}`); } if (response.ok && (response.status >= 200 && response.status < 300)) { const contents = Buffer.from(await response.arrayBuffer()); if (options.checksumSha256) { const actualSHA256Checksum = crypto.createHash('sha256').update(contents).digest('hex'); if (actualSHA256Checksum !== options.checksumSha256) { throw new Error(`Checksum mismatch for ${ansiColors.cyan(url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); } else if (verbose) { log(`Verified SHA256 checksums match for ${ansiColors.cyan(url)}`); } } else if (verbose) { log(`Skipping checksum verification for ${ansiColors.cyan(url)} because no expected checksum was provided`); } if (verbose) { log(`Fetched response body buffer: ${ansiColors.magenta(`${(contents as Buffer).byteLength} bytes`)}`); } return new VinylFile({ cwd: '/', base: options.base, path: url, contents }); } let err = `Request ${ansiColors.magenta(url)} failed with status code: ${response.status}`; if (response.status === 403) { err += ' (you may be rate limited)'; } throw new Error(err); } finally { clearTimeout(timeout); } } catch (e) { if (verbose) { log(`Fetching ${ansiColors.cyan(url)} failed: ${e}`); } if (retries > 0) { await new Promise(resolve => setTimeout(resolve, retryDelay)); return fetchUrl(url, options, retries - 1, retryDelay); } throw e; } } const ghApiHeaders: Record = { Accept: 'application/vnd.github.v3+json', 'User-Agent': 'VSCode Build', }; if (process.env.GITHUB_TOKEN) { ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); } const ghDownloadHeaders = { ...ghApiHeaders, Accept: 'application/octet-stream', }; export interface IGitHubAssetOptions { version: string; name: string | ((name: string) => boolean); checksumSha256?: string; verbose?: boolean; } /** * @param repo for example `Microsoft/vscode` * @param version for example `16.17.1` - must be a valid releases tag * @param assetName for example (name) => name === `win-x64-node.exe` - must be an asset that exists * @returns a stream with the asset as file */ export function fetchGithub(repo: string, options: IGitHubAssetOptions): Stream { return fetchUrls(`/repos/${repo.replace(/^\/|\/$/g, '')}/releases/tags/v${options.version}`, { base: 'https://api.github.com', verbose: options.verbose, nodeFetchOptions: { headers: ghApiHeaders } }).pipe(through2.obj(async function (file, _enc, callback) { const assetFilter = typeof options.name === 'string' ? (name: string) => name === options.name : options.name; const asset = JSON.parse(file.contents.toString()).assets.find((a: { name: string }) => assetFilter(a.name)); if (!asset) { return callback(new Error(`Could not find asset in release of ${repo} @ ${options.version}`)); } try { callback(null, await fetchUrl(asset.url, { nodeFetchOptions: { headers: ghDownloadHeaders }, verbose: options.verbose, checksumSha256: options.checksumSha256 })); } catch (error) { callback(error); } })); } ================================================ FILE: build/lib/formatter.js ================================================ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.format = format; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const typescript_1 = __importDefault(require("typescript")); class LanguageServiceHost { files = {}; addFile(fileName, text) { this.files[fileName] = typescript_1.default.ScriptSnapshot.fromString(text); } fileExists(path) { return !!this.files[path]; } readFile(path) { return this.files[path]?.getText(0, this.files[path].getLength()); } // for ts.LanguageServiceHost getCompilationSettings = () => typescript_1.default.getDefaultCompilerOptions(); getScriptFileNames = () => Object.keys(this.files); getScriptVersion = (_fileName) => '0'; getScriptSnapshot = (fileName) => this.files[fileName]; getCurrentDirectory = () => process.cwd(); getDefaultLibFileName = (options) => typescript_1.default.getDefaultLibFilePath(options); } const defaults = { baseIndentSize: 0, indentSize: 4, tabSize: 4, indentStyle: typescript_1.default.IndentStyle.Smart, newLineCharacter: '\r\n', convertTabsToSpaces: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, insertSpaceAfterConstructor: false, insertSpaceAfterKeywordsInControlFlowStatements: true, insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceAfterTypeAssertion: false, insertSpaceBeforeFunctionParenthesis: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, insertSpaceBeforeTypeAnnotation: false, }; const getOverrides = (() => { let value; return () => { value ??= JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '..', '..', 'tsfmt.json'), 'utf8')); return value; }; })(); function format(fileName, text) { const host = new LanguageServiceHost(); host.addFile(fileName, text); const languageService = typescript_1.default.createLanguageService(host); const edits = languageService.getFormattingEditsForDocument(fileName, { ...defaults, ...getOverrides() }); edits .sort((a, b) => a.span.start - b.span.start) .reverse() .forEach(edit => { const head = text.slice(0, edit.span.start); const tail = text.slice(edit.span.start + edit.span.length); text = `${head}${edit.newText}${tail}`; }); return text; } //# sourceMappingURL=formatter.js.map ================================================ FILE: build/lib/formatter.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import ts from 'typescript'; class LanguageServiceHost implements ts.LanguageServiceHost { files: ts.MapLike = {}; addFile(fileName: string, text: string) { this.files[fileName] = ts.ScriptSnapshot.fromString(text); } fileExists(path: string): boolean { return !!this.files[path]; } readFile(path: string): string | undefined { return this.files[path]?.getText(0, this.files[path]!.getLength()); } // for ts.LanguageServiceHost getCompilationSettings = () => ts.getDefaultCompilerOptions(); getScriptFileNames = () => Object.keys(this.files); getScriptVersion = (_fileName: string) => '0'; getScriptSnapshot = (fileName: string) => this.files[fileName]; getCurrentDirectory = () => process.cwd(); getDefaultLibFileName = (options: ts.CompilerOptions) => ts.getDefaultLibFilePath(options); } const defaults: ts.FormatCodeSettings = { baseIndentSize: 0, indentSize: 4, tabSize: 4, indentStyle: ts.IndentStyle.Smart, newLineCharacter: '\r\n', convertTabsToSpaces: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, insertSpaceAfterConstructor: false, insertSpaceAfterKeywordsInControlFlowStatements: true, insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceAfterTypeAssertion: false, insertSpaceBeforeFunctionParenthesis: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, insertSpaceBeforeTypeAnnotation: false, }; const getOverrides = (() => { let value: ts.FormatCodeSettings | undefined; return () => { value ??= JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'tsfmt.json'), 'utf8')); return value; }; })(); export function format(fileName: string, text: string) { const host = new LanguageServiceHost(); host.addFile(fileName, text); const languageService = ts.createLanguageService(host); const edits = languageService.getFormattingEditsForDocument(fileName, { ...defaults, ...getOverrides() }); edits .sort((a, b) => a.span.start - b.span.start) .reverse() .forEach(edit => { const head = text.slice(0, edit.span.start); const tail = text.slice(edit.span.start + edit.span.length); text = `${head}${edit.newText}${tail}`; }); return text; } ================================================ FILE: build/lib/getVersion.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.getVersion = getVersion; const git = __importStar(require("./git")); function getVersion(root) { let version = process.env['BUILD_SOURCEVERSION']; if (!version || !/^[0-9a-f]{40}$/i.test(version.trim())) { version = git.getVersion(root); } return version; } //# sourceMappingURL=getVersion.js.map ================================================ FILE: build/lib/getVersion.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as git from './git'; export function getVersion(root: string): string | undefined { let version = process.env['BUILD_SOURCEVERSION']; if (!version || !/^[0-9a-f]{40}$/i.test(version.trim())) { version = git.getVersion(root); } return version; } ================================================ FILE: build/lib/git.js ================================================ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVersion = getVersion; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); /** * Returns the sha1 commit version of a repository or undefined in case of failure. */ function getVersion(repo) { const git = path_1.default.join(repo, '.git'); const headPath = path_1.default.join(git, 'HEAD'); let head; try { head = fs_1.default.readFileSync(headPath, 'utf8').trim(); } catch (e) { return undefined; } if (/^[0-9a-f]{40}$/i.test(head)) { return head; } const refMatch = /^ref: (.*)$/.exec(head); if (!refMatch) { return undefined; } const ref = refMatch[1]; const refPath = path_1.default.join(git, ref); try { return fs_1.default.readFileSync(refPath, 'utf8').trim(); } catch (e) { // noop } const packedRefsPath = path_1.default.join(git, 'packed-refs'); let refsRaw; try { refsRaw = fs_1.default.readFileSync(packedRefsPath, 'utf8').trim(); } catch (e) { return undefined; } const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; let refsMatch; const refs = {}; while (refsMatch = refsRegex.exec(refsRaw)) { refs[refsMatch[2]] = refsMatch[1]; } return refs[ref]; } //# sourceMappingURL=git.js.map ================================================ FILE: build/lib/git.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import fs from 'fs'; /** * Returns the sha1 commit version of a repository or undefined in case of failure. */ export function getVersion(repo: string): string | undefined { const git = path.join(repo, '.git'); const headPath = path.join(git, 'HEAD'); let head: string; try { head = fs.readFileSync(headPath, 'utf8').trim(); } catch (e) { return undefined; } if (/^[0-9a-f]{40}$/i.test(head)) { return head; } const refMatch = /^ref: (.*)$/.exec(head); if (!refMatch) { return undefined; } const ref = refMatch[1]; const refPath = path.join(git, ref); try { return fs.readFileSync(refPath, 'utf8').trim(); } catch (e) { // noop } const packedRefsPath = path.join(git, 'packed-refs'); let refsRaw: string; try { refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim(); } catch (e) { return undefined; } const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; let refsMatch: RegExpExecArray | null; const refs: { [ref: string]: string } = {}; while (refsMatch = refsRegex.exec(refsRaw)) { refs[refsMatch[2]] = refsMatch[1]; } return refs[ref]; } ================================================ FILE: build/lib/i18n.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EXTERNAL_EXTENSIONS = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0; exports.processNlsFiles = processNlsFiles; exports.getResource = getResource; exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle; exports.createXlfFilesForExtensions = createXlfFilesForExtensions; exports.createXlfFilesForIsl = createXlfFilesForIsl; exports.prepareI18nPackFiles = prepareI18nPackFiles; exports.prepareIslFiles = prepareIslFiles; const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const event_stream_1 = require("event-stream"); const gulp_merge_json_1 = __importDefault(require("gulp-merge-json")); const vinyl_1 = __importDefault(require("vinyl")); const xml2js_1 = __importDefault(require("xml2js")); const gulp_1 = __importDefault(require("gulp")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const iconv_lite_umd_1 = __importDefault(require("@vscode/iconv-lite-umd")); const l10n_dev_1 = require("@vscode/l10n-dev"); const REPO_ROOT_PATH = path_1.default.join(__dirname, '../..'); function log(message, ...rest) { (0, fancy_log_1.default)(ansi_colors_1.default.green('[i18n]'), message, ...rest); } exports.defaultLanguages = [ { id: 'zh-tw', folderName: 'cht', translationId: 'zh-hant' }, { id: 'zh-cn', folderName: 'chs', translationId: 'zh-hans' }, { id: 'ja', folderName: 'jpn' }, { id: 'ko', folderName: 'kor' }, { id: 'de', folderName: 'deu' }, { id: 'fr', folderName: 'fra' }, { id: 'es', folderName: 'esn' }, { id: 'ru', folderName: 'rus' }, { id: 'it', folderName: 'ita' } ]; // languages requested by the community to non-stable builds exports.extraLanguages = [ { id: 'pt-br', folderName: 'ptb' }, { id: 'hu', folderName: 'hun' }, { id: 'tr', folderName: 'trk' } ]; var LocalizeInfo; (function (LocalizeInfo) { function is(value) { const candidate = value; return candidate && typeof candidate.key === 'string' && (candidate.comment === undefined || (Array.isArray(candidate.comment) && candidate.comment.every(element => typeof element === 'string'))); } LocalizeInfo.is = is; })(LocalizeInfo || (LocalizeInfo = {})); var BundledFormat; (function (BundledFormat) { function is(value) { if (value === undefined) { return false; } const candidate = value; const length = Object.keys(value).length; return length === 3 && !!candidate.keys && !!candidate.messages && !!candidate.bundles; } BundledFormat.is = is; })(BundledFormat || (BundledFormat = {})); var NLSKeysFormat; (function (NLSKeysFormat) { function is(value) { if (value === undefined) { return false; } const candidate = value; return Array.isArray(candidate) && Array.isArray(candidate[1]); } NLSKeysFormat.is = is; })(NLSKeysFormat || (NLSKeysFormat = {})); class Line { buffer = []; constructor(indent = 0) { if (indent > 0) { this.buffer.push(new Array(indent + 1).join(' ')); } } append(value) { this.buffer.push(value); return this; } toString() { return this.buffer.join(''); } } exports.Line = Line; class TextModel { _lines; constructor(contents) { this._lines = contents.split(/\r\n|\r|\n/); } get lines() { return this._lines; } } class XLF { project; buffer; files; numberOfMessages; constructor(project) { this.project = project; this.buffer = []; this.files = Object.create(null); this.numberOfMessages = 0; } toString() { this.appendHeader(); const files = Object.keys(this.files).sort(); for (const file of files) { this.appendNewLine(``, 2); const items = this.files[file].sort((a, b) => { return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; }); for (const item of items) { this.addStringItem(file, item); } this.appendNewLine(''); } this.appendFooter(); return this.buffer.join('\r\n'); } addFile(original, keys, messages) { if (keys.length === 0) { console.log('No keys in ' + original); return; } if (keys.length !== messages.length) { throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`); } this.numberOfMessages += keys.length; this.files[original] = []; const existingKeys = new Set(); for (let i = 0; i < keys.length; i++) { const key = keys[i]; let realKey; let comment; if (typeof key === 'string') { realKey = key; comment = undefined; } else if (LocalizeInfo.is(key)) { realKey = key.key; if (key.comment && key.comment.length > 0) { comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n'); } } if (!realKey || existingKeys.has(realKey)) { continue; } existingKeys.add(realKey); const message = encodeEntities(messages[i]); this.files[original].push({ id: realKey, message: message, comment: comment }); } } addStringItem(file, item) { if (!item.id || item.message === undefined || item.message === null) { throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`); } if (item.message.length === 0) { log(`Item with id ${item.id} in file ${file} has an empty message.`); } this.appendNewLine(``, 4); this.appendNewLine(`${item.message}`, 6); if (item.comment) { this.appendNewLine(`${item.comment}`, 6); } this.appendNewLine('', 4); } appendHeader() { this.appendNewLine('', 0); this.appendNewLine('', 0); } appendFooter() { this.appendNewLine('', 0); } appendNewLine(content, indent) { const line = new Line(indent); line.append(content); this.buffer.push(line.toString()); } static parse = function (xlfString) { return new Promise((resolve, reject) => { const parser = new xml2js_1.default.Parser(); const files = []; parser.parseString(xlfString, function (err, result) { if (err) { reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`)); } const fileNodes = result['xliff']['file']; if (!fileNodes) { reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`)); } fileNodes.forEach((file) => { const name = file.$.original; if (!name) { reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); } const language = file.$['target-language']; if (!language) { reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); } const messages = {}; const transUnits = file.body[0]['trans-unit']; if (transUnits) { transUnits.forEach((unit) => { const key = unit.$.id; if (!unit.target) { return; // No translation available } let val = unit.target[0]; if (typeof val !== 'string') { // We allow empty source values so support them for translations as well. val = val._ ? val._ : ''; } if (!key) { reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`)); return; } messages[key] = decodeEntities(val); }); files.push({ messages, name, language: language.toLowerCase() }); } }); resolve(files); }); }); }; } exports.XLF = XLF; function sortLanguages(languages) { return languages.sort((a, b) => { return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0); }); } function stripComments(content) { // Copied from stripComments.js // // First group matches a double quoted string // Second group matches a single quoted string // Third group matches a multi line comment // Forth group matches a single line comment // Fifth group matches a trailing comma const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))|(,\s*[}\]])/g; const result = content.replace(regexp, (match, _m1, _m2, m3, m4, m5) => { // Only one of m1, m2, m3, m4, m5 matches if (m3) { // A block comment. Replace with nothing return ''; } else if (m4) { // Since m4 is a single line comment is is at least of length 2 (e.g. //) // If it ends in \r?\n then keep it. const length = m4.length; if (m4[length - 1] === '\n') { return m4[length - 2] === '\r' ? '\r\n' : '\n'; } else { return ''; } } else if (m5) { // Remove the trailing comma return match.substring(1); } else { // We match a string return match; } }); return result; } function processCoreBundleFormat(base, fileHeader, languages, json, emitter) { const languageDirectory = path_1.default.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); if (!fs_1.default.existsSync(languageDirectory)) { log(`No VS Code localization repository found. Looking at ${languageDirectory}`); log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); } const sortedLanguages = sortLanguages(languages); sortedLanguages.forEach((language) => { if (process.env['VSCODE_BUILD_VERBOSE']) { log(`Generating nls bundles for: ${language.id}`); } const languageFolderName = language.translationId || language.id; const i18nFile = path_1.default.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); let allMessages; if (fs_1.default.existsSync(i18nFile)) { const content = stripComments(fs_1.default.readFileSync(i18nFile, 'utf8')); allMessages = JSON.parse(content); } let nlsIndex = 0; const nlsResult = []; for (const [moduleId, nlsKeys] of json) { const moduleTranslations = allMessages?.contents[moduleId]; for (const nlsKey of nlsKeys) { nlsResult.push(moduleTranslations?.[nlsKey]); // pushing `undefined` is fine, as we keep english strings as fallback for monaco editor in the build nlsIndex++; } } emitter.queue(new vinyl_1.default({ contents: Buffer.from(`${fileHeader} globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(nlsResult)}; globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), base, path: `${base}/nls.messages.${language.id}.js` })); }); } function processNlsFiles(opts) { return (0, event_stream_1.through)(function (file) { const fileName = path_1.default.basename(file.path); if (fileName === 'nls.keys.json') { try { const contents = file.contents.toString('utf8'); const json = JSON.parse(contents); if (NLSKeysFormat.is(json)) { processCoreBundleFormat(file.base, opts.fileHeader, opts.languages, json, this); } } catch (error) { this.emit('error', `Failed to read component file: ${error}`); } } this.queue(file); }); } const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench', extensionsProject = 'vscode-extensions', setupProject = 'vscode-setup', serverProject = 'vscode-server'; function getResource(sourceFile) { let resource; if (/^vs\/platform/.test(sourceFile)) { return { name: 'vs/platform', project: editorProject }; } else if (/^vs\/editor\/contrib/.test(sourceFile)) { return { name: 'vs/editor/contrib', project: editorProject }; } else if (/^vs\/editor/.test(sourceFile)) { return { name: 'vs/editor', project: editorProject }; } else if (/^vs\/base/.test(sourceFile)) { return { name: 'vs/base', project: editorProject }; } else if (/^vs\/code/.test(sourceFile)) { return { name: 'vs/code', project: workbenchProject }; } else if (/^vs\/server/.test(sourceFile)) { return { name: 'vs/server', project: serverProject }; } else if (/^vs\/workbench\/contrib/.test(sourceFile)) { resource = sourceFile.split('/', 4).join('/'); return { name: resource, project: workbenchProject }; } else if (/^vs\/workbench\/services/.test(sourceFile)) { resource = sourceFile.split('/', 4).join('/'); return { name: resource, project: workbenchProject }; } else if (/^vs\/workbench/.test(sourceFile)) { return { name: 'vs/workbench', project: workbenchProject }; } throw new Error(`Could not identify the XLF bundle for ${sourceFile}`); } function createXlfFilesForCoreBundle() { return (0, event_stream_1.through)(function (file) { const basename = path_1.default.basename(file.path); if (basename === 'nls.metadata.json') { if (file.isBuffer()) { const xlfs = Object.create(null); const json = JSON.parse(file.contents.toString('utf8')); for (const coreModule in json.keys) { const projectResource = getResource(coreModule); const resource = projectResource.name; const project = projectResource.project; const keys = json.keys[coreModule]; const messages = json.messages[coreModule]; if (keys.length !== messages.length) { this.emit('error', `There is a mismatch between keys and messages in ${file.relative} for module ${coreModule}`); return; } else { let xlf = xlfs[resource]; if (!xlf) { xlf = new XLF(project); xlfs[resource] = xlf; } xlf.addFile(`src/${coreModule}`, keys, messages); } } for (const resource in xlfs) { const xlf = xlfs[resource]; const filePath = `${xlf.project}/${resource.replace(/\//g, '_')}.xlf`; const xlfFile = new vinyl_1.default({ path: filePath, contents: Buffer.from(xlf.toString(), 'utf8') }); this.queue(xlfFile); } } else { this.emit('error', new Error(`File ${file.relative} is not using a buffer content`)); return; } } else { this.emit('error', new Error(`File ${file.relative} is not a core meta data file.`)); return; } }); } function createL10nBundleForExtension(extensionFolderName, prefixWithBuildFolder) { const prefix = prefixWithBuildFolder ? '.build/' : ''; return gulp_1.default .src([ // For source code of extensions `${prefix}extensions/${extensionFolderName}/{src,client,server}/**/*.{ts,tsx}`, // // For any dependencies pulled in (think vscode-css-languageservice or @vscode/emmet-helper) `${prefix}extensions/${extensionFolderName}/**/node_modules/{@vscode,vscode-*}/**/*.{js,jsx}`, // // For any dependencies pulled in that bundle @vscode/l10n. They needed to export the bundle `${prefix}extensions/${extensionFolderName}/**/bundle.l10n.json`, ]) .pipe((0, event_stream_1.map)(function (data, callback) { const file = data; if (!file.isBuffer()) { // Not a buffer so we drop it callback(); return; } const extension = path_1.default.extname(file.relative); if (extension !== '.json') { const contents = file.contents.toString('utf8'); (0, l10n_dev_1.getL10nJson)([{ contents, extension }]) .then((json) => { callback(undefined, new vinyl_1.default({ path: `extensions/${extensionFolderName}/bundle.l10n.json`, contents: Buffer.from(JSON.stringify(json), 'utf8') })); }) .catch((err) => { callback(new Error(`File ${file.relative} threw an error when parsing: ${err}`)); }); // signal pause? return false; } // for bundle.l10n.jsons let bundleJson; try { bundleJson = JSON.parse(file.contents.toString('utf8')); } catch (err) { callback(new Error(`File ${file.relative} threw an error when parsing: ${err}`)); return; } // some validation of the bundle.l10n.json format for (const key in bundleJson) { if (typeof bundleJson[key] !== 'string' && (typeof bundleJson[key].message !== 'string' || !Array.isArray(bundleJson[key].comment))) { callback(new Error(`Invalid bundle.l10n.json file. The value for key ${key} is not in the expected format.`)); return; } } callback(undefined, file); })) .pipe((0, gulp_merge_json_1.default)({ fileName: `extensions/${extensionFolderName}/bundle.l10n.json`, jsonSpace: '', concatArrays: true })); } exports.EXTERNAL_EXTENSIONS = [ 'ms-vscode.js-debug', 'ms-vscode.js-debug-companion', 'ms-vscode.vscode-js-profile-table', ]; function createXlfFilesForExtensions() { let counter = 0; let folderStreamEnded = false; let folderStreamEndEmitted = false; return (0, event_stream_1.through)(function (extensionFolder) { const folderStream = this; const stat = fs_1.default.statSync(extensionFolder.path); if (!stat.isDirectory()) { return; } const extensionFolderName = path_1.default.basename(extensionFolder.path); if (extensionFolderName === 'node_modules') { return; } // Get extension id and use that as the id const manifest = fs_1.default.readFileSync(path_1.default.join(extensionFolder.path, 'package.json'), 'utf-8'); const manifestJson = JSON.parse(manifest); const extensionId = manifestJson.publisher + '.' + manifestJson.name; counter++; let _l10nMap; function getL10nMap() { if (!_l10nMap) { _l10nMap = new Map(); } return _l10nMap; } (0, event_stream_1.merge)(gulp_1.default.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionFolderName, exports.EXTERNAL_EXTENSIONS.includes(extensionId))).pipe((0, event_stream_1.through)(function (file) { if (file.isBuffer()) { const buffer = file.contents; const basename = path_1.default.basename(file.path); if (basename === 'package.nls.json') { const json = JSON.parse(buffer.toString('utf8')); getL10nMap().set(`extensions/${extensionId}/package`, json); } else if (basename === 'nls.metadata.json') { const json = JSON.parse(buffer.toString('utf8')); const relPath = path_1.default.relative(`.build/extensions/${extensionFolderName}`, path_1.default.dirname(file.path)); for (const file in json) { const fileContent = json[file]; const info = Object.create(null); for (let i = 0; i < fileContent.messages.length; i++) { const message = fileContent.messages[i]; const { key, comment } = LocalizeInfo.is(fileContent.keys[i]) ? fileContent.keys[i] : { key: fileContent.keys[i], comment: undefined }; info[key] = comment ? { message, comment } : message; } getL10nMap().set(`extensions/${extensionId}/${relPath}/${file}`, info); } } else if (basename === 'bundle.l10n.json') { const json = JSON.parse(buffer.toString('utf8')); getL10nMap().set(`extensions/${extensionId}/bundle`, json); } else { this.emit('error', new Error(`${file.path} is not a valid extension nls file`)); return; } } }, function () { if (_l10nMap?.size > 0) { const xlfFile = new vinyl_1.default({ path: path_1.default.join(extensionsProject, extensionId + '.xlf'), contents: Buffer.from((0, l10n_dev_1.getL10nXlf)(_l10nMap), 'utf8') }); folderStream.queue(xlfFile); } this.queue(null); counter--; if (counter === 0 && folderStreamEnded && !folderStreamEndEmitted) { folderStreamEndEmitted = true; folderStream.queue(null); } })); }, function () { folderStreamEnded = true; if (counter === 0) { folderStreamEndEmitted = true; this.queue(null); } }); } function createXlfFilesForIsl() { return (0, event_stream_1.through)(function (file) { let projectName, resourceFile; if (path_1.default.basename(file.path) === 'messages.en.isl') { projectName = setupProject; resourceFile = 'messages.xlf'; } else { throw new Error(`Unknown input file ${file.path}`); } const xlf = new XLF(projectName), keys = [], messages = []; const model = new TextModel(file.contents.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { return; } const firstChar = line.charAt(0); switch (firstChar) { case ';': // Comment line; return; case '[': inMessageSection = '[Messages]' === line || '[CustomMessages]' === line; return; } if (!inMessageSection) { return; } const sections = line.split('='); if (sections.length !== 2) { throw new Error(`Badly formatted message found: ${line}`); } else { const key = sections[0]; const value = sections[1]; if (key.length > 0 && value.length > 0) { keys.push(key); messages.push(value); } } }); const originalPath = file.path.substring(file.cwd.length + 1, file.path.split('.')[0].length).replace(/\\/g, '/'); xlf.addFile(originalPath, keys, messages); // Emit only upon all ISL files combined into single XLF instance const newFilePath = path_1.default.join(projectName, resourceFile); const xlfFile = new vinyl_1.default({ path: newFilePath, contents: Buffer.from(xlf.toString(), 'utf-8') }); this.queue(xlfFile); }); } function createI18nFile(name, messages) { const result = Object.create(null); result[''] = [ '--------------------------------------------------------------------------------------------', 'Copyright (c) Microsoft Corporation. All rights reserved.', 'Licensed under the MIT License. See License.txt in the project root for license information.', '--------------------------------------------------------------------------------------------', 'Do not edit this file. It is machine generated.' ]; for (const key of Object.keys(messages)) { result[key] = messages[key]; } let content = JSON.stringify(result, null, '\t'); if (process.platform === 'win32') { content = content.replace(/\n/g, '\r\n'); } return new vinyl_1.default({ path: path_1.default.join(name + '.i18n.json'), contents: Buffer.from(content, 'utf8') }); } const i18nPackVersion = '1.0.0'; function getRecordFromL10nJsonFormat(l10nJsonFormat) { const record = {}; for (const key of Object.keys(l10nJsonFormat).sort()) { const value = l10nJsonFormat[key]; record[key] = typeof value === 'string' ? value : value.message; } return record; } function prepareI18nPackFiles(resultingTranslationPaths) { const parsePromises = []; const mainPack = { version: i18nPackVersion, contents: {} }; const extensionsPacks = {}; const errors = []; return (0, event_stream_1.through)(function (xlf) { let project = path_1.default.basename(path_1.default.dirname(path_1.default.dirname(xlf.relative))); // strip `-new` since vscode-extensions-loc uses the `-new` suffix to indicate that it's from the new loc pipeline const resource = path_1.default.basename(path_1.default.basename(xlf.relative, '.xlf'), '-new'); if (exports.EXTERNAL_EXTENSIONS.find(e => e === resource)) { project = extensionsProject; } const contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); const parsePromise = (0, l10n_dev_1.getL10nFilesFromXlf)(contents); parsePromises.push(parsePromise); parsePromise.then(resolvedFiles => { resolvedFiles.forEach(file => { const path = file.name; const firstSlash = path.indexOf('/'); if (project === extensionsProject) { // resource will be the extension id let extPack = extensionsPacks[resource]; if (!extPack) { extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} }; } // remove 'extensions/extensionId/' segment const secondSlash = path.indexOf('/', firstSlash + 1); extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); } else { mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); } }); }).catch(reason => { errors.push(reason); }); }, function () { Promise.all(parsePromises) .then(() => { if (errors.length > 0) { throw errors; } const translatedMainFile = createI18nFile('./main', mainPack); resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); this.queue(translatedMainFile); for (const extensionId in extensionsPacks) { const translatedExtFile = createI18nFile(`extensions/${extensionId}`, extensionsPacks[extensionId]); this.queue(translatedExtFile); resultingTranslationPaths.push({ id: extensionId, resourceName: `extensions/${extensionId}.i18n.json` }); } this.queue(null); }) .catch((reason) => { this.emit('error', reason); }); }); } function prepareIslFiles(language, innoSetupConfig) { const parsePromises = []; return (0, event_stream_1.through)(function (xlf) { const stream = this; const parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then(resolvedFiles => { resolvedFiles.forEach(file => { const translatedFile = createIslFile(file.name, file.messages, language, innoSetupConfig); stream.queue(translatedFile); }); }).catch(reason => { this.emit('error', reason); }); }, function () { Promise.all(parsePromises) .then(() => { this.queue(null); }) .catch(reason => { this.emit('error', reason); }); }); } function createIslFile(name, messages, language, innoSetup) { const content = []; let originalContent; if (path_1.default.basename(name) === 'Default') { originalContent = new TextModel(fs_1.default.readFileSync(name + '.isl', 'utf8')); } else { originalContent = new TextModel(fs_1.default.readFileSync(name + '.en.isl', 'utf8')); } originalContent.lines.forEach(line => { if (line.length > 0) { const firstChar = line.charAt(0); if (firstChar === '[' || firstChar === ';') { content.push(line); } else { const sections = line.split('='); const key = sections[0]; let translated = line; if (key) { const translatedMessage = messages[key]; if (translatedMessage) { translated = `${key}=${translatedMessage}`; } } content.push(translated); } } }); const basename = path_1.default.basename(name); const filePath = `${basename}.${language.id}.isl`; const encoded = iconv_lite_umd_1.default.encode(Buffer.from(content.join('\r\n'), 'utf8').toString(), innoSetup.codePage); return new vinyl_1.default({ path: filePath, contents: Buffer.from(encoded), }); } function encodeEntities(value) { const result = []; for (let i = 0; i < value.length; i++) { const ch = value[i]; switch (ch) { case '<': result.push('<'); break; case '>': result.push('>'); break; case '&': result.push('&'); break; default: result.push(ch); } } return result.join(''); } function decodeEntities(value) { return value.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); } //# sourceMappingURL=i18n.js.map ================================================ FILE: build/lib/i18n.resources.json ================================================ { "editor": [ { "name": "vs/platform", "project": "vscode-editor" }, { "name": "vs/editor/contrib", "project": "vscode-editor" }, { "name": "vs/editor", "project": "vscode-editor" }, { "name": "vs/base", "project": "vscode-editor" } ], "workbench": [ { "name": "vs/code", "project": "vscode-workbench" }, { "name": "vs/workbench", "project": "vscode-workbench" }, { "name": "vs/workbench/api/common", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/bulkEdit", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/cli", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/codeEditor", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/callHierarchy", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/typeHierarchy", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/codeActions", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/commands", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/markdown", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/comments", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/debug", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/dialogs", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/multiDiffEditor", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/emmet", "project": "vscode-workbench" }, { "name": "vs/workbench/services/assignment", "project": "vscode-workbench" }, { "name": "vs/workbench/services/auxiliaryWindow", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/extensions", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/externalTerminal", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/files", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/folding", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/html", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/issue", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/inlayHints", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/interactive", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/languageStatus", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/limitIndicator", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/keybindings", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/markers", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/mergeEditor", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/localization", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/logs", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/output", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/performance", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/preferences", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/notebook", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/inlineChat", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/chat", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/quickaccess", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/userData", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/remote", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/relauncher", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/sash", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/scm", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/search", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/searchEditor", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/snippets", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/format", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/tags", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/speech", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/surveys", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/tasks", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/testing", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/terminal", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/terminalContrib", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/themes", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/trust", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/update", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/url", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/watermark", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/webview", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/webviewPanel", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/workspace", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/workspaces", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/customEditor", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/externalUriOpener", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/welcomeGettingStarted", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/welcomePage", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/welcomeViews", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/welcomeWalkthrough", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/welcomeDialog", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/outline", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/userDataSync", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/editSessions", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/views", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/languageDetection", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/accessibilitySignals", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/deprecatedExtensionMigrator", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/bracketPairColorizer2Telemetry", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/scrollLocking", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/remoteTunnel", "project": "vscode-workbench" }, { "name": "vs/workbench/services/actions", "project": "vscode-workbench" }, { "name": "vs/workbench/services/authToken", "project": "vscode-workbench" }, { "name": "vs/workbench/services/backup", "project": "vscode-workbench" }, { "name": "vs/workbench/services/bulkEdit", "project": "vscode-workbench" }, { "name": "vs/workbench/services/clipboard", "project": "vscode-workbench" }, { "name": "vs/workbench/services/commands", "project": "vscode-workbench" }, { "name": "vs/workbench/services/configuration", "project": "vscode-workbench" }, { "name": "vs/workbench/services/configurationResolver", "project": "vscode-workbench" }, { "name": "vs/workbench/services/dialogs", "project": "vscode-workbench" }, { "name": "vs/workbench/services/editor", "project": "vscode-workbench" }, { "name": "vs/workbench/services/extensions", "project": "vscode-workbench" }, { "name": "vs/workbench/services/extensionManagement", "project": "vscode-workbench" }, { "name": "vs/workbench/services/files", "project": "vscode-workbench" }, { "name": "vs/workbench/services/filesConfiguration", "project": "vscode-workbench" }, { "name": "vs/workbench/services/history", "project": "vscode-workbench" }, { "name": "vs/workbench/services/hover", "project": "vscode-workbench" }, { "name": "vs/workbench/services/log", "project": "vscode-workbench" }, { "name": "vs/workbench/services/integrity", "project": "vscode-workbench" }, { "name": "vs/workbench/services/keybinding", "project": "vscode-workbench" }, { "name": "vs/workbench/services/lifecycle", "project": "vscode-workbench" }, { "name": "vs/workbench/services/language", "project": "vscode-workbench" }, { "name": "vs/workbench/services/progress", "project": "vscode-workbench" }, { "name": "vs/workbench/services/remote", "project": "vscode-workbench" }, { "name": "vs/workbench/services/search", "project": "vscode-workbench" }, { "name": "vs/workbench/services/suggest", "project": "vscode-workbench" }, { "name": "vs/workbench/services/textfile", "project": "vscode-workbench" }, { "name": "vs/workbench/services/themes", "project": "vscode-workbench" }, { "name": "vs/workbench/services/textMate", "project": "vscode-workbench" }, { "name": "vs/workbench/services/workingCopy", "project": "vscode-workbench" }, { "name": "vs/workbench/services/workspaces", "project": "vscode-workbench" }, { "name": "vs/workbench/services/decorations", "project": "vscode-workbench" }, { "name": "vs/workbench/services/label", "project": "vscode-workbench" }, { "name": "vs/workbench/services/preferences", "project": "vscode-preferences" }, { "name": "vs/workbench/services/notification", "project": "vscode-workbench" }, { "name": "vs/workbench/services/userData", "project": "vscode-workbench" }, { "name": "vs/workbench/services/userDataSync", "project": "vscode-workbench" }, { "name": "vs/workbench/services/editSessions", "project": "vscode-workbench" }, { "name": "vs/workbench/services/views", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/timeline", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/localHistory", "project": "vscode-workbench" }, { "name": "vs/workbench/services/authentication", "project": "vscode-workbench" }, { "name": "vs/workbench/services/extensionRecommendations", "project": "vscode-workbench" }, { "name": "vs/workbench/services/gettingStarted", "project": "vscode-workbench" }, { "name": "vs/workbench/services/host", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/userDataProfile", "project": "vscode-profiles" }, { "name": "vs/workbench/services/userDataProfile", "project": "vscode-profiles" }, { "name": "vs/workbench/services/localization", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/share", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/accessibility", "project": "vscode-workbench" }, { "name": "vs/workbench/services/issue", "project": "vscode-workbench" }, { "name": "vs/workbench/services/secrets", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/accountEntitlements", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/authentication", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/replNotebook", "project": "vscode-workbench" }, { "name": "vs/workbench/contrib/list", "project": "vscode-workbench" } ] } ================================================ FILE: build/lib/i18n.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import fs from 'fs'; import { map, merge, through, ThroughStream } from 'event-stream'; import jsonMerge from 'gulp-merge-json'; import File from 'vinyl'; import xml2js from 'xml2js'; import gulp from 'gulp'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import iconv from '@vscode/iconv-lite-umd'; import { l10nJsonFormat, getL10nXlf, l10nJsonDetails, getL10nFilesFromXlf, getL10nJson } from '@vscode/l10n-dev'; const REPO_ROOT_PATH = path.join(__dirname, '../..'); function log(message: any, ...rest: any[]): void { fancyLog(ansiColors.green('[i18n]'), message, ...rest); } export interface Language { id: string; // language id, e.g. zh-tw, de translationId?: string; // language id used in translation tools, e.g. zh-hant, de (optional, if not set, the id is used) folderName?: string; // language specific folder name, e.g. cht, deu (optional, if not set, the id is used) } export interface InnoSetup { codePage: string; //code page for encoding (http://www.jrsoftware.org/ishelp/index.php?topic=langoptionssection) } export const defaultLanguages: Language[] = [ { id: 'zh-tw', folderName: 'cht', translationId: 'zh-hant' }, { id: 'zh-cn', folderName: 'chs', translationId: 'zh-hans' }, { id: 'ja', folderName: 'jpn' }, { id: 'ko', folderName: 'kor' }, { id: 'de', folderName: 'deu' }, { id: 'fr', folderName: 'fra' }, { id: 'es', folderName: 'esn' }, { id: 'ru', folderName: 'rus' }, { id: 'it', folderName: 'ita' } ]; // languages requested by the community to non-stable builds export const extraLanguages: Language[] = [ { id: 'pt-br', folderName: 'ptb' }, { id: 'hu', folderName: 'hun' }, { id: 'tr', folderName: 'trk' } ]; interface Item { id: string; message: string; comment?: string; } export interface Resource { name: string; project: string; } interface LocalizeInfo { key: string; comment: string[]; } module LocalizeInfo { export function is(value: any): value is LocalizeInfo { const candidate = value as LocalizeInfo; return candidate && typeof candidate.key === 'string' && (candidate.comment === undefined || (Array.isArray(candidate.comment) && candidate.comment.every(element => typeof element === 'string'))); } } interface BundledFormat { keys: Record; messages: Record; bundles: Record; } module BundledFormat { export function is(value: any): value is BundledFormat { if (value === undefined) { return false; } const candidate = value as BundledFormat; const length = Object.keys(value).length; return length === 3 && !!candidate.keys && !!candidate.messages && !!candidate.bundles; } } type NLSKeysFormat = [string /* module ID */, string[] /* keys */]; module NLSKeysFormat { export function is(value: any): value is NLSKeysFormat { if (value === undefined) { return false; } const candidate = value as NLSKeysFormat; return Array.isArray(candidate) && Array.isArray(candidate[1]); } } interface BundledExtensionFormat { [key: string]: { messages: string[]; keys: (string | LocalizeInfo)[]; }; } interface I18nFormat { version: string; contents: { [module: string]: { [messageKey: string]: string; }; }; } export class Line { private buffer: string[] = []; constructor(indent: number = 0) { if (indent > 0) { this.buffer.push(new Array(indent + 1).join(' ')); } } public append(value: string): Line { this.buffer.push(value); return this; } public toString(): string { return this.buffer.join(''); } } class TextModel { private _lines: string[]; constructor(contents: string) { this._lines = contents.split(/\r\n|\r|\n/); } public get lines(): string[] { return this._lines; } } export class XLF { private buffer: string[]; private files: Record; public numberOfMessages: number; constructor(public project: string) { this.buffer = []; this.files = Object.create(null); this.numberOfMessages = 0; } public toString(): string { this.appendHeader(); const files = Object.keys(this.files).sort(); for (const file of files) { this.appendNewLine(``, 2); const items = this.files[file].sort((a: Item, b: Item) => { return a.id < b.id ? -1 : a.id > b.id ? 1 : 0; }); for (const item of items) { this.addStringItem(file, item); } this.appendNewLine(''); } this.appendFooter(); return this.buffer.join('\r\n'); } public addFile(original: string, keys: (string | LocalizeInfo)[], messages: string[]) { if (keys.length === 0) { console.log('No keys in ' + original); return; } if (keys.length !== messages.length) { throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`); } this.numberOfMessages += keys.length; this.files[original] = []; const existingKeys = new Set(); for (let i = 0; i < keys.length; i++) { const key = keys[i]; let realKey: string | undefined; let comment: string | undefined; if (typeof key === 'string') { realKey = key; comment = undefined; } else if (LocalizeInfo.is(key)) { realKey = key.key; if (key.comment && key.comment.length > 0) { comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n'); } } if (!realKey || existingKeys.has(realKey)) { continue; } existingKeys.add(realKey); const message: string = encodeEntities(messages[i]); this.files[original].push({ id: realKey, message: message, comment: comment }); } } private addStringItem(file: string, item: Item): void { if (!item.id || item.message === undefined || item.message === null) { throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`); } if (item.message.length === 0) { log(`Item with id ${item.id} in file ${file} has an empty message.`); } this.appendNewLine(``, 4); this.appendNewLine(`${item.message}`, 6); if (item.comment) { this.appendNewLine(`${item.comment}`, 6); } this.appendNewLine('', 4); } private appendHeader(): void { this.appendNewLine('', 0); this.appendNewLine('', 0); } private appendFooter(): void { this.appendNewLine('', 0); } private appendNewLine(content: string, indent?: number): void { const line = new Line(indent); line.append(content); this.buffer.push(line.toString()); } static parse = function (xlfString: string): Promise { return new Promise((resolve, reject) => { const parser = new xml2js.Parser(); const files: { messages: Record; name: string; language: string }[] = []; parser.parseString(xlfString, function (err: any, result: any) { if (err) { reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`)); } const fileNodes: any[] = result['xliff']['file']; if (!fileNodes) { reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`)); } fileNodes.forEach((file) => { const name = file.$.original; if (!name) { reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); } const language = file.$['target-language']; if (!language) { reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); } const messages: Record = {}; const transUnits = file.body[0]['trans-unit']; if (transUnits) { transUnits.forEach((unit: any) => { const key = unit.$.id; if (!unit.target) { return; // No translation available } let val = unit.target[0]; if (typeof val !== 'string') { // We allow empty source values so support them for translations as well. val = val._ ? val._ : ''; } if (!key) { reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`)); return; } messages[key] = decodeEntities(val); }); files.push({ messages, name, language: language.toLowerCase() }); } }); resolve(files); }); }); }; } function sortLanguages(languages: Language[]): Language[] { return languages.sort((a: Language, b: Language): number => { return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0); }); } function stripComments(content: string): string { // Copied from stripComments.js // // First group matches a double quoted string // Second group matches a single quoted string // Third group matches a multi line comment // Forth group matches a single line comment // Fifth group matches a trailing comma const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))|(,\s*[}\]])/g; const result = content.replace(regexp, (match, _m1: string, _m2: string, m3: string, m4: string, m5: string) => { // Only one of m1, m2, m3, m4, m5 matches if (m3) { // A block comment. Replace with nothing return ''; } else if (m4) { // Since m4 is a single line comment is is at least of length 2 (e.g. //) // If it ends in \r?\n then keep it. const length = m4.length; if (m4[length - 1] === '\n') { return m4[length - 2] === '\r' ? '\r\n' : '\n'; } else { return ''; } } else if (m5) { // Remove the trailing comma return match.substring(1); } else { // We match a string return match; } }); return result; } function processCoreBundleFormat(base: string, fileHeader: string, languages: Language[], json: NLSKeysFormat, emitter: ThroughStream) { const languageDirectory = path.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { log(`No VS Code localization repository found. Looking at ${languageDirectory}`); log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); } const sortedLanguages = sortLanguages(languages); sortedLanguages.forEach((language) => { if (process.env['VSCODE_BUILD_VERBOSE']) { log(`Generating nls bundles for: ${language.id}`); } const languageFolderName = language.translationId || language.id; const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); let allMessages: I18nFormat | undefined; if (fs.existsSync(i18nFile)) { const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); allMessages = JSON.parse(content); } let nlsIndex = 0; const nlsResult: Array = []; for (const [moduleId, nlsKeys] of json) { const moduleTranslations = allMessages?.contents[moduleId]; for (const nlsKey of nlsKeys) { nlsResult.push(moduleTranslations?.[nlsKey]); // pushing `undefined` is fine, as we keep english strings as fallback for monaco editor in the build nlsIndex++; } } emitter.queue(new File({ contents: Buffer.from(`${fileHeader} globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(nlsResult)}; globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), base, path: `${base}/nls.messages.${language.id}.js` })); }); } export function processNlsFiles(opts: { out: string; fileHeader: string; languages: Language[] }): ThroughStream { return through(function (this: ThroughStream, file: File) { const fileName = path.basename(file.path); if (fileName === 'nls.keys.json') { try { const contents = file.contents.toString('utf8'); const json = JSON.parse(contents); if (NLSKeysFormat.is(json)) { processCoreBundleFormat(file.base, opts.fileHeader, opts.languages, json, this); } } catch (error) { this.emit('error', `Failed to read component file: ${error}`); } } this.queue(file); }); } const editorProject: string = 'vscode-editor', workbenchProject: string = 'vscode-workbench', extensionsProject: string = 'vscode-extensions', setupProject: string = 'vscode-setup', serverProject: string = 'vscode-server'; export function getResource(sourceFile: string): Resource { let resource: string; if (/^vs\/platform/.test(sourceFile)) { return { name: 'vs/platform', project: editorProject }; } else if (/^vs\/editor\/contrib/.test(sourceFile)) { return { name: 'vs/editor/contrib', project: editorProject }; } else if (/^vs\/editor/.test(sourceFile)) { return { name: 'vs/editor', project: editorProject }; } else if (/^vs\/base/.test(sourceFile)) { return { name: 'vs/base', project: editorProject }; } else if (/^vs\/code/.test(sourceFile)) { return { name: 'vs/code', project: workbenchProject }; } else if (/^vs\/server/.test(sourceFile)) { return { name: 'vs/server', project: serverProject }; } else if (/^vs\/workbench\/contrib/.test(sourceFile)) { resource = sourceFile.split('/', 4).join('/'); return { name: resource, project: workbenchProject }; } else if (/^vs\/workbench\/services/.test(sourceFile)) { resource = sourceFile.split('/', 4).join('/'); return { name: resource, project: workbenchProject }; } else if (/^vs\/workbench/.test(sourceFile)) { return { name: 'vs/workbench', project: workbenchProject }; } throw new Error(`Could not identify the XLF bundle for ${sourceFile}`); } export function createXlfFilesForCoreBundle(): ThroughStream { return through(function (this: ThroughStream, file: File) { const basename = path.basename(file.path); if (basename === 'nls.metadata.json') { if (file.isBuffer()) { const xlfs: Record = Object.create(null); const json: BundledFormat = JSON.parse((file.contents as Buffer).toString('utf8')); for (const coreModule in json.keys) { const projectResource = getResource(coreModule); const resource = projectResource.name; const project = projectResource.project; const keys = json.keys[coreModule]; const messages = json.messages[coreModule]; if (keys.length !== messages.length) { this.emit('error', `There is a mismatch between keys and messages in ${file.relative} for module ${coreModule}`); return; } else { let xlf = xlfs[resource]; if (!xlf) { xlf = new XLF(project); xlfs[resource] = xlf; } xlf.addFile(`src/${coreModule}`, keys, messages); } } for (const resource in xlfs) { const xlf = xlfs[resource]; const filePath = `${xlf.project}/${resource.replace(/\//g, '_')}.xlf`; const xlfFile = new File({ path: filePath, contents: Buffer.from(xlf.toString(), 'utf8') }); this.queue(xlfFile); } } else { this.emit('error', new Error(`File ${file.relative} is not using a buffer content`)); return; } } else { this.emit('error', new Error(`File ${file.relative} is not a core meta data file.`)); return; } }); } function createL10nBundleForExtension(extensionFolderName: string, prefixWithBuildFolder: boolean): NodeJS.ReadWriteStream { const prefix = prefixWithBuildFolder ? '.build/' : ''; return gulp .src([ // For source code of extensions `${prefix}extensions/${extensionFolderName}/{src,client,server}/**/*.{ts,tsx}`, // // For any dependencies pulled in (think vscode-css-languageservice or @vscode/emmet-helper) `${prefix}extensions/${extensionFolderName}/**/node_modules/{@vscode,vscode-*}/**/*.{js,jsx}`, // // For any dependencies pulled in that bundle @vscode/l10n. They needed to export the bundle `${prefix}extensions/${extensionFolderName}/**/bundle.l10n.json`, ]) .pipe(map(function (data, callback) { const file = data as File; if (!file.isBuffer()) { // Not a buffer so we drop it callback(); return; } const extension = path.extname(file.relative); if (extension !== '.json') { const contents = file.contents.toString('utf8'); getL10nJson([{ contents, extension }]) .then((json) => { callback(undefined, new File({ path: `extensions/${extensionFolderName}/bundle.l10n.json`, contents: Buffer.from(JSON.stringify(json), 'utf8') })); }) .catch((err) => { callback(new Error(`File ${file.relative} threw an error when parsing: ${err}`)); }); // signal pause? return false; } // for bundle.l10n.jsons let bundleJson; try { bundleJson = JSON.parse(file.contents.toString('utf8')); } catch (err) { callback(new Error(`File ${file.relative} threw an error when parsing: ${err}`)); return; } // some validation of the bundle.l10n.json format for (const key in bundleJson) { if ( typeof bundleJson[key] !== 'string' && (typeof bundleJson[key].message !== 'string' || !Array.isArray(bundleJson[key].comment)) ) { callback(new Error(`Invalid bundle.l10n.json file. The value for key ${key} is not in the expected format.`)); return; } } callback(undefined, file); })) .pipe(jsonMerge({ fileName: `extensions/${extensionFolderName}/bundle.l10n.json`, jsonSpace: '', concatArrays: true })); } export const EXTERNAL_EXTENSIONS = [ 'ms-vscode.js-debug', 'ms-vscode.js-debug-companion', 'ms-vscode.vscode-js-profile-table', ]; export function createXlfFilesForExtensions(): ThroughStream { let counter: number = 0; let folderStreamEnded: boolean = false; let folderStreamEndEmitted: boolean = false; return through(function (this: ThroughStream, extensionFolder: File) { const folderStream = this; const stat = fs.statSync(extensionFolder.path); if (!stat.isDirectory()) { return; } const extensionFolderName = path.basename(extensionFolder.path); if (extensionFolderName === 'node_modules') { return; } // Get extension id and use that as the id const manifest = fs.readFileSync(path.join(extensionFolder.path, 'package.json'), 'utf-8'); const manifestJson = JSON.parse(manifest); const extensionId = manifestJson.publisher + '.' + manifestJson.name; counter++; let _l10nMap: Map; function getL10nMap() { if (!_l10nMap) { _l10nMap = new Map(); } return _l10nMap; } merge( gulp.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionFolderName, EXTERNAL_EXTENSIONS.includes(extensionId)) ).pipe(through(function (file: File) { if (file.isBuffer()) { const buffer: Buffer = file.contents as Buffer; const basename = path.basename(file.path); if (basename === 'package.nls.json') { const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8')); getL10nMap().set(`extensions/${extensionId}/package`, json); } else if (basename === 'nls.metadata.json') { const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8')); const relPath = path.relative(`.build/extensions/${extensionFolderName}`, path.dirname(file.path)); for (const file in json) { const fileContent = json[file]; const info: l10nJsonFormat = Object.create(null); for (let i = 0; i < fileContent.messages.length; i++) { const message = fileContent.messages[i]; const { key, comment } = LocalizeInfo.is(fileContent.keys[i]) ? fileContent.keys[i] as LocalizeInfo : { key: fileContent.keys[i] as string, comment: undefined }; info[key] = comment ? { message, comment } : message; } getL10nMap().set(`extensions/${extensionId}/${relPath}/${file}`, info); } } else if (basename === 'bundle.l10n.json') { const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8')); getL10nMap().set(`extensions/${extensionId}/bundle`, json); } else { this.emit('error', new Error(`${file.path} is not a valid extension nls file`)); return; } } }, function () { if (_l10nMap?.size > 0) { const xlfFile = new File({ path: path.join(extensionsProject, extensionId + '.xlf'), contents: Buffer.from(getL10nXlf(_l10nMap), 'utf8') }); folderStream.queue(xlfFile); } this.queue(null); counter--; if (counter === 0 && folderStreamEnded && !folderStreamEndEmitted) { folderStreamEndEmitted = true; folderStream.queue(null); } })); }, function () { folderStreamEnded = true; if (counter === 0) { folderStreamEndEmitted = true; this.queue(null); } }); } export function createXlfFilesForIsl(): ThroughStream { return through(function (this: ThroughStream, file: File) { let projectName: string, resourceFile: string; if (path.basename(file.path) === 'messages.en.isl') { projectName = setupProject; resourceFile = 'messages.xlf'; } else { throw new Error(`Unknown input file ${file.path}`); } const xlf = new XLF(projectName), keys: string[] = [], messages: string[] = []; const model = new TextModel(file.contents.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { return; } const firstChar = line.charAt(0); switch (firstChar) { case ';': // Comment line; return; case '[': inMessageSection = '[Messages]' === line || '[CustomMessages]' === line; return; } if (!inMessageSection) { return; } const sections: string[] = line.split('='); if (sections.length !== 2) { throw new Error(`Badly formatted message found: ${line}`); } else { const key = sections[0]; const value = sections[1]; if (key.length > 0 && value.length > 0) { keys.push(key); messages.push(value); } } }); const originalPath = file.path.substring(file.cwd.length + 1, file.path.split('.')[0].length).replace(/\\/g, '/'); xlf.addFile(originalPath, keys, messages); // Emit only upon all ISL files combined into single XLF instance const newFilePath = path.join(projectName, resourceFile); const xlfFile = new File({ path: newFilePath, contents: Buffer.from(xlf.toString(), 'utf-8') }); this.queue(xlfFile); }); } function createI18nFile(name: string, messages: any): File { const result = Object.create(null); result[''] = [ '--------------------------------------------------------------------------------------------', 'Copyright (c) Microsoft Corporation. All rights reserved.', 'Licensed under the MIT License. See License.txt in the project root for license information.', '--------------------------------------------------------------------------------------------', 'Do not edit this file. It is machine generated.' ]; for (const key of Object.keys(messages)) { result[key] = messages[key]; } let content = JSON.stringify(result, null, '\t'); if (process.platform === 'win32') { content = content.replace(/\n/g, '\r\n'); } return new File({ path: path.join(name + '.i18n.json'), contents: Buffer.from(content, 'utf8') }); } interface I18nPack { version: string; contents: { [path: string]: Record; }; } const i18nPackVersion = '1.0.0'; export interface TranslationPath { id: string; resourceName: string; } function getRecordFromL10nJsonFormat(l10nJsonFormat: l10nJsonFormat): Record { const record: Record = {}; for (const key of Object.keys(l10nJsonFormat).sort()) { const value = l10nJsonFormat[key]; record[key] = typeof value === 'string' ? value : value.message; } return record; } export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[]): NodeJS.ReadWriteStream { const parsePromises: Promise[] = []; const mainPack: I18nPack = { version: i18nPackVersion, contents: {} }; const extensionsPacks: Record = {}; const errors: any[] = []; return through(function (this: ThroughStream, xlf: File) { let project = path.basename(path.dirname(path.dirname(xlf.relative))); // strip `-new` since vscode-extensions-loc uses the `-new` suffix to indicate that it's from the new loc pipeline const resource = path.basename(path.basename(xlf.relative, '.xlf'), '-new'); if (EXTERNAL_EXTENSIONS.find(e => e === resource)) { project = extensionsProject; } const contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); const parsePromise = getL10nFilesFromXlf(contents); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { const path = file.name; const firstSlash = path.indexOf('/'); if (project === extensionsProject) { // resource will be the extension id let extPack = extensionsPacks[resource]; if (!extPack) { extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} }; } // remove 'extensions/extensionId/' segment const secondSlash = path.indexOf('/', firstSlash + 1); extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); } else { mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); } }); } ).catch(reason => { errors.push(reason); }); }, function () { Promise.all(parsePromises) .then(() => { if (errors.length > 0) { throw errors; } const translatedMainFile = createI18nFile('./main', mainPack); resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); this.queue(translatedMainFile); for (const extensionId in extensionsPacks) { const translatedExtFile = createI18nFile(`extensions/${extensionId}`, extensionsPacks[extensionId]); this.queue(translatedExtFile); resultingTranslationPaths.push({ id: extensionId, resourceName: `extensions/${extensionId}.i18n.json` }); } this.queue(null); }) .catch((reason) => { this.emit('error', reason); }); }); } export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): ThroughStream { const parsePromises: Promise[] = []; return through(function (this: ThroughStream, xlf: File) { const stream = this; const parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { const translatedFile = createIslFile(file.name, file.messages, language, innoSetupConfig); stream.queue(translatedFile); }); } ).catch(reason => { this.emit('error', reason); }); }, function () { Promise.all(parsePromises) .then(() => { this.queue(null); }) .catch(reason => { this.emit('error', reason); }); }); } function createIslFile(name: string, messages: l10nJsonFormat, language: Language, innoSetup: InnoSetup): File { const content: string[] = []; let originalContent: TextModel; if (path.basename(name) === 'Default') { originalContent = new TextModel(fs.readFileSync(name + '.isl', 'utf8')); } else { originalContent = new TextModel(fs.readFileSync(name + '.en.isl', 'utf8')); } originalContent.lines.forEach(line => { if (line.length > 0) { const firstChar = line.charAt(0); if (firstChar === '[' || firstChar === ';') { content.push(line); } else { const sections: string[] = line.split('='); const key = sections[0]; let translated = line; if (key) { const translatedMessage = messages[key]; if (translatedMessage) { translated = `${key}=${translatedMessage}`; } } content.push(translated); } } }); const basename = path.basename(name); const filePath = `${basename}.${language.id}.isl`; const encoded = iconv.encode(Buffer.from(content.join('\r\n'), 'utf8').toString(), innoSetup.codePage); return new File({ path: filePath, contents: Buffer.from(encoded), }); } function encodeEntities(value: string): string { const result: string[] = []; for (let i = 0; i < value.length; i++) { const ch = value[i]; switch (ch) { case '<': result.push('<'); break; case '>': result.push('>'); break; case '&': result.push('&'); break; default: result.push(ch); } } return result.join(''); } function decodeEntities(value: string): string { return value.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); } ================================================ FILE: build/lib/inlineMeta.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.inlineMeta = inlineMeta; const event_stream_1 = __importDefault(require("event-stream")); const path_1 = require("path"); const packageJsonMarkerId = 'BUILD_INSERT_PACKAGE_CONFIGURATION'; // TODO in order to inline `product.json`, more work is // needed to ensure that we cover all cases where modifications // are done to the product configuration during build. There are // at least 2 more changes that kick in very late: // - a `darwinUniversalAssetId` is added in`create-universal-app.ts` // - a `target` is added in `gulpfile.vscode.win32.js` // const productJsonMarkerId = 'BUILD_INSERT_PRODUCT_CONFIGURATION'; function inlineMeta(result, ctx) { return result.pipe(event_stream_1.default.through(function (file) { if (matchesFile(file, ctx)) { let content = file.contents.toString(); let markerFound = false; const packageMarker = `${packageJsonMarkerId}:"${packageJsonMarkerId}"`; // this needs to be the format after esbuild has processed the file (e.g. double quotes) if (content.includes(packageMarker)) { content = content.replace(packageMarker, JSON.stringify(JSON.parse(ctx.packageJsonFn())).slice(1, -1) /* trim braces */); markerFound = true; } // const productMarker = `${productJsonMarkerId}:"${productJsonMarkerId}"`; // this needs to be the format after esbuild has processed the file (e.g. double quotes) // if (content.includes(productMarker)) { // content = content.replace(productMarker, JSON.stringify(JSON.parse(ctx.productJsonFn())).slice(1, -1) /* trim braces */); // markerFound = true; // } if (markerFound) { file.contents = Buffer.from(content); } } this.emit('data', file); })); } function matchesFile(file, ctx) { for (const targetPath of ctx.targetPaths) { if (file.basename === (0, path_1.basename)(targetPath)) { // TODO would be nicer to figure out root relative path to not match on false positives return true; } } return false; } //# sourceMappingURL=inlineMeta.js.map ================================================ FILE: build/lib/inlineMeta.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import { basename } from 'path'; import File from 'vinyl'; export interface IInlineMetaContext { readonly targetPaths: string[]; readonly packageJsonFn: () => string; readonly productJsonFn: () => string; } const packageJsonMarkerId = 'BUILD_INSERT_PACKAGE_CONFIGURATION'; // TODO in order to inline `product.json`, more work is // needed to ensure that we cover all cases where modifications // are done to the product configuration during build. There are // at least 2 more changes that kick in very late: // - a `darwinUniversalAssetId` is added in`create-universal-app.ts` // - a `target` is added in `gulpfile.vscode.win32.js` // const productJsonMarkerId = 'BUILD_INSERT_PRODUCT_CONFIGURATION'; export function inlineMeta(result: NodeJS.ReadWriteStream, ctx: IInlineMetaContext): NodeJS.ReadWriteStream { return result.pipe(es.through(function (file: File) { if (matchesFile(file, ctx)) { let content = file.contents.toString(); let markerFound = false; const packageMarker = `${packageJsonMarkerId}:"${packageJsonMarkerId}"`; // this needs to be the format after esbuild has processed the file (e.g. double quotes) if (content.includes(packageMarker)) { content = content.replace(packageMarker, JSON.stringify(JSON.parse(ctx.packageJsonFn())).slice(1, -1) /* trim braces */); markerFound = true; } // const productMarker = `${productJsonMarkerId}:"${productJsonMarkerId}"`; // this needs to be the format after esbuild has processed the file (e.g. double quotes) // if (content.includes(productMarker)) { // content = content.replace(productMarker, JSON.stringify(JSON.parse(ctx.productJsonFn())).slice(1, -1) /* trim braces */); // markerFound = true; // } if (markerFound) { file.contents = Buffer.from(content); } } this.emit('data', file); })); } function matchesFile(file: File, ctx: IInlineMetaContext): boolean { for (const targetPath of ctx.targetPaths) { if (file.basename === basename(targetPath)) { // TODO would be nicer to figure out root relative path to not match on false positives return true; } } return false; } ================================================ FILE: build/lib/layersChecker.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const typescript_1 = __importDefault(require("typescript")); const fs_1 = require("fs"); const path_1 = require("path"); const minimatch_1 = require("minimatch"); // // ############################################################################################# // // A custom typescript checker for the specific task of detecting the use of certain types in a // layer that does not allow such use. For example: // - using DOM globals in common/node/electron-main layer (e.g. HTMLElement) // - using node.js globals in common/browser layer (e.g. process) // // Make changes to below RULES to lift certain files from these checks only if absolutely needed // // ############################################################################################# // // Types we assume are present in all implementations of JS VMs (node.js, browsers) // Feel free to add more core types as you see needed if present in node.js and browsers const CORE_TYPES = [ 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'console', 'Console', 'Error', 'ErrorConstructor', 'String', 'TextDecoder', 'TextEncoder', 'self', 'queueMicrotask', 'Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Uint8ClampedArray', 'BigUint64Array', 'BigInt64Array', 'btoa', 'atob', 'AbortController', 'AbortSignal', 'MessageChannel', 'MessagePort', 'URL', 'URLSearchParams', 'ReadonlyArray', 'Event', 'EventTarget', 'BroadcastChannel', 'performance', 'Blob', 'crypto', 'File', 'fetch', 'RequestInit', 'Headers', 'Request', 'Response', 'Body', '__type', '__global', 'Performance', 'PerformanceMark', 'PerformanceObserver', 'ImportMeta', 'structuredClone', // webcrypto has been available since Node.js 19, but still live in dom.d.ts 'Crypto', 'SubtleCrypto', 'JsonWebKey', 'MessageEvent', ]; // Types that are defined in a common layer but are known to be only // available in native environments should not be allowed in browser const NATIVE_TYPES = [ 'NativeParsedArgs', 'INativeEnvironmentService', 'AbstractNativeEnvironmentService', 'INativeWindowConfiguration', 'ICommonNativeHostService', 'INativeHostService', 'IMainProcessService' ]; const RULES = [ // Tests: skip { target: '**/vs/**/test/**', skip: true // -> skip all test files }, // Common: vs/base/common/platform.ts { target: '**/vs/base/common/platform.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to postMessage() and friends 'MessageEvent', ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/common/async.ts { target: '**/vs/base/common/async.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to requestIdleCallback & cancelIdleCallback 'requestIdleCallback', 'cancelIdleCallback' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/common/performance.ts { target: '**/vs/base/common/performance.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to Performance 'Performance', 'PerformanceEntry', 'PerformanceTiming' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/environment/common/* { target: '**/vs/platform/environment/common/*.ts', allowedTypes: CORE_TYPES, disallowedTypes: [ /* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/window/common/window.ts { target: '**/vs/platform/window/common/window.ts', allowedTypes: CORE_TYPES, disallowedTypes: [ /* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/native/common/native.ts { target: '**/vs/platform/native/common/native.ts', allowedTypes: CORE_TYPES, disallowedTypes: [ /* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/native/common/nativeHostService.ts { target: '**/vs/platform/native/common/nativeHostService.ts', allowedTypes: CORE_TYPES, disallowedTypes: [ /* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/workbench/api/common/extHostExtensionService.ts { target: '**/vs/workbench/api/common/extHostExtensionService.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to global 'global' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/parts/sandbox/electron-sandbox/preload.ts { target: '**/vs/base/parts/sandbox/electron-sandbox/preload.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to a very small subset of node.js 'process', 'NodeJS' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // Common { target: '**/vs/**/common/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Browser { target: '**/vs/**/browser/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, allowedDefinitions: [ '@types/node/stream/consumers.d.ts' // node.js started to duplicate types from lib.dom.d.ts so we have to account for that ], disallowedDefinitions: [ '@types/node' // no node.js ] }, // Browser (editor contrib) { target: '**/src/vs/editor/contrib/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // node.js { target: '**/vs/**/node/**', allowedTypes: CORE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] }, // Electron (sandbox) { target: '**/vs/**/electron-sandbox/**', allowedTypes: CORE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // Electron (utility) { target: '**/vs/**/electron-utility/**', allowedTypes: [ ...CORE_TYPES, // --> types from electron.d.ts that duplicate from lib.dom.d.ts 'Event', 'Request' ], disallowedTypes: [ 'ipcMain' // not allowed, use validatedIpcMain instead ], disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] }, // Electron (main) { target: '**/vs/**/electron-main/**', allowedTypes: [ ...CORE_TYPES, // --> types from electron.d.ts that duplicate from lib.dom.d.ts 'Event', 'Request' ], disallowedTypes: [ 'ipcMain' // not allowed, use validatedIpcMain instead ], disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] } ]; const TS_CONFIG_PATH = (0, path_1.join)(__dirname, '../../', 'src', 'tsconfig.json'); let hasErrors = false; function checkFile(program, sourceFile, rule) { checkNode(sourceFile); function checkNode(node) { if (node.kind !== typescript_1.default.SyntaxKind.Identifier) { return typescript_1.default.forEachChild(node, checkNode); // recurse down } const checker = program.getTypeChecker(); const symbol = checker.getSymbolAtLocation(node); if (!symbol) { return; } let _parentSymbol = symbol; while (_parentSymbol.parent) { _parentSymbol = _parentSymbol.parent; } const parentSymbol = _parentSymbol; const text = parentSymbol.getName(); if (rule.allowedTypes?.some(allowed => allowed === text)) { return; // override } if (rule.disallowedTypes?.some(disallowed => disallowed === text)) { const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart()); console.log(`[build/lib/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`); hasErrors = true; return; } const declarations = symbol.declarations; if (Array.isArray(declarations)) { DeclarationLoop: for (const declaration of declarations) { if (declaration) { const parent = declaration.parent; if (parent) { const parentSourceFile = parent.getSourceFile(); if (parentSourceFile) { const definitionFileName = parentSourceFile.fileName; if (rule.allowedDefinitions) { for (const allowedDefinition of rule.allowedDefinitions) { if (definitionFileName.indexOf(allowedDefinition) >= 0) { continue DeclarationLoop; } } } if (rule.disallowedDefinitions) { for (const disallowedDefinition of rule.disallowedDefinitions) { if (definitionFileName.indexOf(disallowedDefinition) >= 0) { const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart()); console.log(`[build/lib/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`); hasErrors = true; return; } } } } } } } } } } function createProgram(tsconfigPath) { const tsConfig = typescript_1.default.readConfigFile(tsconfigPath, typescript_1.default.sys.readFile); const configHostParser = { fileExists: fs_1.existsSync, readDirectory: typescript_1.default.sys.readDirectory, readFile: file => (0, fs_1.readFileSync)(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' }; const tsConfigParsed = typescript_1.default.parseJsonConfigFileContent(tsConfig.config, configHostParser, (0, path_1.resolve)((0, path_1.dirname)(tsconfigPath)), { noEmit: true }); const compilerHost = typescript_1.default.createCompilerHost(tsConfigParsed.options, true); return typescript_1.default.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost); } // // Create program and start checking // const program = createProgram(TS_CONFIG_PATH); for (const sourceFile of program.getSourceFiles()) { for (const rule of RULES) { if ((0, minimatch_1.match)([sourceFile.fileName], rule.target).length > 0) { if (!rule.skip) { checkFile(program, sourceFile, rule); } break; } } } if (hasErrors) { process.exit(1); } //# sourceMappingURL=layersChecker.js.map ================================================ FILE: build/lib/layersChecker.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import ts from 'typescript'; import { readFileSync, existsSync } from 'fs'; import { resolve, dirname, join } from 'path'; import { match } from 'minimatch'; // // ############################################################################################# // // A custom typescript checker for the specific task of detecting the use of certain types in a // layer that does not allow such use. For example: // - using DOM globals in common/node/electron-main layer (e.g. HTMLElement) // - using node.js globals in common/browser layer (e.g. process) // // Make changes to below RULES to lift certain files from these checks only if absolutely needed // // ############################################################################################# // // Types we assume are present in all implementations of JS VMs (node.js, browsers) // Feel free to add more core types as you see needed if present in node.js and browsers const CORE_TYPES = [ 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'console', 'Console', 'Error', 'ErrorConstructor', 'String', 'TextDecoder', 'TextEncoder', 'self', 'queueMicrotask', 'Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Uint8ClampedArray', 'BigUint64Array', 'BigInt64Array', 'btoa', 'atob', 'AbortController', 'AbortSignal', 'MessageChannel', 'MessagePort', 'URL', 'URLSearchParams', 'ReadonlyArray', 'Event', 'EventTarget', 'BroadcastChannel', 'performance', 'Blob', 'crypto', 'File', 'fetch', 'RequestInit', 'Headers', 'Request', 'Response', 'Body', '__type', '__global', 'Performance', 'PerformanceMark', 'PerformanceObserver', 'ImportMeta', 'structuredClone', // webcrypto has been available since Node.js 19, but still live in dom.d.ts 'Crypto', 'SubtleCrypto', 'JsonWebKey', 'MessageEvent', ]; // Types that are defined in a common layer but are known to be only // available in native environments should not be allowed in browser const NATIVE_TYPES = [ 'NativeParsedArgs', 'INativeEnvironmentService', 'AbstractNativeEnvironmentService', 'INativeWindowConfiguration', 'ICommonNativeHostService', 'INativeHostService', 'IMainProcessService' ]; const RULES: IRule[] = [ // Tests: skip { target: '**/vs/**/test/**', skip: true // -> skip all test files }, // Common: vs/base/common/platform.ts { target: '**/vs/base/common/platform.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to postMessage() and friends 'MessageEvent', ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/common/async.ts { target: '**/vs/base/common/async.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to requestIdleCallback & cancelIdleCallback 'requestIdleCallback', 'cancelIdleCallback' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/common/performance.ts { target: '**/vs/base/common/performance.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to Performance 'Performance', 'PerformanceEntry', 'PerformanceTiming' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/environment/common/* { target: '**/vs/platform/environment/common/*.ts', allowedTypes: CORE_TYPES, disallowedTypes: [/* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/window/common/window.ts { target: '**/vs/platform/window/common/window.ts', allowedTypes: CORE_TYPES, disallowedTypes: [/* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/native/common/native.ts { target: '**/vs/platform/native/common/native.ts', allowedTypes: CORE_TYPES, disallowedTypes: [/* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/platform/native/common/nativeHostService.ts { target: '**/vs/platform/native/common/nativeHostService.ts', allowedTypes: CORE_TYPES, disallowedTypes: [/* Ignore native types that are defined from here */], disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/workbench/api/common/extHostExtensionService.ts { target: '**/vs/workbench/api/common/extHostExtensionService.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to global 'global' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Common: vs/base/parts/sandbox/electron-sandbox/preload.ts { target: '**/vs/base/parts/sandbox/electron-sandbox/preload.ts', allowedTypes: [ ...CORE_TYPES, // Safe access to a very small subset of node.js 'process', 'NodeJS' ], disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // Common { target: '**/vs/**/common/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts', // no DOM '@types/node' // no node.js ] }, // Browser { target: '**/vs/**/browser/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, allowedDefinitions: [ '@types/node/stream/consumers.d.ts' // node.js started to duplicate types from lib.dom.d.ts so we have to account for that ], disallowedDefinitions: [ '@types/node' // no node.js ] }, // Browser (editor contrib) { target: '**/src/vs/editor/contrib/**', allowedTypes: CORE_TYPES, disallowedTypes: NATIVE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // node.js { target: '**/vs/**/node/**', allowedTypes: CORE_TYPES, disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] }, // Electron (sandbox) { target: '**/vs/**/electron-sandbox/**', allowedTypes: CORE_TYPES, disallowedDefinitions: [ '@types/node' // no node.js ] }, // Electron (utility) { target: '**/vs/**/electron-utility/**', allowedTypes: [ ...CORE_TYPES, // --> types from electron.d.ts that duplicate from lib.dom.d.ts 'Event', 'Request' ], disallowedTypes: [ 'ipcMain' // not allowed, use validatedIpcMain instead ], disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] }, // Electron (main) { target: '**/vs/**/electron-main/**', allowedTypes: [ ...CORE_TYPES, // --> types from electron.d.ts that duplicate from lib.dom.d.ts 'Event', 'Request' ], disallowedTypes: [ 'ipcMain' // not allowed, use validatedIpcMain instead ], disallowedDefinitions: [ 'lib.dom.d.ts' // no DOM ] } ]; const TS_CONFIG_PATH = join(__dirname, '../../', 'src', 'tsconfig.json'); interface IRule { target: string; skip?: boolean; allowedTypes?: string[]; allowedDefinitions?: string[]; disallowedDefinitions?: string[]; disallowedTypes?: string[]; } let hasErrors = false; function checkFile(program: ts.Program, sourceFile: ts.SourceFile, rule: IRule) { checkNode(sourceFile); function checkNode(node: ts.Node): void { if (node.kind !== ts.SyntaxKind.Identifier) { return ts.forEachChild(node, checkNode); // recurse down } const checker = program.getTypeChecker(); const symbol = checker.getSymbolAtLocation(node); if (!symbol) { return; } let _parentSymbol: any = symbol; while (_parentSymbol.parent) { _parentSymbol = _parentSymbol.parent; } const parentSymbol = _parentSymbol as ts.Symbol; const text = parentSymbol.getName(); if (rule.allowedTypes?.some(allowed => allowed === text)) { return; // override } if (rule.disallowedTypes?.some(disallowed => disallowed === text)) { const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart()); console.log(`[build/lib/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`); hasErrors = true; return; } const declarations = symbol.declarations; if (Array.isArray(declarations)) { DeclarationLoop: for (const declaration of declarations) { if (declaration) { const parent = declaration.parent; if (parent) { const parentSourceFile = parent.getSourceFile(); if (parentSourceFile) { const definitionFileName = parentSourceFile.fileName; if (rule.allowedDefinitions) { for (const allowedDefinition of rule.allowedDefinitions) { if (definitionFileName.indexOf(allowedDefinition) >= 0) { continue DeclarationLoop; } } } if (rule.disallowedDefinitions) { for (const disallowedDefinition of rule.disallowedDefinitions) { if (definitionFileName.indexOf(disallowedDefinition) >= 0) { const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart()); console.log(`[build/lib/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`); hasErrors = true; return; } } } } } } } } } } function createProgram(tsconfigPath: string): ts.Program { const tsConfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile); const configHostParser: ts.ParseConfigHost = { fileExists: existsSync, readDirectory: ts.sys.readDirectory, readFile: file => readFileSync(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' }; const tsConfigParsed = ts.parseJsonConfigFileContent(tsConfig.config, configHostParser, resolve(dirname(tsconfigPath)), { noEmit: true }); const compilerHost = ts.createCompilerHost(tsConfigParsed.options, true); return ts.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost); } // // Create program and start checking // const program = createProgram(TS_CONFIG_PATH); for (const sourceFile of program.getSourceFiles()) { for (const rule of RULES) { if (match([sourceFile.fileName], rule.target).length > 0) { if (!rule.skip) { checkFile(program, sourceFile, rule); } break; } } } if (hasErrors) { process.exit(1); } ================================================ FILE: build/lib/mangle/index.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Mangler = void 0; const node_v8_1 = __importDefault(require("node:v8")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const process_1 = require("process"); const source_map_1 = require("source-map"); const typescript_1 = __importDefault(require("typescript")); const url_1 = require("url"); const workerpool_1 = __importDefault(require("workerpool")); const staticLanguageServiceHost_1 = require("./staticLanguageServiceHost"); const buildfile = require('../../buildfile'); class ShortIdent { prefix; static _keywords = new Set(['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null', 'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield']); static _alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$_'.split(''); _value = 0; constructor(prefix) { this.prefix = prefix; } next(isNameTaken) { const candidate = this.prefix + ShortIdent.convert(this._value); this._value++; if (ShortIdent._keywords.has(candidate) || /^[_0-9]/.test(candidate) || isNameTaken?.(candidate)) { // try again return this.next(isNameTaken); } return candidate; } static convert(n) { const base = this._alphabet.length; let result = ''; do { const rest = n % base; result += this._alphabet[rest]; n = (n / base) | 0; } while (n > 0); return result; } } var FieldType; (function (FieldType) { FieldType[FieldType["Public"] = 0] = "Public"; FieldType[FieldType["Protected"] = 1] = "Protected"; FieldType[FieldType["Private"] = 2] = "Private"; })(FieldType || (FieldType = {})); class ClassData { fileName; node; fields = new Map(); replacements; parent; children; constructor(fileName, node) { // analyse all fields (properties and methods). Find usages of all protected and // private ones and keep track of all public ones (to prevent naming collisions) this.fileName = fileName; this.node = node; const candidates = []; for (const member of node.members) { if (typescript_1.default.isMethodDeclaration(member)) { // method `foo() {}` candidates.push(member); } else if (typescript_1.default.isPropertyDeclaration(member)) { // property `foo = 234` candidates.push(member); } else if (typescript_1.default.isGetAccessor(member)) { // getter: `get foo() { ... }` candidates.push(member); } else if (typescript_1.default.isSetAccessor(member)) { // setter: `set foo() { ... }` candidates.push(member); } else if (typescript_1.default.isConstructorDeclaration(member)) { // constructor-prop:`constructor(private foo) {}` for (const param of member.parameters) { if (hasModifier(param, typescript_1.default.SyntaxKind.PrivateKeyword) || hasModifier(param, typescript_1.default.SyntaxKind.ProtectedKeyword) || hasModifier(param, typescript_1.default.SyntaxKind.PublicKeyword) || hasModifier(param, typescript_1.default.SyntaxKind.ReadonlyKeyword)) { candidates.push(param); } } } } for (const member of candidates) { const ident = ClassData._getMemberName(member); if (!ident) { continue; } const type = ClassData._getFieldType(member); this.fields.set(ident, { type, pos: member.name.getStart() }); } } static _getMemberName(node) { if (!node.name) { return undefined; } const { name } = node; let ident = name.getText(); if (name.kind === typescript_1.default.SyntaxKind.ComputedPropertyName) { if (name.expression.kind !== typescript_1.default.SyntaxKind.StringLiteral) { // unsupported: [Symbol.foo] or [abc + 'field'] return; } // ['foo'] ident = name.expression.getText().slice(1, -1); } return ident; } static _getFieldType(node) { if (hasModifier(node, typescript_1.default.SyntaxKind.PrivateKeyword)) { return 2 /* FieldType.Private */; } else if (hasModifier(node, typescript_1.default.SyntaxKind.ProtectedKeyword)) { return 1 /* FieldType.Protected */; } else { return 0 /* FieldType.Public */; } } static _shouldMangle(type) { return type === 2 /* FieldType.Private */ || type === 1 /* FieldType.Protected */; } static makeImplicitPublicActuallyPublic(data, reportViolation) { // TS-HACK // A subtype can make an inherited protected field public. To prevent accidential // mangling of public fields we mark the original (protected) fields as public... for (const [name, info] of data.fields) { if (info.type !== 0 /* FieldType.Public */) { continue; } let parent = data.parent; while (parent) { if (parent.fields.get(name)?.type === 1 /* FieldType.Protected */) { const parentPos = parent.node.getSourceFile().getLineAndCharacterOfPosition(parent.fields.get(name).pos); const infoPos = data.node.getSourceFile().getLineAndCharacterOfPosition(info.pos); reportViolation(name, `'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); parent.fields.get(name).type = 0 /* FieldType.Public */; } parent = parent.parent; } } } static fillInReplacement(data) { if (data.replacements) { // already done return; } // fill in parents first if (data.parent) { ClassData.fillInReplacement(data.parent); } data.replacements = new Map(); const isNameTaken = (name) => { // locally taken if (data._isNameTaken(name)) { return true; } // parents let parent = data.parent; while (parent) { if (parent._isNameTaken(name)) { return true; } parent = parent.parent; } // children if (data.children) { const stack = [...data.children]; while (stack.length) { const node = stack.pop(); if (node._isNameTaken(name)) { return true; } if (node.children) { stack.push(...node.children); } } } return false; }; const identPool = new ShortIdent(''); for (const [name, info] of data.fields) { if (ClassData._shouldMangle(info.type)) { const shortName = identPool.next(isNameTaken); data.replacements.set(name, shortName); } } } // a name is taken when a field that doesn't get mangled exists or // when the name is already in use for replacement _isNameTaken(name) { if (this.fields.has(name) && !ClassData._shouldMangle(this.fields.get(name).type)) { // public field return true; } if (this.replacements) { for (const shortName of this.replacements.values()) { if (shortName === name) { // replaced already (happens wih super types) return true; } } } if (isNameTakenInFile(this.node, name)) { return true; } return false; } lookupShortName(name) { let value = this.replacements.get(name); let parent = this.parent; while (parent) { if (parent.replacements.has(name) && parent.fields.get(name)?.type === 1 /* FieldType.Protected */) { value = parent.replacements.get(name) ?? value; } parent = parent.parent; } return value; } // --- parent chaining addChild(child) { this.children ??= []; this.children.push(child); child.parent = this; } } function isNameTakenInFile(node, name) { const identifiers = node.getSourceFile().identifiers; if (identifiers instanceof Map) { if (identifiers.has(name)) { return true; } } return false; } const skippedExportMangledFiles = [ // Build 'css.build', // Monaco 'editorCommon', 'editorOptions', 'editorZoom', 'standaloneEditor', 'standaloneEnums', 'standaloneLanguages', // Generated 'extensionsApiProposals', // Module passed around as type 'pfs', // entry points ...[ buildfile.workerEditor, buildfile.workerExtensionHost, buildfile.workerNotebook, buildfile.workerLanguageDetection, buildfile.workerLocalFileSearch, buildfile.workerProfileAnalysis, buildfile.workerOutputLinks, buildfile.workerBackgroundTokenization, buildfile.workbenchDesktop, buildfile.workbenchWeb, buildfile.code, buildfile.codeWeb ].flat().map(x => x.name), ]; const skippedExportMangledProjects = [ // Test projects 'vscode-api-tests', // These projects use webpack to dynamically rewrite imports, which messes up our mangling 'configuration-editing', 'microsoft-authentication', 'github-authentication', 'html-language-features/server', ]; const skippedExportMangledSymbols = [ // Don't mangle extension entry points 'activate', 'deactivate', ]; class DeclarationData { fileName; node; replacementName; constructor(fileName, node, fileIdents) { this.fileName = fileName; this.node = node; // Todo: generate replacement names based on usage count, with more used names getting shorter identifiers this.replacementName = fileIdents.next(); } getLocations(service) { if (typescript_1.default.isVariableDeclaration(this.node)) { // If the const aliases any types, we need to rename those too const definitionResult = service.getDefinitionAndBoundSpan(this.fileName, this.node.name.getStart()); if (definitionResult?.definitions && definitionResult.definitions.length > 1) { return definitionResult.definitions.map(x => ({ fileName: x.fileName, offset: x.textSpan.start })); } } return [{ fileName: this.fileName, offset: this.node.name.getStart() }]; } shouldMangle(newName) { const currentName = this.node.name.getText(); if (currentName.startsWith('$') || skippedExportMangledSymbols.includes(currentName)) { return false; } // New name is longer the existing one :'( if (newName.length >= currentName.length) { return false; } // Don't mangle functions we've explicitly opted out if (this.node.getFullText().includes('@skipMangle')) { return false; } return true; } } /** * TypeScript2TypeScript transformer that mangles all private and protected fields * * 1. Collect all class fields (properties, methods) * 2. Collect all sub and super-type relations between classes * 3. Compute replacement names for each field * 4. Lookup rename locations for these fields * 5. Prepare and apply edits */ class Mangler { projectPath; log; config; allClassDataByKey = new Map(); allExportedSymbols = new Set(); renameWorkerPool; constructor(projectPath, log = () => { }, config) { this.projectPath = projectPath; this.log = log; this.config = config; this.renameWorkerPool = workerpool_1.default.pool(path_1.default.join(__dirname, 'renameWorker.js'), { maxWorkers: 4, minWorkers: 'max' }); } async computeNewFileContents(strictImplicitPublicHandling) { const service = typescript_1.default.createLanguageService(new staticLanguageServiceHost_1.StaticLanguageServiceHost(this.projectPath)); // STEP: // - Find all classes and their field info. // - Find exported symbols. const fileIdents = new ShortIdent('$'); const visit = (node) => { if (this.config.manglePrivateFields) { if (typescript_1.default.isClassDeclaration(node) || typescript_1.default.isClassExpression(node)) { const anchor = node.name ?? node; const key = `${node.getSourceFile().fileName}|${anchor.getStart()}`; if (this.allClassDataByKey.has(key)) { throw new Error('DUPE?'); } this.allClassDataByKey.set(key, new ClassData(node.getSourceFile().fileName, node)); } } if (this.config.mangleExports) { // Find exported classes, functions, and vars if (( // Exported class typescript_1.default.isClassDeclaration(node) && hasModifier(node, typescript_1.default.SyntaxKind.ExportKeyword) && node.name) || ( // Exported function typescript_1.default.isFunctionDeclaration(node) && typescript_1.default.isSourceFile(node.parent) && hasModifier(node, typescript_1.default.SyntaxKind.ExportKeyword) && node.name && node.body // On named function and not on the overload ) || ( // Exported variable typescript_1.default.isVariableDeclaration(node) && hasModifier(node.parent.parent, typescript_1.default.SyntaxKind.ExportKeyword) // Variable statement is exported && typescript_1.default.isSourceFile(node.parent.parent.parent)) // Disabled for now because we need to figure out how to handle // enums that are used in monaco or extHost interfaces. /* || ( // Exported enum ts.isEnumDeclaration(node) && ts.isSourceFile(node.parent) && hasModifier(node, ts.SyntaxKind.ExportKeyword) && !hasModifier(node, ts.SyntaxKind.ConstKeyword) // Don't bother mangling const enums because these are inlined && node.name */ ) { if (isInAmbientContext(node)) { return; } this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, fileIdents)); } } typescript_1.default.forEachChild(node, visit); }; for (const file of service.getProgram().getSourceFiles()) { if (!file.isDeclarationFile) { typescript_1.default.forEachChild(file, visit); } } this.log(`Done collecting. Classes: ${this.allClassDataByKey.size}. Exported symbols: ${this.allExportedSymbols.size}`); // STEP: connect sub and super-types const setupParents = (data) => { const extendsClause = data.node.heritageClauses?.find(h => h.token === typescript_1.default.SyntaxKind.ExtendsKeyword); if (!extendsClause) { // no EXTENDS-clause return; } const info = service.getDefinitionAtPosition(data.fileName, extendsClause.types[0].expression.getEnd()); if (!info || info.length === 0) { // throw new Error('SUPER type not found'); return; } if (info.length !== 1) { // inherits from declared/library type return; } const [definition] = info; const key = `${definition.fileName}|${definition.textSpan.start}`; const parent = this.allClassDataByKey.get(key); if (!parent) { // throw new Error(`SUPER type not found: ${key}`); return; } parent.addChild(data); }; for (const data of this.allClassDataByKey.values()) { setupParents(data); } // STEP: make implicit public (actually protected) field really public const violations = new Map(); let violationsCauseFailure = false; for (const data of this.allClassDataByKey.values()) { ClassData.makeImplicitPublicActuallyPublic(data, (name, what, why) => { const arr = violations.get(what); if (arr) { arr.push(why); } else { violations.set(what, [why]); } if (strictImplicitPublicHandling && !strictImplicitPublicHandling.has(name)) { violationsCauseFailure = true; } }); } for (const [why, whys] of violations) { this.log(`WARN: ${why} became PUBLIC because of: ${whys.join(' , ')}`); } if (violationsCauseFailure) { const message = 'Protected fields have been made PUBLIC. This hurts minification and is therefore not allowed. Review the WARN messages further above'; this.log(`ERROR: ${message}`); throw new Error(message); } // STEP: compute replacement names for each class for (const data of this.allClassDataByKey.values()) { ClassData.fillInReplacement(data); } this.log(`Done creating class replacements`); // STEP: prepare rename edits this.log(`Starting prepare rename edits`); const editsByFile = new Map(); const appendEdit = (fileName, edit) => { const edits = editsByFile.get(fileName); if (!edits) { editsByFile.set(fileName, [edit]); } else { edits.push(edit); } }; const appendRename = (newText, loc) => { appendEdit(loc.fileName, { newText: (loc.prefixText || '') + newText + (loc.suffixText || ''), offset: loc.textSpan.start, length: loc.textSpan.length }); }; const renameResults = []; const queueRename = (fileName, pos, newName) => { renameResults.push(Promise.resolve(this.renameWorkerPool.exec('findRenameLocations', [this.projectPath, fileName, pos])) .then((locations) => ({ newName, locations }))); }; for (const data of this.allClassDataByKey.values()) { if (hasModifier(data.node, typescript_1.default.SyntaxKind.DeclareKeyword)) { continue; } fields: for (const [name, info] of data.fields) { if (!ClassData._shouldMangle(info.type)) { continue fields; } // TS-HACK: protected became public via 'some' child // and because of that we might need to ignore this now let parent = data.parent; while (parent) { if (parent.fields.get(name)?.type === 0 /* FieldType.Public */) { continue fields; } parent = parent.parent; } const newName = data.lookupShortName(name); queueRename(data.fileName, info.pos, newName); } } for (const data of this.allExportedSymbols.values()) { if (data.fileName.endsWith('.d.ts') || skippedExportMangledProjects.some(proj => data.fileName.includes(proj)) || skippedExportMangledFiles.some(file => data.fileName.endsWith(file + '.ts'))) { continue; } if (!data.shouldMangle(data.replacementName)) { continue; } const newText = data.replacementName; for (const { fileName, offset } of data.getLocations(service)) { queueRename(fileName, offset, newText); } } await Promise.all(renameResults).then((result) => { for (const { newName, locations } of result) { for (const loc of locations) { appendRename(newName, loc); } } }); await this.renameWorkerPool.terminate(); this.log(`Done preparing edits: ${editsByFile.size} files`); // STEP: apply all rename edits (per file) const result = new Map(); let savedBytes = 0; for (const item of service.getProgram().getSourceFiles()) { const { mapRoot, sourceRoot } = service.getProgram().getCompilerOptions(); const projectDir = path_1.default.dirname(this.projectPath); const sourceMapRoot = mapRoot ?? (0, url_1.pathToFileURL)(sourceRoot ?? projectDir).toString(); // source maps let generator; let newFullText; const edits = editsByFile.get(item.fileName); if (!edits) { // just copy newFullText = item.getFullText(); } else { // source map generator const relativeFileName = normalize(path_1.default.relative(projectDir, item.fileName)); const mappingsByLine = new Map(); // apply renames edits.sort((a, b) => b.offset - a.offset); const characters = item.getFullText().split(''); let lastEdit; for (const edit of edits) { if (lastEdit && lastEdit.offset === edit.offset) { // if (lastEdit.length !== edit.length || lastEdit.newText !== edit.newText) { this.log('ERROR: Overlapping edit', item.fileName, edit.offset, edits); throw new Error('OVERLAPPING edit'); } else { continue; } } lastEdit = edit; const mangledName = characters.splice(edit.offset, edit.length, edit.newText).join(''); savedBytes += mangledName.length - edit.newText.length; // source maps const pos = item.getLineAndCharacterOfPosition(edit.offset); let mappings = mappingsByLine.get(pos.line); if (!mappings) { mappings = []; mappingsByLine.set(pos.line, mappings); } mappings.unshift({ source: relativeFileName, original: { line: pos.line + 1, column: pos.character }, generated: { line: pos.line + 1, column: pos.character }, name: mangledName }, { source: relativeFileName, original: { line: pos.line + 1, column: pos.character + edit.length }, generated: { line: pos.line + 1, column: pos.character + edit.newText.length }, }); } // source map generation, make sure to get mappings per line correct generator = new source_map_1.SourceMapGenerator({ file: path_1.default.basename(item.fileName), sourceRoot: sourceMapRoot }); generator.setSourceContent(relativeFileName, item.getFullText()); for (const [, mappings] of mappingsByLine) { let lineDelta = 0; for (const mapping of mappings) { generator.addMapping({ ...mapping, generated: { line: mapping.generated.line, column: mapping.generated.column - lineDelta } }); lineDelta += mapping.original.column - mapping.generated.column; } } newFullText = characters.join(''); } result.set(item.fileName, { out: newFullText, sourceMap: generator?.toString() }); } service.dispose(); this.renameWorkerPool.terminate(); this.log(`Done: ${savedBytes / 1000}kb saved, memory-usage: ${JSON.stringify(node_v8_1.default.getHeapStatistics())}`); return result; } } exports.Mangler = Mangler; // --- ast utils function hasModifier(node, kind) { const modifiers = typescript_1.default.canHaveModifiers(node) ? typescript_1.default.getModifiers(node) : undefined; return Boolean(modifiers?.find(mode => mode.kind === kind)); } function isInAmbientContext(node) { for (let p = node.parent; p; p = p.parent) { if (typescript_1.default.isModuleDeclaration(p)) { return true; } } return false; } function normalize(path) { return path.replace(/\\/g, '/'); } async function _run() { const root = path_1.default.join(__dirname, '..', '..', '..'); const projectBase = path_1.default.join(root, 'src'); const projectPath = path_1.default.join(projectBase, 'tsconfig.json'); const newProjectBase = path_1.default.join(path_1.default.dirname(projectBase), path_1.default.basename(projectBase) + '2'); fs_1.default.cpSync(projectBase, newProjectBase, { recursive: true }); const mangler = new Mangler(projectPath, console.log, { mangleExports: true, manglePrivateFields: true, }); for (const [fileName, contents] of await mangler.computeNewFileContents(new Set(['saveState']))) { const newFilePath = path_1.default.join(newProjectBase, path_1.default.relative(projectBase, fileName)); await fs_1.default.promises.mkdir(path_1.default.dirname(newFilePath), { recursive: true }); await fs_1.default.promises.writeFile(newFilePath, contents.out); if (contents.sourceMap) { await fs_1.default.promises.writeFile(newFilePath + '.map', contents.sourceMap); } } } if (__filename === process_1.argv[1]) { _run(); } //# sourceMappingURL=index.js.map ================================================ FILE: build/lib/mangle/index.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import v8 from 'node:v8'; import fs from 'fs'; import path from 'path'; import { argv } from 'process'; import { Mapping, SourceMapGenerator } from 'source-map'; import ts from 'typescript'; import { pathToFileURL } from 'url'; import workerpool from 'workerpool'; import { StaticLanguageServiceHost } from './staticLanguageServiceHost'; const buildfile = require('../../buildfile'); class ShortIdent { private static _keywords = new Set(['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null', 'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield']); private static _alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$_'.split(''); private _value = 0; constructor( private readonly prefix: string ) { } next(isNameTaken?: (name: string) => boolean): string { const candidate = this.prefix + ShortIdent.convert(this._value); this._value++; if (ShortIdent._keywords.has(candidate) || /^[_0-9]/.test(candidate) || isNameTaken?.(candidate)) { // try again return this.next(isNameTaken); } return candidate; } private static convert(n: number): string { const base = this._alphabet.length; let result = ''; do { const rest = n % base; result += this._alphabet[rest]; n = (n / base) | 0; } while (n > 0); return result; } } const enum FieldType { Public, Protected, Private } class ClassData { fields = new Map(); private replacements: Map | undefined; parent: ClassData | undefined; children: ClassData[] | undefined; constructor( readonly fileName: string, readonly node: ts.ClassDeclaration | ts.ClassExpression, ) { // analyse all fields (properties and methods). Find usages of all protected and // private ones and keep track of all public ones (to prevent naming collisions) const candidates: (ts.NamedDeclaration)[] = []; for (const member of node.members) { if (ts.isMethodDeclaration(member)) { // method `foo() {}` candidates.push(member); } else if (ts.isPropertyDeclaration(member)) { // property `foo = 234` candidates.push(member); } else if (ts.isGetAccessor(member)) { // getter: `get foo() { ... }` candidates.push(member); } else if (ts.isSetAccessor(member)) { // setter: `set foo() { ... }` candidates.push(member); } else if (ts.isConstructorDeclaration(member)) { // constructor-prop:`constructor(private foo) {}` for (const param of member.parameters) { if (hasModifier(param, ts.SyntaxKind.PrivateKeyword) || hasModifier(param, ts.SyntaxKind.ProtectedKeyword) || hasModifier(param, ts.SyntaxKind.PublicKeyword) || hasModifier(param, ts.SyntaxKind.ReadonlyKeyword) ) { candidates.push(param); } } } } for (const member of candidates) { const ident = ClassData._getMemberName(member); if (!ident) { continue; } const type = ClassData._getFieldType(member); this.fields.set(ident, { type, pos: member.name!.getStart() }); } } private static _getMemberName(node: ts.NamedDeclaration): string | undefined { if (!node.name) { return undefined; } const { name } = node; let ident = name.getText(); if (name.kind === ts.SyntaxKind.ComputedPropertyName) { if (name.expression.kind !== ts.SyntaxKind.StringLiteral) { // unsupported: [Symbol.foo] or [abc + 'field'] return; } // ['foo'] ident = name.expression.getText().slice(1, -1); } return ident; } private static _getFieldType(node: ts.Node): FieldType { if (hasModifier(node, ts.SyntaxKind.PrivateKeyword)) { return FieldType.Private; } else if (hasModifier(node, ts.SyntaxKind.ProtectedKeyword)) { return FieldType.Protected; } else { return FieldType.Public; } } static _shouldMangle(type: FieldType): boolean { return type === FieldType.Private || type === FieldType.Protected ; } static makeImplicitPublicActuallyPublic(data: ClassData, reportViolation: (name: string, what: string, why: string) => void): void { // TS-HACK // A subtype can make an inherited protected field public. To prevent accidential // mangling of public fields we mark the original (protected) fields as public... for (const [name, info] of data.fields) { if (info.type !== FieldType.Public) { continue; } let parent: ClassData | undefined = data.parent; while (parent) { if (parent.fields.get(name)?.type === FieldType.Protected) { const parentPos = parent.node.getSourceFile().getLineAndCharacterOfPosition(parent.fields.get(name)!.pos); const infoPos = data.node.getSourceFile().getLineAndCharacterOfPosition(info.pos); reportViolation(name, `'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); parent.fields.get(name)!.type = FieldType.Public; } parent = parent.parent; } } } static fillInReplacement(data: ClassData) { if (data.replacements) { // already done return; } // fill in parents first if (data.parent) { ClassData.fillInReplacement(data.parent); } data.replacements = new Map(); const isNameTaken = (name: string) => { // locally taken if (data._isNameTaken(name)) { return true; } // parents let parent: ClassData | undefined = data.parent; while (parent) { if (parent._isNameTaken(name)) { return true; } parent = parent.parent; } // children if (data.children) { const stack = [...data.children]; while (stack.length) { const node = stack.pop()!; if (node._isNameTaken(name)) { return true; } if (node.children) { stack.push(...node.children); } } } return false; }; const identPool = new ShortIdent(''); for (const [name, info] of data.fields) { if (ClassData._shouldMangle(info.type)) { const shortName = identPool.next(isNameTaken); data.replacements.set(name, shortName); } } } // a name is taken when a field that doesn't get mangled exists or // when the name is already in use for replacement private _isNameTaken(name: string) { if (this.fields.has(name) && !ClassData._shouldMangle(this.fields.get(name)!.type)) { // public field return true; } if (this.replacements) { for (const shortName of this.replacements.values()) { if (shortName === name) { // replaced already (happens wih super types) return true; } } } if (isNameTakenInFile(this.node, name)) { return true; } return false; } lookupShortName(name: string): string { let value = this.replacements!.get(name)!; let parent = this.parent; while (parent) { if (parent.replacements!.has(name) && parent.fields.get(name)?.type === FieldType.Protected) { value = parent.replacements!.get(name)! ?? value; } parent = parent.parent; } return value; } // --- parent chaining addChild(child: ClassData) { this.children ??= []; this.children.push(child); child.parent = this; } } function isNameTakenInFile(node: ts.Node, name: string): boolean { const identifiers = (node.getSourceFile()).identifiers; if (identifiers instanceof Map) { if (identifiers.has(name)) { return true; } } return false; } const skippedExportMangledFiles = [ // Build 'css.build', // Monaco 'editorCommon', 'editorOptions', 'editorZoom', 'standaloneEditor', 'standaloneEnums', 'standaloneLanguages', // Generated 'extensionsApiProposals', // Module passed around as type 'pfs', // entry points ...[ buildfile.workerEditor, buildfile.workerExtensionHost, buildfile.workerNotebook, buildfile.workerLanguageDetection, buildfile.workerLocalFileSearch, buildfile.workerProfileAnalysis, buildfile.workerOutputLinks, buildfile.workerBackgroundTokenization, buildfile.workbenchDesktop, buildfile.workbenchWeb, buildfile.code, buildfile.codeWeb ].flat().map(x => x.name), ]; const skippedExportMangledProjects = [ // Test projects 'vscode-api-tests', // These projects use webpack to dynamically rewrite imports, which messes up our mangling 'configuration-editing', 'microsoft-authentication', 'github-authentication', 'html-language-features/server', ]; const skippedExportMangledSymbols = [ // Don't mangle extension entry points 'activate', 'deactivate', ]; class DeclarationData { readonly replacementName: string; constructor( readonly fileName: string, readonly node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration | ts.VariableDeclaration, fileIdents: ShortIdent, ) { // Todo: generate replacement names based on usage count, with more used names getting shorter identifiers this.replacementName = fileIdents.next(); } getLocations(service: ts.LanguageService): Iterable<{ fileName: string; offset: number }> { if (ts.isVariableDeclaration(this.node)) { // If the const aliases any types, we need to rename those too const definitionResult = service.getDefinitionAndBoundSpan(this.fileName, this.node.name.getStart()); if (definitionResult?.definitions && definitionResult.definitions.length > 1) { return definitionResult.definitions.map(x => ({ fileName: x.fileName, offset: x.textSpan.start })); } } return [{ fileName: this.fileName, offset: this.node.name!.getStart() }]; } shouldMangle(newName: string): boolean { const currentName = this.node.name!.getText(); if (currentName.startsWith('$') || skippedExportMangledSymbols.includes(currentName)) { return false; } // New name is longer the existing one :'( if (newName.length >= currentName.length) { return false; } // Don't mangle functions we've explicitly opted out if (this.node.getFullText().includes('@skipMangle')) { return false; } return true; } } export interface MangleOutput { out: string; sourceMap?: string; } /** * TypeScript2TypeScript transformer that mangles all private and protected fields * * 1. Collect all class fields (properties, methods) * 2. Collect all sub and super-type relations between classes * 3. Compute replacement names for each field * 4. Lookup rename locations for these fields * 5. Prepare and apply edits */ export class Mangler { private readonly allClassDataByKey = new Map(); private readonly allExportedSymbols = new Set(); private readonly renameWorkerPool: workerpool.WorkerPool; constructor( private readonly projectPath: string, private readonly log: typeof console.log = () => { }, private readonly config: { readonly manglePrivateFields: boolean; readonly mangleExports: boolean }, ) { this.renameWorkerPool = workerpool.pool(path.join(__dirname, 'renameWorker.js'), { maxWorkers: 4, minWorkers: 'max' }); } async computeNewFileContents(strictImplicitPublicHandling?: Set): Promise> { const service = ts.createLanguageService(new StaticLanguageServiceHost(this.projectPath)); // STEP: // - Find all classes and their field info. // - Find exported symbols. const fileIdents = new ShortIdent('$'); const visit = (node: ts.Node): void => { if (this.config.manglePrivateFields) { if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) { const anchor = node.name ?? node; const key = `${node.getSourceFile().fileName}|${anchor.getStart()}`; if (this.allClassDataByKey.has(key)) { throw new Error('DUPE?'); } this.allClassDataByKey.set(key, new ClassData(node.getSourceFile().fileName, node)); } } if (this.config.mangleExports) { // Find exported classes, functions, and vars if ( ( // Exported class ts.isClassDeclaration(node) && hasModifier(node, ts.SyntaxKind.ExportKeyword) && node.name ) || ( // Exported function ts.isFunctionDeclaration(node) && ts.isSourceFile(node.parent) && hasModifier(node, ts.SyntaxKind.ExportKeyword) && node.name && node.body // On named function and not on the overload ) || ( // Exported variable ts.isVariableDeclaration(node) && hasModifier(node.parent.parent, ts.SyntaxKind.ExportKeyword) // Variable statement is exported && ts.isSourceFile(node.parent.parent.parent) ) // Disabled for now because we need to figure out how to handle // enums that are used in monaco or extHost interfaces. /* || ( // Exported enum ts.isEnumDeclaration(node) && ts.isSourceFile(node.parent) && hasModifier(node, ts.SyntaxKind.ExportKeyword) && !hasModifier(node, ts.SyntaxKind.ConstKeyword) // Don't bother mangling const enums because these are inlined && node.name */ ) { if (isInAmbientContext(node)) { return; } this.allExportedSymbols.add(new DeclarationData(node.getSourceFile().fileName, node, fileIdents)); } } ts.forEachChild(node, visit); }; for (const file of service.getProgram()!.getSourceFiles()) { if (!file.isDeclarationFile) { ts.forEachChild(file, visit); } } this.log(`Done collecting. Classes: ${this.allClassDataByKey.size}. Exported symbols: ${this.allExportedSymbols.size}`); // STEP: connect sub and super-types const setupParents = (data: ClassData) => { const extendsClause = data.node.heritageClauses?.find(h => h.token === ts.SyntaxKind.ExtendsKeyword); if (!extendsClause) { // no EXTENDS-clause return; } const info = service.getDefinitionAtPosition(data.fileName, extendsClause.types[0].expression.getEnd()); if (!info || info.length === 0) { // throw new Error('SUPER type not found'); return; } if (info.length !== 1) { // inherits from declared/library type return; } const [definition] = info; const key = `${definition.fileName}|${definition.textSpan.start}`; const parent = this.allClassDataByKey.get(key); if (!parent) { // throw new Error(`SUPER type not found: ${key}`); return; } parent.addChild(data); }; for (const data of this.allClassDataByKey.values()) { setupParents(data); } // STEP: make implicit public (actually protected) field really public const violations = new Map(); let violationsCauseFailure = false; for (const data of this.allClassDataByKey.values()) { ClassData.makeImplicitPublicActuallyPublic(data, (name: string, what, why) => { const arr = violations.get(what); if (arr) { arr.push(why); } else { violations.set(what, [why]); } if (strictImplicitPublicHandling && !strictImplicitPublicHandling.has(name)) { violationsCauseFailure = true; } }); } for (const [why, whys] of violations) { this.log(`WARN: ${why} became PUBLIC because of: ${whys.join(' , ')}`); } if (violationsCauseFailure) { const message = 'Protected fields have been made PUBLIC. This hurts minification and is therefore not allowed. Review the WARN messages further above'; this.log(`ERROR: ${message}`); throw new Error(message); } // STEP: compute replacement names for each class for (const data of this.allClassDataByKey.values()) { ClassData.fillInReplacement(data); } this.log(`Done creating class replacements`); // STEP: prepare rename edits this.log(`Starting prepare rename edits`); type Edit = { newText: string; offset: number; length: number }; const editsByFile = new Map(); const appendEdit = (fileName: string, edit: Edit) => { const edits = editsByFile.get(fileName); if (!edits) { editsByFile.set(fileName, [edit]); } else { edits.push(edit); } }; const appendRename = (newText: string, loc: ts.RenameLocation) => { appendEdit(loc.fileName, { newText: (loc.prefixText || '') + newText + (loc.suffixText || ''), offset: loc.textSpan.start, length: loc.textSpan.length }); }; type RenameFn = (projectName: string, fileName: string, pos: number) => ts.RenameLocation[]; const renameResults: Array> = []; const queueRename = (fileName: string, pos: number, newName: string) => { renameResults.push(Promise.resolve(this.renameWorkerPool.exec('findRenameLocations', [this.projectPath, fileName, pos])) .then((locations) => ({ newName, locations }))); }; for (const data of this.allClassDataByKey.values()) { if (hasModifier(data.node, ts.SyntaxKind.DeclareKeyword)) { continue; } fields: for (const [name, info] of data.fields) { if (!ClassData._shouldMangle(info.type)) { continue fields; } // TS-HACK: protected became public via 'some' child // and because of that we might need to ignore this now let parent = data.parent; while (parent) { if (parent.fields.get(name)?.type === FieldType.Public) { continue fields; } parent = parent.parent; } const newName = data.lookupShortName(name); queueRename(data.fileName, info.pos, newName); } } for (const data of this.allExportedSymbols.values()) { if (data.fileName.endsWith('.d.ts') || skippedExportMangledProjects.some(proj => data.fileName.includes(proj)) || skippedExportMangledFiles.some(file => data.fileName.endsWith(file + '.ts')) ) { continue; } if (!data.shouldMangle(data.replacementName)) { continue; } const newText = data.replacementName; for (const { fileName, offset } of data.getLocations(service)) { queueRename(fileName, offset, newText); } } await Promise.all(renameResults).then((result) => { for (const { newName, locations } of result) { for (const loc of locations) { appendRename(newName, loc); } } }); await this.renameWorkerPool.terminate(); this.log(`Done preparing edits: ${editsByFile.size} files`); // STEP: apply all rename edits (per file) const result = new Map(); let savedBytes = 0; for (const item of service.getProgram()!.getSourceFiles()) { const { mapRoot, sourceRoot } = service.getProgram()!.getCompilerOptions(); const projectDir = path.dirname(this.projectPath); const sourceMapRoot = mapRoot ?? pathToFileURL(sourceRoot ?? projectDir).toString(); // source maps let generator: SourceMapGenerator | undefined; let newFullText: string; const edits = editsByFile.get(item.fileName); if (!edits) { // just copy newFullText = item.getFullText(); } else { // source map generator const relativeFileName = normalize(path.relative(projectDir, item.fileName)); const mappingsByLine = new Map(); // apply renames edits.sort((a, b) => b.offset - a.offset); const characters = item.getFullText().split(''); let lastEdit: Edit | undefined; for (const edit of edits) { if (lastEdit && lastEdit.offset === edit.offset) { // if (lastEdit.length !== edit.length || lastEdit.newText !== edit.newText) { this.log('ERROR: Overlapping edit', item.fileName, edit.offset, edits); throw new Error('OVERLAPPING edit'); } else { continue; } } lastEdit = edit; const mangledName = characters.splice(edit.offset, edit.length, edit.newText).join(''); savedBytes += mangledName.length - edit.newText.length; // source maps const pos = item.getLineAndCharacterOfPosition(edit.offset); let mappings = mappingsByLine.get(pos.line); if (!mappings) { mappings = []; mappingsByLine.set(pos.line, mappings); } mappings.unshift({ source: relativeFileName, original: { line: pos.line + 1, column: pos.character }, generated: { line: pos.line + 1, column: pos.character }, name: mangledName }, { source: relativeFileName, original: { line: pos.line + 1, column: pos.character + edit.length }, generated: { line: pos.line + 1, column: pos.character + edit.newText.length }, }); } // source map generation, make sure to get mappings per line correct generator = new SourceMapGenerator({ file: path.basename(item.fileName), sourceRoot: sourceMapRoot }); generator.setSourceContent(relativeFileName, item.getFullText()); for (const [, mappings] of mappingsByLine) { let lineDelta = 0; for (const mapping of mappings) { generator.addMapping({ ...mapping, generated: { line: mapping.generated.line, column: mapping.generated.column - lineDelta } }); lineDelta += mapping.original.column - mapping.generated.column; } } newFullText = characters.join(''); } result.set(item.fileName, { out: newFullText, sourceMap: generator?.toString() }); } service.dispose(); this.renameWorkerPool.terminate(); this.log(`Done: ${savedBytes / 1000}kb saved, memory-usage: ${JSON.stringify(v8.getHeapStatistics())}`); return result; } } // --- ast utils function hasModifier(node: ts.Node, kind: ts.SyntaxKind) { const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined; return Boolean(modifiers?.find(mode => mode.kind === kind)); } function isInAmbientContext(node: ts.Node): boolean { for (let p = node.parent; p; p = p.parent) { if (ts.isModuleDeclaration(p)) { return true; } } return false; } function normalize(path: string): string { return path.replace(/\\/g, '/'); } async function _run() { const root = path.join(__dirname, '..', '..', '..'); const projectBase = path.join(root, 'src'); const projectPath = path.join(projectBase, 'tsconfig.json'); const newProjectBase = path.join(path.dirname(projectBase), path.basename(projectBase) + '2'); fs.cpSync(projectBase, newProjectBase, { recursive: true }); const mangler = new Mangler(projectPath, console.log, { mangleExports: true, manglePrivateFields: true, }); for (const [fileName, contents] of await mangler.computeNewFileContents(new Set(['saveState']))) { const newFilePath = path.join(newProjectBase, path.relative(projectBase, fileName)); await fs.promises.mkdir(path.dirname(newFilePath), { recursive: true }); await fs.promises.writeFile(newFilePath, contents.out); if (contents.sourceMap) { await fs.promises.writeFile(newFilePath + '.map', contents.sourceMap); } } } if (__filename === argv[1]) { _run(); } ================================================ FILE: build/lib/mangle/renameWorker.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const typescript_1 = __importDefault(require("typescript")); const workerpool_1 = __importDefault(require("workerpool")); const staticLanguageServiceHost_1 = require("./staticLanguageServiceHost"); let service; function findRenameLocations(projectPath, fileName, position) { if (!service) { service = typescript_1.default.createLanguageService(new staticLanguageServiceHost_1.StaticLanguageServiceHost(projectPath)); } return service.findRenameLocations(fileName, position, false, false, { providePrefixAndSuffixTextForRename: true, }) ?? []; } workerpool_1.default.worker({ findRenameLocations }); //# sourceMappingURL=renameWorker.js.map ================================================ FILE: build/lib/mangle/renameWorker.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import ts from 'typescript'; import workerpool from 'workerpool'; import { StaticLanguageServiceHost } from './staticLanguageServiceHost'; let service: ts.LanguageService | undefined; function findRenameLocations( projectPath: string, fileName: string, position: number, ): readonly ts.RenameLocation[] { if (!service) { service = ts.createLanguageService(new StaticLanguageServiceHost(projectPath)); } return service.findRenameLocations(fileName, position, false, false, { providePrefixAndSuffixTextForRename: true, }) ?? []; } workerpool.worker({ findRenameLocations }); ================================================ FILE: build/lib/mangle/staticLanguageServiceHost.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StaticLanguageServiceHost = void 0; const typescript_1 = __importDefault(require("typescript")); const path_1 = __importDefault(require("path")); class StaticLanguageServiceHost { projectPath; _cmdLine; _scriptSnapshots = new Map(); constructor(projectPath) { this.projectPath = projectPath; const existingOptions = {}; const parsed = typescript_1.default.readConfigFile(projectPath, typescript_1.default.sys.readFile); if (parsed.error) { throw parsed.error; } this._cmdLine = typescript_1.default.parseJsonConfigFileContent(parsed.config, typescript_1.default.sys, path_1.default.dirname(projectPath), existingOptions); if (this._cmdLine.errors.length > 0) { throw parsed.error; } } getCompilationSettings() { return this._cmdLine.options; } getScriptFileNames() { return this._cmdLine.fileNames; } getScriptVersion(_fileName) { return '1'; } getProjectVersion() { return '1'; } getScriptSnapshot(fileName) { let result = this._scriptSnapshots.get(fileName); if (result === undefined) { const content = typescript_1.default.sys.readFile(fileName); if (content === undefined) { return undefined; } result = typescript_1.default.ScriptSnapshot.fromString(content); this._scriptSnapshots.set(fileName, result); } return result; } getCurrentDirectory() { return path_1.default.dirname(this.projectPath); } getDefaultLibFileName(options) { return typescript_1.default.getDefaultLibFilePath(options); } directoryExists = typescript_1.default.sys.directoryExists; getDirectories = typescript_1.default.sys.getDirectories; fileExists = typescript_1.default.sys.fileExists; readFile = typescript_1.default.sys.readFile; readDirectory = typescript_1.default.sys.readDirectory; // this is necessary to make source references work. realpath = typescript_1.default.sys.realpath; } exports.StaticLanguageServiceHost = StaticLanguageServiceHost; //# sourceMappingURL=staticLanguageServiceHost.js.map ================================================ FILE: build/lib/mangle/staticLanguageServiceHost.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import ts from 'typescript'; import path from 'path'; export class StaticLanguageServiceHost implements ts.LanguageServiceHost { private readonly _cmdLine: ts.ParsedCommandLine; private readonly _scriptSnapshots: Map = new Map(); constructor(readonly projectPath: string) { const existingOptions: Partial = {}; const parsed = ts.readConfigFile(projectPath, ts.sys.readFile); if (parsed.error) { throw parsed.error; } this._cmdLine = ts.parseJsonConfigFileContent(parsed.config, ts.sys, path.dirname(projectPath), existingOptions); if (this._cmdLine.errors.length > 0) { throw parsed.error; } } getCompilationSettings(): ts.CompilerOptions { return this._cmdLine.options; } getScriptFileNames(): string[] { return this._cmdLine.fileNames; } getScriptVersion(_fileName: string): string { return '1'; } getProjectVersion(): string { return '1'; } getScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined { let result: ts.IScriptSnapshot | undefined = this._scriptSnapshots.get(fileName); if (result === undefined) { const content = ts.sys.readFile(fileName); if (content === undefined) { return undefined; } result = ts.ScriptSnapshot.fromString(content); this._scriptSnapshots.set(fileName, result); } return result; } getCurrentDirectory(): string { return path.dirname(this.projectPath); } getDefaultLibFileName(options: ts.CompilerOptions): string { return ts.getDefaultLibFilePath(options); } directoryExists = ts.sys.directoryExists; getDirectories = ts.sys.getDirectories; fileExists = ts.sys.fileExists; readFile = ts.sys.readFile; readDirectory = ts.sys.readDirectory; // this is necessary to make source references work. realpath = ts.sys.realpath; } ================================================ FILE: build/lib/monaco-api.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DeclarationResolver = exports.FSProvider = exports.RECIPE_PATH = void 0; exports.run3 = run3; exports.execute = execute; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const dtsv = '3'; const tsfmt = require('../../tsfmt.json'); const SRC = path_1.default.join(__dirname, '../../src'); exports.RECIPE_PATH = path_1.default.join(__dirname, '../monaco/monaco.d.ts.recipe'); const DECLARATION_PATH = path_1.default.join(__dirname, '../../src/vs/monaco.d.ts'); function logErr(message, ...rest) { (0, fancy_log_1.default)(ansi_colors_1.default.yellow(`[monaco.d.ts]`), message, ...rest); } function isDeclaration(ts, a) { return (a.kind === ts.SyntaxKind.InterfaceDeclaration || a.kind === ts.SyntaxKind.EnumDeclaration || a.kind === ts.SyntaxKind.ClassDeclaration || a.kind === ts.SyntaxKind.TypeAliasDeclaration || a.kind === ts.SyntaxKind.FunctionDeclaration || a.kind === ts.SyntaxKind.ModuleDeclaration); } function visitTopLevelDeclarations(ts, sourceFile, visitor) { let stop = false; const visit = (node) => { if (stop) { return; } switch (node.kind) { case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.EnumDeclaration: case ts.SyntaxKind.ClassDeclaration: case ts.SyntaxKind.VariableStatement: case ts.SyntaxKind.TypeAliasDeclaration: case ts.SyntaxKind.FunctionDeclaration: case ts.SyntaxKind.ModuleDeclaration: stop = visitor(node); } if (stop) { return; } ts.forEachChild(node, visit); }; visit(sourceFile); } function getAllTopLevelDeclarations(ts, sourceFile) { const all = []; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) { const interfaceDeclaration = node; const triviaStart = interfaceDeclaration.pos; const triviaEnd = interfaceDeclaration.name.pos; const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); if (triviaText.indexOf('@internal') === -1) { all.push(node); } } else { const nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { all.push(node); } } return false /*continue*/; }); return all; } function getTopLevelDeclaration(ts, sourceFile, typeName) { let result = null; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (isDeclaration(ts, node) && node.name) { if (node.name.text === typeName) { result = node; return true /*stop*/; } return false /*continue*/; } // node is ts.VariableStatement if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) { result = node; return true /*stop*/; } return false /*continue*/; }); return result; } function getNodeText(sourceFile, node) { return sourceFile.getFullText().substring(node.pos, node.end); } function hasModifier(modifiers, kind) { if (modifiers) { for (let i = 0; i < modifiers.length; i++) { const mod = modifiers[i]; if (mod.kind === kind) { return true; } } } return false; } function isStatic(ts, member) { if (ts.canHaveModifiers(member)) { return hasModifier(ts.getModifiers(member), ts.SyntaxKind.StaticKeyword); } return false; } function isDefaultExport(ts, declaration) { return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword) && hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword)); } function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums) { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { const interfaceDeclaration = declaration; const staticTypeName = (isDefaultExport(ts, interfaceDeclaration) ? `${importName}.default` : `${importName}.${declaration.name.text}`); let instanceTypeName = staticTypeName; const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); if (typeParametersCnt > 0) { const arr = []; for (let i = 0; i < typeParametersCnt; i++) { arr.push('any'); } instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; } const members = interfaceDeclaration.members; members.forEach((member) => { try { const memberText = getNodeText(sourceFile, member); if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { result = result.replace(memberText, ''); } else { const memberName = member.name.text; const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); if (isStatic(ts, member)) { usage.push(`a = ${staticTypeName}${memberAccess};`); } else { usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); } } } catch (err) { // life.. } }); } result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); result = result.replace(/declare /g, ''); const lines = result.split(/\r\n|\r|\n/); for (let i = 0; i < lines.length; i++) { if (/\s*\*/.test(lines[i])) { // very likely a comment continue; } lines[i] = lines[i].replace(/"/g, '\''); } result = lines.join('\n'); if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { result = result.replace(/const enum/, 'enum'); enums.push({ enumName: declaration.name.getText(sourceFile), text: result }); } return result; } function format(ts, text, endl) { const REALLY_FORMAT = false; text = preformat(text, endl); if (!REALLY_FORMAT) { return text; } // Parse the source text const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); // Get the formatting edits on the input sources const edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); // Apply the edits on the input code return applyEdits(text, edits); function countParensCurly(text) { let cnt = 0; for (let i = 0; i < text.length; i++) { if (text.charAt(i) === '(' || text.charAt(i) === '{') { cnt++; } if (text.charAt(i) === ')' || text.charAt(i) === '}') { cnt--; } } return cnt; } function repeatStr(s, cnt) { let r = ''; for (let i = 0; i < cnt; i++) { r += s; } return r; } function preformat(text, endl) { const lines = text.split(endl); let inComment = false; let inCommentDeltaIndent = 0; let indent = 0; for (let i = 0; i < lines.length; i++) { let line = lines[i].replace(/\s$/, ''); let repeat = false; let lineIndent = 0; do { repeat = false; if (line.substring(0, 4) === ' ') { line = line.substring(4); lineIndent++; repeat = true; } if (line.charAt(0) === '\t') { line = line.substring(1); lineIndent++; repeat = true; } } while (repeat); if (line.length === 0) { continue; } if (inComment) { if (/\*\//.test(line)) { inComment = false; } lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line; continue; } if (/\/\*/.test(line)) { inComment = true; inCommentDeltaIndent = indent - lineIndent; lines[i] = repeatStr('\t', indent) + line; continue; } const cnt = countParensCurly(line); let shouldUnindentAfter = false; let shouldUnindentBefore = false; if (cnt < 0) { if (/[({]/.test(line)) { shouldUnindentAfter = true; } else { shouldUnindentBefore = true; } } else if (cnt === 0) { shouldUnindentBefore = /^\}/.test(line); } let shouldIndentAfter = false; if (cnt > 0) { shouldIndentAfter = true; } else if (cnt === 0) { shouldIndentAfter = /{$/.test(line); } if (shouldUnindentBefore) { indent--; } lines[i] = repeatStr('\t', indent) + line; if (shouldUnindentAfter) { indent--; } if (shouldIndentAfter) { indent++; } } return lines.join(endl); } function getRuleProvider(options) { // Share this between multiple formatters using the same options. // This represents the bulk of the space the formatter uses. return ts.formatting.getFormatContext(options); } function applyEdits(text, edits) { // Apply edits in reverse on the existing text let result = text; for (let i = edits.length - 1; i >= 0; i--) { const change = edits[i]; const head = result.slice(0, change.span.start); const tail = result.slice(change.span.start + change.span.length); result = head + change.newText + tail; } return result; } } function createReplacerFromDirectives(directives) { return (str) => { for (let i = 0; i < directives.length; i++) { str = str.replace(directives[i][0], directives[i][1]); } return str; }; } function createReplacer(data) { data = data || ''; const rawDirectives = data.split(';'); const directives = []; rawDirectives.forEach((rawDirective) => { if (rawDirective.length === 0) { return; } const pieces = rawDirective.split('=>'); let findStr = pieces[0]; const replaceStr = pieces[1]; findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); findStr = '\\b' + findStr + '\\b'; directives.push([new RegExp(findStr, 'g'), replaceStr]); }); return createReplacerFromDirectives(directives); } function generateDeclarationFile(ts, recipe, sourceFileGetter) { const endl = /\r\n/.test(recipe) ? '\r\n' : '\n'; const lines = recipe.split(endl); const result = []; let usageCounter = 0; const usageImports = []; const usage = []; let failed = false; usage.push(`var a: any;`); usage.push(`var b: any;`); const generateUsageImport = (moduleId) => { const importName = 'm' + (++usageCounter); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); return importName; }; const enums = []; let version = null; lines.forEach(line => { if (failed) { return; } const m0 = line.match(/^\/\/dtsv=(\d+)$/); if (m0) { version = m0[1]; } const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m1) { const moduleId = m1[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); logErr(`Cannot find ${moduleId}`); failed = true; return; } const importName = generateUsageImport(moduleId); const replacer = createReplacer(m1[2]); const typeNames = m1[3].split(/,/); typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } const declaration = getTopLevelDeclaration(ts, sourceFile, typeName); if (!declaration) { logErr(`While handling ${line}`); logErr(`Cannot find ${typeName}`); failed = true; return; } result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums))); }); return; } const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m2) { const moduleId = m2[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); logErr(`Cannot find ${moduleId}`); failed = true; return; } const importName = generateUsageImport(moduleId); const replacer = createReplacer(m2[2]); const typeNames = m2[3].split(/,/); const typesToExcludeMap = {}; const typesToExcludeArr = []; typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } typesToExcludeMap[typeName] = true; typesToExcludeArr.push(typeName); }); getAllTopLevelDeclarations(ts, sourceFile).forEach((declaration) => { if (isDeclaration(ts, declaration) && declaration.name) { if (typesToExcludeMap[declaration.name.text]) { return; } } else { // node is ts.VariableStatement const nodeText = getNodeText(sourceFile, declaration); for (let i = 0; i < typesToExcludeArr.length; i++) { if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) { return; } } } result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums))); }); return; } result.push(line); }); if (failed) { return null; } if (version !== dtsv) { if (!version) { logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`); } else { logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`); } return null; } let resultTxt = result.join(endl); resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri'); resultTxt = resultTxt.replace(/\bEvent { if (e1.enumName < e2.enumName) { return -1; } if (e1.enumName > e2.enumName) { return 1; } return 0; }); let resultEnums = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', '', '// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.', '' ].concat(enums.map(e => e.text)).join(endl); resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl); resultEnums = format(ts, resultEnums, endl); resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl); return { result: resultTxt, usageContent: `${usageImports.join('\n')}\n\n${usage.join('\n')}`, enums: resultEnums }; } function _run(ts, sourceFileGetter) { const recipe = fs_1.default.readFileSync(exports.RECIPE_PATH).toString(); const t = generateDeclarationFile(ts, recipe, sourceFileGetter); if (!t) { return null; } const result = t.result; const usageContent = t.usageContent; const enums = t.enums; const currentContent = fs_1.default.readFileSync(DECLARATION_PATH).toString(); const one = currentContent.replace(/\r\n/gm, '\n'); const other = result.replace(/\r\n/gm, '\n'); const isTheSame = (one === other); return { content: result, usageContent: usageContent, enums: enums, filePath: DECLARATION_PATH, isTheSame }; } class FSProvider { existsSync(filePath) { return fs_1.default.existsSync(filePath); } statSync(filePath) { return fs_1.default.statSync(filePath); } readFileSync(_moduleId, filePath) { return fs_1.default.readFileSync(filePath); } } exports.FSProvider = FSProvider; class CacheEntry { sourceFile; mtime; constructor(sourceFile, mtime) { this.sourceFile = sourceFile; this.mtime = mtime; } } class DeclarationResolver { _fsProvider; ts; _sourceFileCache; constructor(_fsProvider) { this._fsProvider = _fsProvider; this.ts = require('typescript'); this._sourceFileCache = Object.create(null); } invalidateCache(moduleId) { this._sourceFileCache[moduleId] = null; } getDeclarationSourceFile(moduleId) { if (this._sourceFileCache[moduleId]) { // Since we cannot trust file watching to invalidate the cache, check also the mtime const fileName = this._getFileName(moduleId); const mtime = this._fsProvider.statSync(fileName).mtime.getTime(); if (this._sourceFileCache[moduleId].mtime !== mtime) { this._sourceFileCache[moduleId] = null; } } if (!this._sourceFileCache[moduleId]) { this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId); } return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId].sourceFile : null; } _getFileName(moduleId) { if (/\.d\.ts$/.test(moduleId)) { return path_1.default.join(SRC, moduleId); } return path_1.default.join(SRC, `${moduleId}.ts`); } _getDeclarationSourceFile(moduleId) { const fileName = this._getFileName(moduleId); if (!this._fsProvider.existsSync(fileName)) { return null; } const mtime = this._fsProvider.statSync(fileName).mtime.getTime(); if (/\.d\.ts$/.test(moduleId)) { // const mtime = this._fsProvider.statFileSync() const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString(); return new CacheEntry(this.ts.createSourceFile(fileName, fileContents, this.ts.ScriptTarget.ES5), mtime); } const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString(); const fileMap = { 'file.ts': fileContents }; const service = this.ts.createLanguageService(new TypeScriptLanguageServiceHost(this.ts, {}, fileMap, {})); const text = service.getEmitOutput('file.ts', true, true).outputFiles[0].text; return new CacheEntry(this.ts.createSourceFile(fileName, text, this.ts.ScriptTarget.ES5), mtime); } } exports.DeclarationResolver = DeclarationResolver; function run3(resolver) { const sourceFileGetter = (moduleId) => resolver.getDeclarationSourceFile(moduleId); return _run(resolver.ts, sourceFileGetter); } class TypeScriptLanguageServiceHost { _ts; _libs; _files; _compilerOptions; constructor(ts, libs, files, compilerOptions) { this._ts = ts; this._libs = libs; this._files = files; this._compilerOptions = compilerOptions; } // --- language service host --------------- getCompilationSettings() { return this._compilerOptions; } getScriptFileNames() { return ([] .concat(Object.keys(this._libs)) .concat(Object.keys(this._files))); } getScriptVersion(_fileName) { return '1'; } getProjectVersion() { return '1'; } getScriptSnapshot(fileName) { if (this._files.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._files[fileName]); } else if (this._libs.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._libs[fileName]); } else { return this._ts.ScriptSnapshot.fromString(''); } } getScriptKind(_fileName) { return this._ts.ScriptKind.TS; } getCurrentDirectory() { return ''; } getDefaultLibFileName(_options) { return 'defaultLib:es5'; } isDefaultLibFileName(fileName) { return fileName === this.getDefaultLibFileName(this._compilerOptions); } readFile(path, _encoding) { return this._files[path] || this._libs[path]; } fileExists(path) { return path in this._files || path in this._libs; } } function execute() { const r = run3(new DeclarationResolver(new FSProvider())); if (!r) { throw new Error(`monaco.d.ts generation error - Cannot continue`); } return r; } //# sourceMappingURL=monaco-api.js.map ================================================ FILE: build/lib/monaco-api.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import type * as ts from 'typescript'; import path from 'path'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; const dtsv = '3'; const tsfmt = require('../../tsfmt.json'); const SRC = path.join(__dirname, '../../src'); export const RECIPE_PATH = path.join(__dirname, '../monaco/monaco.d.ts.recipe'); const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts'); function logErr(message: any, ...rest: any[]): void { fancyLog(ansiColors.yellow(`[monaco.d.ts]`), message, ...rest); } type SourceFileGetter = (moduleId: string) => ts.SourceFile | null; type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ModuleDeclaration; type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement; function isDeclaration(ts: typeof import('typescript'), a: TSTopLevelDeclare): a is TSTopLevelDeclaration { return ( a.kind === ts.SyntaxKind.InterfaceDeclaration || a.kind === ts.SyntaxKind.EnumDeclaration || a.kind === ts.SyntaxKind.ClassDeclaration || a.kind === ts.SyntaxKind.TypeAliasDeclaration || a.kind === ts.SyntaxKind.FunctionDeclaration || a.kind === ts.SyntaxKind.ModuleDeclaration ); } function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void { let stop = false; const visit = (node: ts.Node): void => { if (stop) { return; } switch (node.kind) { case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.EnumDeclaration: case ts.SyntaxKind.ClassDeclaration: case ts.SyntaxKind.VariableStatement: case ts.SyntaxKind.TypeAliasDeclaration: case ts.SyntaxKind.FunctionDeclaration: case ts.SyntaxKind.ModuleDeclaration: stop = visitor(node); } if (stop) { return; } ts.forEachChild(node, visit); }; visit(sourceFile); } function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TSTopLevelDeclare[] { const all: TSTopLevelDeclare[] = []; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) { const interfaceDeclaration = node; const triviaStart = interfaceDeclaration.pos; const triviaEnd = interfaceDeclaration.name.pos; const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); if (triviaText.indexOf('@internal') === -1) { all.push(node); } } else { const nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { all.push(node); } } return false /*continue*/; }); return all; } function getTopLevelDeclaration(ts: typeof import('typescript'), sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare | null { let result: TSTopLevelDeclare | null = null; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (isDeclaration(ts, node) && node.name) { if (node.name.text === typeName) { result = node; return true /*stop*/; } return false /*continue*/; } // node is ts.VariableStatement if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) { result = node; return true /*stop*/; } return false /*continue*/; }); return result; } function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number }): string { return sourceFile.getFullText().substring(node.pos, node.end); } function hasModifier(modifiers: readonly ts.ModifierLike[] | undefined, kind: ts.SyntaxKind): boolean { if (modifiers) { for (let i = 0; i < modifiers.length; i++) { const mod = modifiers[i]; if (mod.kind === kind) { return true; } } } return false; } function isStatic(ts: typeof import('typescript'), member: ts.ClassElement | ts.TypeElement): boolean { if (ts.canHaveModifiers(member)) { return hasModifier(ts.getModifiers(member), ts.SyntaxKind.StaticKeyword); } return false; } function isDefaultExport(ts: typeof import('typescript'), declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean { return ( hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword) && hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword) ); } function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { const interfaceDeclaration = declaration; const staticTypeName = ( isDefaultExport(ts, interfaceDeclaration) ? `${importName}.default` : `${importName}.${declaration.name!.text}` ); let instanceTypeName = staticTypeName; const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); if (typeParametersCnt > 0) { const arr: string[] = []; for (let i = 0; i < typeParametersCnt; i++) { arr.push('any'); } instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; } const members: ts.NodeArray = interfaceDeclaration.members; members.forEach((member) => { try { const memberText = getNodeText(sourceFile, member); if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { result = result.replace(memberText, ''); } else { const memberName = (member.name).text; const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); if (isStatic(ts, member)) { usage.push(`a = ${staticTypeName}${memberAccess};`); } else { usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); } } } catch (err) { // life.. } }); } result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); result = result.replace(/declare /g, ''); const lines = result.split(/\r\n|\r|\n/); for (let i = 0; i < lines.length; i++) { if (/\s*\*/.test(lines[i])) { // very likely a comment continue; } lines[i] = lines[i].replace(/"/g, '\''); } result = lines.join('\n'); if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { result = result.replace(/const enum/, 'enum'); enums.push({ enumName: declaration.name.getText(sourceFile), text: result }); } return result; } function format(ts: typeof import('typescript'), text: string, endl: string): string { const REALLY_FORMAT = false; text = preformat(text, endl); if (!REALLY_FORMAT) { return text; } // Parse the source text const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); // Get the formatting edits on the input sources const edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); // Apply the edits on the input code return applyEdits(text, edits); function countParensCurly(text: string): number { let cnt = 0; for (let i = 0; i < text.length; i++) { if (text.charAt(i) === '(' || text.charAt(i) === '{') { cnt++; } if (text.charAt(i) === ')' || text.charAt(i) === '}') { cnt--; } } return cnt; } function repeatStr(s: string, cnt: number): string { let r = ''; for (let i = 0; i < cnt; i++) { r += s; } return r; } function preformat(text: string, endl: string): string { const lines = text.split(endl); let inComment = false; let inCommentDeltaIndent = 0; let indent = 0; for (let i = 0; i < lines.length; i++) { let line = lines[i].replace(/\s$/, ''); let repeat = false; let lineIndent = 0; do { repeat = false; if (line.substring(0, 4) === ' ') { line = line.substring(4); lineIndent++; repeat = true; } if (line.charAt(0) === '\t') { line = line.substring(1); lineIndent++; repeat = true; } } while (repeat); if (line.length === 0) { continue; } if (inComment) { if (/\*\//.test(line)) { inComment = false; } lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line; continue; } if (/\/\*/.test(line)) { inComment = true; inCommentDeltaIndent = indent - lineIndent; lines[i] = repeatStr('\t', indent) + line; continue; } const cnt = countParensCurly(line); let shouldUnindentAfter = false; let shouldUnindentBefore = false; if (cnt < 0) { if (/[({]/.test(line)) { shouldUnindentAfter = true; } else { shouldUnindentBefore = true; } } else if (cnt === 0) { shouldUnindentBefore = /^\}/.test(line); } let shouldIndentAfter = false; if (cnt > 0) { shouldIndentAfter = true; } else if (cnt === 0) { shouldIndentAfter = /{$/.test(line); } if (shouldUnindentBefore) { indent--; } lines[i] = repeatStr('\t', indent) + line; if (shouldUnindentAfter) { indent--; } if (shouldIndentAfter) { indent++; } } return lines.join(endl); } function getRuleProvider(options: ts.FormatCodeSettings) { // Share this between multiple formatters using the same options. // This represents the bulk of the space the formatter uses. return (ts as any).formatting.getFormatContext(options); } function applyEdits(text: string, edits: ts.TextChange[]): string { // Apply edits in reverse on the existing text let result = text; for (let i = edits.length - 1; i >= 0; i--) { const change = edits[i]; const head = result.slice(0, change.span.start); const tail = result.slice(change.span.start + change.span.length); result = head + change.newText + tail; } return result; } } function createReplacerFromDirectives(directives: [RegExp, string][]): (str: string) => string { return (str: string) => { for (let i = 0; i < directives.length; i++) { str = str.replace(directives[i][0], directives[i][1]); } return str; }; } function createReplacer(data: string): (str: string) => string { data = data || ''; const rawDirectives = data.split(';'); const directives: [RegExp, string][] = []; rawDirectives.forEach((rawDirective) => { if (rawDirective.length === 0) { return; } const pieces = rawDirective.split('=>'); let findStr = pieces[0]; const replaceStr = pieces[1]; findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); findStr = '\\b' + findStr + '\\b'; directives.push([new RegExp(findStr, 'g'), replaceStr]); }); return createReplacerFromDirectives(directives); } interface ITempResult { result: string; usageContent: string; enums: string; } interface IEnumEntry { enumName: string; text: string; } function generateDeclarationFile(ts: typeof import('typescript'), recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null { const endl = /\r\n/.test(recipe) ? '\r\n' : '\n'; const lines = recipe.split(endl); const result: string[] = []; let usageCounter = 0; const usageImports: string[] = []; const usage: string[] = []; let failed = false; usage.push(`var a: any;`); usage.push(`var b: any;`); const generateUsageImport = (moduleId: string) => { const importName = 'm' + (++usageCounter); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); return importName; }; const enums: IEnumEntry[] = []; let version: string | null = null; lines.forEach(line => { if (failed) { return; } const m0 = line.match(/^\/\/dtsv=(\d+)$/); if (m0) { version = m0[1]; } const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m1) { const moduleId = m1[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); logErr(`Cannot find ${moduleId}`); failed = true; return; } const importName = generateUsageImport(moduleId); const replacer = createReplacer(m1[2]); const typeNames = m1[3].split(/,/); typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } const declaration = getTopLevelDeclaration(ts, sourceFile, typeName); if (!declaration) { logErr(`While handling ${line}`); logErr(`Cannot find ${typeName}`); failed = true; return; } result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums))); }); return; } const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m2) { const moduleId = m2[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); logErr(`Cannot find ${moduleId}`); failed = true; return; } const importName = generateUsageImport(moduleId); const replacer = createReplacer(m2[2]); const typeNames = m2[3].split(/,/); const typesToExcludeMap: { [typeName: string]: boolean } = {}; const typesToExcludeArr: string[] = []; typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } typesToExcludeMap[typeName] = true; typesToExcludeArr.push(typeName); }); getAllTopLevelDeclarations(ts, sourceFile).forEach((declaration) => { if (isDeclaration(ts, declaration) && declaration.name) { if (typesToExcludeMap[declaration.name.text]) { return; } } else { // node is ts.VariableStatement const nodeText = getNodeText(sourceFile, declaration); for (let i = 0; i < typesToExcludeArr.length; i++) { if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) { return; } } } result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums))); }); return; } result.push(line); }); if (failed) { return null; } if (version !== dtsv) { if (!version) { logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`); } else { logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`); } return null; } let resultTxt = result.join(endl); resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri'); resultTxt = resultTxt.replace(/\bEvent { if (e1.enumName < e2.enumName) { return -1; } if (e1.enumName > e2.enumName) { return 1; } return 0; }); let resultEnums = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', '', '// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.', '' ].concat(enums.map(e => e.text)).join(endl); resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl); resultEnums = format(ts, resultEnums, endl); resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl); return { result: resultTxt, usageContent: `${usageImports.join('\n')}\n\n${usage.join('\n')}`, enums: resultEnums }; } export interface IMonacoDeclarationResult { content: string; usageContent: string; enums: string; filePath: string; isTheSame: boolean; } function _run(ts: typeof import('typescript'), sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult | null { const recipe = fs.readFileSync(RECIPE_PATH).toString(); const t = generateDeclarationFile(ts, recipe, sourceFileGetter); if (!t) { return null; } const result = t.result; const usageContent = t.usageContent; const enums = t.enums; const currentContent = fs.readFileSync(DECLARATION_PATH).toString(); const one = currentContent.replace(/\r\n/gm, '\n'); const other = result.replace(/\r\n/gm, '\n'); const isTheSame = (one === other); return { content: result, usageContent: usageContent, enums: enums, filePath: DECLARATION_PATH, isTheSame }; } export class FSProvider { public existsSync(filePath: string): boolean { return fs.existsSync(filePath); } public statSync(filePath: string): fs.Stats { return fs.statSync(filePath); } public readFileSync(_moduleId: string, filePath: string): Buffer { return fs.readFileSync(filePath); } } class CacheEntry { constructor( public readonly sourceFile: ts.SourceFile, public readonly mtime: number ) { } } export class DeclarationResolver { public readonly ts: typeof import('typescript'); private _sourceFileCache: { [moduleId: string]: CacheEntry | null }; constructor(private readonly _fsProvider: FSProvider) { this.ts = require('typescript') as typeof import('typescript'); this._sourceFileCache = Object.create(null); } public invalidateCache(moduleId: string): void { this._sourceFileCache[moduleId] = null; } public getDeclarationSourceFile(moduleId: string): ts.SourceFile | null { if (this._sourceFileCache[moduleId]) { // Since we cannot trust file watching to invalidate the cache, check also the mtime const fileName = this._getFileName(moduleId); const mtime = this._fsProvider.statSync(fileName).mtime.getTime(); if (this._sourceFileCache[moduleId]!.mtime !== mtime) { this._sourceFileCache[moduleId] = null; } } if (!this._sourceFileCache[moduleId]) { this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId); } return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId]!.sourceFile : null; } private _getFileName(moduleId: string): string { if (/\.d\.ts$/.test(moduleId)) { return path.join(SRC, moduleId); } return path.join(SRC, `${moduleId}.ts`); } private _getDeclarationSourceFile(moduleId: string): CacheEntry | null { const fileName = this._getFileName(moduleId); if (!this._fsProvider.existsSync(fileName)) { return null; } const mtime = this._fsProvider.statSync(fileName).mtime.getTime(); if (/\.d\.ts$/.test(moduleId)) { // const mtime = this._fsProvider.statFileSync() const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString(); return new CacheEntry( this.ts.createSourceFile(fileName, fileContents, this.ts.ScriptTarget.ES5), mtime ); } const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString(); const fileMap: IFileMap = { 'file.ts': fileContents }; const service = this.ts.createLanguageService(new TypeScriptLanguageServiceHost(this.ts, {}, fileMap, {})); const text = service.getEmitOutput('file.ts', true, true).outputFiles[0].text; return new CacheEntry( this.ts.createSourceFile(fileName, text, this.ts.ScriptTarget.ES5), mtime ); } } export function run3(resolver: DeclarationResolver): IMonacoDeclarationResult | null { const sourceFileGetter = (moduleId: string) => resolver.getDeclarationSourceFile(moduleId); return _run(resolver.ts, sourceFileGetter); } interface ILibMap { [libName: string]: string } interface IFileMap { [fileName: string]: string } class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost { private readonly _ts: typeof import('typescript'); private readonly _libs: ILibMap; private readonly _files: IFileMap; private readonly _compilerOptions: ts.CompilerOptions; constructor(ts: typeof import('typescript'), libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) { this._ts = ts; this._libs = libs; this._files = files; this._compilerOptions = compilerOptions; } // --- language service host --------------- getCompilationSettings(): ts.CompilerOptions { return this._compilerOptions; } getScriptFileNames(): string[] { return ( ([] as string[]) .concat(Object.keys(this._libs)) .concat(Object.keys(this._files)) ); } getScriptVersion(_fileName: string): string { return '1'; } getProjectVersion(): string { return '1'; } getScriptSnapshot(fileName: string): ts.IScriptSnapshot { if (this._files.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._files[fileName]); } else if (this._libs.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._libs[fileName]); } else { return this._ts.ScriptSnapshot.fromString(''); } } getScriptKind(_fileName: string): ts.ScriptKind { return this._ts.ScriptKind.TS; } getCurrentDirectory(): string { return ''; } getDefaultLibFileName(_options: ts.CompilerOptions): string { return 'defaultLib:es5'; } isDefaultLibFileName(fileName: string): boolean { return fileName === this.getDefaultLibFileName(this._compilerOptions); } readFile(path: string, _encoding?: string): string | undefined { return this._files[path] || this._libs[path]; } fileExists(path: string): boolean { return path in this._files || path in this._libs; } } export function execute(): IMonacoDeclarationResult { const r = run3(new DeclarationResolver(new FSProvider())); if (!r) { throw new Error(`monaco.d.ts generation error - Cannot continue`); } return r; } ================================================ FILE: build/lib/nls.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.nls = nls; const lazy_js_1 = __importDefault(require("lazy.js")); const event_stream_1 = require("event-stream"); const vinyl_1 = __importDefault(require("vinyl")); const source_map_1 = __importDefault(require("source-map")); const path_1 = __importDefault(require("path")); const gulp_sort_1 = __importDefault(require("gulp-sort")); var CollectStepResult; (function (CollectStepResult) { CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes"; CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse"; CollectStepResult[CollectStepResult["No"] = 2] = "No"; CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse"; })(CollectStepResult || (CollectStepResult = {})); function collect(ts, node, fn) { const result = []; function loop(node) { const stepResult = fn(node); if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) { result.push(node); } if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) { ts.forEachChild(node, loop); } } loop(node); return result; } function clone(object) { const result = {}; for (const id in object) { result[id] = object[id]; } return result; } /** * Returns a stream containing the patched JavaScript and source maps. */ function nls(options) { let base; const input = (0, event_stream_1.through)(); const output = input .pipe((0, gulp_sort_1.default)()) // IMPORTANT: to ensure stable NLS metadata generation, we must sort the files because NLS messages are globally extracted and indexed across all files .pipe((0, event_stream_1.through)(function (f) { if (!f.sourceMap) { return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`)); } let source = f.sourceMap.sources[0]; if (!source) { return this.emit('error', new Error(`File ${f.relative} does not have a source in the source map.`)); } const root = f.sourceMap.sourceRoot; if (root) { source = path_1.default.join(root, source); } const typescript = f.sourceMap.sourcesContent[0]; if (!typescript) { return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`)); } base = f.base; this.emit('data', _nls.patchFile(f, typescript, options)); }, function () { for (const file of [ new vinyl_1.default({ contents: Buffer.from(JSON.stringify({ keys: _nls.moduleToNLSKeys, messages: _nls.moduleToNLSMessages, }, null, '\t')), base, path: `${base}/nls.metadata.json` }), new vinyl_1.default({ contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), base, path: `${base}/nls.messages.json` }), new vinyl_1.default({ contents: Buffer.from(JSON.stringify(_nls.allNLSModulesAndKeys)), base, path: `${base}/nls.keys.json` }), new vinyl_1.default({ contents: Buffer.from(`/*--------------------------------------------------------- * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), base, path: `${base}/nls.messages.js` }) ]) { this.emit('data', file); } this.emit('end'); })); return (0, event_stream_1.duplex)(input, output); } function isImportNode(ts, node) { return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration; } var _nls; (function (_nls) { _nls.moduleToNLSKeys = {}; _nls.moduleToNLSMessages = {}; _nls.allNLSMessages = []; _nls.allNLSModulesAndKeys = []; let allNLSMessagesIndex = 0; function fileFrom(file, contents, path = file.path) { return new vinyl_1.default({ contents: Buffer.from(contents), base: file.base, cwd: file.cwd, path: path }); } function mappedPositionFrom(source, lc) { return { source, line: lc.line + 1, column: lc.character }; } function lcFrom(position) { return { line: position.line - 1, character: position.column }; } class SingleFileServiceHost { options; filename; file; lib; constructor(ts, options, filename, contents) { this.options = options; this.filename = filename; this.file = ts.ScriptSnapshot.fromString(contents); this.lib = ts.ScriptSnapshot.fromString(''); } getCompilationSettings = () => this.options; getScriptFileNames = () => [this.filename]; getScriptVersion = () => '1'; getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib; getCurrentDirectory = () => ''; getDefaultLibFileName = () => 'lib.d.ts'; readFile(path, _encoding) { if (path === this.filename) { return this.file.getText(0, this.file.getLength()); } return undefined; } fileExists(path) { return path === this.filename; } } function isCallExpressionWithinTextSpanCollectStep(ts, textSpan, node) { if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) { return CollectStepResult.No; } return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; } function analyze(ts, contents, functionName, options = {}) { const filename = 'file.ts'; const serviceHost = new SingleFileServiceHost(ts, Object.assign(clone(options), { noResolve: true }), filename, contents); const service = ts.createLanguageService(serviceHost); const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true); // all imports const imports = (0, lazy_js_1.default)(collect(ts, sourceFile, n => isImportNode(ts, n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse)); // import nls = require('vs/nls'); const importEqualsDeclarations = imports .filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration) .map(n => n) .filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) .filter(d => d.moduleReference.expression.getText().endsWith(`/nls.js'`)); // import ... from 'vs/nls'; const importDeclarations = imports .filter(n => n.kind === ts.SyntaxKind.ImportDeclaration) .map(n => n) .filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral) .filter(d => d.moduleSpecifier.getText().endsWith(`/nls.js'`)) .filter(d => !!d.importClause && !!d.importClause.namedBindings); // `nls.localize(...)` calls const nlsLocalizeCallExpressions = importDeclarations .filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport)) .map(d => d.importClause.namedBindings.name) .concat(importEqualsDeclarations.map(d => d.name)) // find read-only references to `nls` .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) .flatten() .filter(r => !r.isWriteAccess) // find the deepest call expressions AST nodes that contain those references .map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n))) .map(a => (0, lazy_js_1.default)(a).last()) .filter(n => !!n) .map(n => n) // only `localize` calls .filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === functionName); // `localize` named imports const allLocalizeImportDeclarations = importDeclarations .filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)) .map(d => [].concat(d.importClause.namedBindings.elements)) .flatten(); // `localize` read-only references const localizeReferences = allLocalizeImportDeclarations .filter(d => d.name.getText() === functionName) .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) .flatten() .filter(r => !r.isWriteAccess); // custom named `localize` read-only references const namedLocalizeReferences = allLocalizeImportDeclarations .filter(d => d.propertyName && d.propertyName.getText() === functionName) .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1)) .flatten() .filter(r => !r.isWriteAccess); // find the deepest call expressions AST nodes that contain those references const localizeCallExpressions = localizeReferences .concat(namedLocalizeReferences) .map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n))) .map(a => (0, lazy_js_1.default)(a).last()) .filter(n => !!n) .map(n => n); // collect everything const localizeCalls = nlsLocalizeCallExpressions .concat(localizeCallExpressions) .map(e => e.arguments) .filter(a => a.length > 1) .sort((a, b) => a[0].getStart() - b[0].getStart()) .map(a => ({ keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, key: a[0].getText(), valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, value: a[1].getText() })); return { localizeCalls: localizeCalls.toArray() }; } class TextModel { lines; lineEndings; constructor(contents) { const regex = /\r\n|\r|\n/g; let index = 0; let match; this.lines = []; this.lineEndings = []; while (match = regex.exec(contents)) { this.lines.push(contents.substring(index, match.index)); this.lineEndings.push(match[0]); index = regex.lastIndex; } if (contents.length > 0) { this.lines.push(contents.substring(index, contents.length)); this.lineEndings.push(''); } } get(index) { return this.lines[index]; } set(index, line) { this.lines[index] = line; } get lineCount() { return this.lines.length; } /** * Applies patch(es) to the model. * Multiple patches must be ordered. * Does not support patches spanning multiple lines. */ apply(patch) { const startLineNumber = patch.span.start.line; const endLineNumber = patch.span.end.line; const startLine = this.lines[startLineNumber] || ''; const endLine = this.lines[endLineNumber] || ''; this.lines[startLineNumber] = [ startLine.substring(0, patch.span.start.character), patch.content, endLine.substring(patch.span.end.character) ].join(''); for (let i = startLineNumber + 1; i <= endLineNumber; i++) { this.lines[i] = ''; } } toString() { return (0, lazy_js_1.default)(this.lines).zip(this.lineEndings) .flatten().toArray().join(''); } } function patchJavascript(patches, contents) { const model = new TextModel(contents); // patch the localize calls (0, lazy_js_1.default)(patches).reverse().each(p => model.apply(p)); return model.toString(); } function patchSourcemap(patches, rsm, smc) { const smg = new source_map_1.default.SourceMapGenerator({ file: rsm.file, sourceRoot: rsm.sourceRoot }); patches = patches.reverse(); let currentLine = -1; let currentLineDiff = 0; let source = null; smc.eachMapping(m => { const patch = patches[patches.length - 1]; const original = { line: m.originalLine, column: m.originalColumn }; const generated = { line: m.generatedLine, column: m.generatedColumn }; if (currentLine !== generated.line) { currentLineDiff = 0; } currentLine = generated.line; generated.column += currentLineDiff; if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) { const originalLength = patch.span.end.character - patch.span.start.character; const modifiedLength = patch.content.length; const lengthDiff = modifiedLength - originalLength; currentLineDiff += lengthDiff; generated.column += lengthDiff; patches.pop(); } source = rsm.sourceRoot ? path_1.default.relative(rsm.sourceRoot, m.source) : m.source; source = source.replace(/\\/g, '/'); smg.addMapping({ source, name: m.name, original, generated }); }, null, source_map_1.default.SourceMapConsumer.GENERATED_ORDER); if (source) { smg.setSourceContent(source, smc.sourceContentFor(source)); } return JSON.parse(smg.toString()); } function parseLocalizeKeyOrValue(sourceExpression) { // sourceValue can be "foo", 'foo', `foo` or { .... } // in its evalulated form // we want to return either the string or the object // eslint-disable-next-line no-eval return eval(`(${sourceExpression})`); } function patch(ts, typescript, javascript, sourcemap, options) { const { localizeCalls } = analyze(ts, typescript, 'localize'); const { localizeCalls: localize2Calls } = analyze(ts, typescript, 'localize2'); if (localizeCalls.length === 0 && localize2Calls.length === 0) { return { javascript, sourcemap }; } const nlsKeys = localizeCalls.map(lc => parseLocalizeKeyOrValue(lc.key)).concat(localize2Calls.map(lc => parseLocalizeKeyOrValue(lc.key))); const nlsMessages = localizeCalls.map(lc => parseLocalizeKeyOrValue(lc.value)).concat(localize2Calls.map(lc => parseLocalizeKeyOrValue(lc.value))); const smc = new source_map_1.default.SourceMapConsumer(sourcemap); const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]); // build patches const toPatch = (c) => { const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start))); const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end))); return { span: { start, end }, content: c.content }; }; const localizePatches = (0, lazy_js_1.default)(localizeCalls) .map(lc => (options.preserveEnglish ? [ { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") ] : [ { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) { range: lc.valueSpan, content: 'null' } ])) .flatten() .map(toPatch); const localize2Patches = (0, lazy_js_1.default)(localize2Calls) .map(lc => ({ range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize2('key', "message") => localize(, "message") )) .map(toPatch); // Sort patches by their start position const patches = localizePatches.concat(localize2Patches).toArray().sort((a, b) => { if (a.span.start.line < b.span.start.line) { return -1; } else if (a.span.start.line > b.span.start.line) { return 1; } else if (a.span.start.character < b.span.start.character) { return -1; } else if (a.span.start.character > b.span.start.character) { return 1; } else { return 0; } }); javascript = patchJavascript(patches, javascript); sourcemap = patchSourcemap(patches, sourcemap, smc); return { javascript, sourcemap, nlsKeys, nlsMessages }; } function patchFile(javascriptFile, typescript, options) { const ts = require('typescript'); // hack? const moduleId = javascriptFile.relative .replace(/\.js$/, '') .replace(/\\/g, '/'); const { javascript, sourcemap, nlsKeys, nlsMessages } = patch(ts, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap, options); const result = fileFrom(javascriptFile, javascript); result.sourceMap = sourcemap; if (nlsKeys) { _nls.moduleToNLSKeys[moduleId] = nlsKeys; _nls.allNLSModulesAndKeys.push([moduleId, nlsKeys.map(nlsKey => typeof nlsKey === 'string' ? nlsKey : nlsKey.key)]); } if (nlsMessages) { _nls.moduleToNLSMessages[moduleId] = nlsMessages; _nls.allNLSMessages.push(...nlsMessages); } return result; } _nls.patchFile = patchFile; })(_nls || (_nls = {})); //# sourceMappingURL=nls.js.map ================================================ FILE: build/lib/nls.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import type * as ts from 'typescript'; import lazy from 'lazy.js'; import { duplex, through } from 'event-stream'; import File from 'vinyl'; import sm from 'source-map'; import path from 'path'; import sort from 'gulp-sort'; declare class FileSourceMap extends File { public sourceMap: sm.RawSourceMap; } enum CollectStepResult { Yes, YesAndRecurse, No, NoAndRecurse } function collect(ts: typeof import('typescript'), node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.Node[] { const result: ts.Node[] = []; function loop(node: ts.Node) { const stepResult = fn(node); if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) { result.push(node); } if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) { ts.forEachChild(node, loop); } } loop(node); return result; } function clone(object: T): T { const result = {} as any as T; for (const id in object) { result[id] = object[id]; } return result; } /** * Returns a stream containing the patched JavaScript and source maps. */ export function nls(options: { preserveEnglish: boolean }): NodeJS.ReadWriteStream { let base: string; const input = through(); const output = input .pipe(sort()) // IMPORTANT: to ensure stable NLS metadata generation, we must sort the files because NLS messages are globally extracted and indexed across all files .pipe(through(function (f: FileSourceMap) { if (!f.sourceMap) { return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`)); } let source = f.sourceMap.sources[0]; if (!source) { return this.emit('error', new Error(`File ${f.relative} does not have a source in the source map.`)); } const root = f.sourceMap.sourceRoot; if (root) { source = path.join(root, source); } const typescript = f.sourceMap.sourcesContent![0]; if (!typescript) { return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`)); } base = f.base; this.emit('data', _nls.patchFile(f, typescript, options)); }, function () { for (const file of [ new File({ contents: Buffer.from(JSON.stringify({ keys: _nls.moduleToNLSKeys, messages: _nls.moduleToNLSMessages, }, null, '\t')), base, path: `${base}/nls.metadata.json` }), new File({ contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), base, path: `${base}/nls.messages.json` }), new File({ contents: Buffer.from(JSON.stringify(_nls.allNLSModulesAndKeys)), base, path: `${base}/nls.keys.json` }), new File({ contents: Buffer.from(`/*--------------------------------------------------------- * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), base, path: `${base}/nls.messages.js` }) ]) { this.emit('data', file); } this.emit('end'); })); return duplex(input, output); } function isImportNode(ts: typeof import('typescript'), node: ts.Node): boolean { return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration; } module _nls { export const moduleToNLSKeys: { [name: string /* module ID */]: ILocalizeKey[] /* keys */ } = {}; export const moduleToNLSMessages: { [name: string /* module ID */]: string[] /* messages */ } = {}; export const allNLSMessages: string[] = []; export const allNLSModulesAndKeys: Array<[string /* module ID */, string[] /* keys */]> = []; let allNLSMessagesIndex = 0; type ILocalizeKey = string | { key: string }; // key might contain metadata for translators and then is not just a string interface INlsPatchResult { javascript: string; sourcemap: sm.RawSourceMap; nlsMessages?: string[]; nlsKeys?: ILocalizeKey[]; } interface ISpan { start: ts.LineAndCharacter; end: ts.LineAndCharacter; } interface ILocalizeCall { keySpan: ISpan; key: string; valueSpan: ISpan; value: string; } interface ILocalizeAnalysisResult { localizeCalls: ILocalizeCall[]; } interface IPatch { span: ISpan; content: string; } function fileFrom(file: File, contents: string, path: string = file.path) { return new File({ contents: Buffer.from(contents), base: file.base, cwd: file.cwd, path: path }); } function mappedPositionFrom(source: string, lc: ts.LineAndCharacter): sm.MappedPosition { return { source, line: lc.line + 1, column: lc.character }; } function lcFrom(position: sm.Position): ts.LineAndCharacter { return { line: position.line - 1, character: position.column }; } class SingleFileServiceHost implements ts.LanguageServiceHost { private file: ts.IScriptSnapshot; private lib: ts.IScriptSnapshot; constructor(ts: typeof import('typescript'), private options: ts.CompilerOptions, private filename: string, contents: string) { this.file = ts.ScriptSnapshot.fromString(contents); this.lib = ts.ScriptSnapshot.fromString(''); } getCompilationSettings = () => this.options; getScriptFileNames = () => [this.filename]; getScriptVersion = () => '1'; getScriptSnapshot = (name: string) => name === this.filename ? this.file : this.lib; getCurrentDirectory = () => ''; getDefaultLibFileName = () => 'lib.d.ts'; readFile(path: string, _encoding?: string): string | undefined { if (path === this.filename) { return this.file.getText(0, this.file.getLength()); } return undefined; } fileExists(path: string): boolean { return path === this.filename; } } function isCallExpressionWithinTextSpanCollectStep(ts: typeof import('typescript'), textSpan: ts.TextSpan, node: ts.Node): CollectStepResult { if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) { return CollectStepResult.No; } return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; } function analyze( ts: typeof import('typescript'), contents: string, functionName: 'localize' | 'localize2', options: ts.CompilerOptions = {} ): ILocalizeAnalysisResult { const filename = 'file.ts'; const serviceHost = new SingleFileServiceHost(ts, Object.assign(clone(options), { noResolve: true }), filename, contents); const service = ts.createLanguageService(serviceHost); const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true); // all imports const imports = lazy(collect(ts, sourceFile, n => isImportNode(ts, n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse)); // import nls = require('vs/nls'); const importEqualsDeclarations = imports .filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration) .map(n => n) .filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) .filter(d => (d.moduleReference).expression.getText().endsWith(`/nls.js'`)); // import ... from 'vs/nls'; const importDeclarations = imports .filter(n => n.kind === ts.SyntaxKind.ImportDeclaration) .map(n => n) .filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral) .filter(d => d.moduleSpecifier.getText().endsWith(`/nls.js'`)) .filter(d => !!d.importClause && !!d.importClause.namedBindings); // `nls.localize(...)` calls const nlsLocalizeCallExpressions = importDeclarations .filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport)) .map(d => (d.importClause!.namedBindings).name) .concat(importEqualsDeclarations.map(d => d.name)) // find read-only references to `nls` .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) .flatten() .filter(r => !r.isWriteAccess) // find the deepest call expressions AST nodes that contain those references .map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n))) .map(a => lazy(a).last()) .filter(n => !!n) .map(n => n) // only `localize` calls .filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && (n.expression).name.getText() === functionName); // `localize` named imports const allLocalizeImportDeclarations = importDeclarations .filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)) .map(d => ([] as any[]).concat((d.importClause!.namedBindings!).elements)) .flatten(); // `localize` read-only references const localizeReferences = allLocalizeImportDeclarations .filter(d => d.name.getText() === functionName) .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) .flatten() .filter(r => !r.isWriteAccess); // custom named `localize` read-only references const namedLocalizeReferences = allLocalizeImportDeclarations .filter(d => d.propertyName && d.propertyName.getText() === functionName) .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1)) .flatten() .filter(r => !r.isWriteAccess); // find the deepest call expressions AST nodes that contain those references const localizeCallExpressions = localizeReferences .concat(namedLocalizeReferences) .map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n))) .map(a => lazy(a).last()) .filter(n => !!n) .map(n => n); // collect everything const localizeCalls = nlsLocalizeCallExpressions .concat(localizeCallExpressions) .map(e => e.arguments) .filter(a => a.length > 1) .sort((a, b) => a[0].getStart() - b[0].getStart()) .map(a => ({ keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, key: a[0].getText(), valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, value: a[1].getText() })); return { localizeCalls: localizeCalls.toArray() }; } class TextModel { private lines: string[]; private lineEndings: string[]; constructor(contents: string) { const regex = /\r\n|\r|\n/g; let index = 0; let match: RegExpExecArray | null; this.lines = []; this.lineEndings = []; while (match = regex.exec(contents)) { this.lines.push(contents.substring(index, match.index)); this.lineEndings.push(match[0]); index = regex.lastIndex; } if (contents.length > 0) { this.lines.push(contents.substring(index, contents.length)); this.lineEndings.push(''); } } public get(index: number): string { return this.lines[index]; } public set(index: number, line: string): void { this.lines[index] = line; } public get lineCount(): number { return this.lines.length; } /** * Applies patch(es) to the model. * Multiple patches must be ordered. * Does not support patches spanning multiple lines. */ public apply(patch: IPatch): void { const startLineNumber = patch.span.start.line; const endLineNumber = patch.span.end.line; const startLine = this.lines[startLineNumber] || ''; const endLine = this.lines[endLineNumber] || ''; this.lines[startLineNumber] = [ startLine.substring(0, patch.span.start.character), patch.content, endLine.substring(patch.span.end.character) ].join(''); for (let i = startLineNumber + 1; i <= endLineNumber; i++) { this.lines[i] = ''; } } public toString(): string { return lazy(this.lines).zip(this.lineEndings) .flatten().toArray().join(''); } } function patchJavascript(patches: IPatch[], contents: string): string { const model = new TextModel(contents); // patch the localize calls lazy(patches).reverse().each(p => model.apply(p)); return model.toString(); } function patchSourcemap(patches: IPatch[], rsm: sm.RawSourceMap, smc: sm.SourceMapConsumer): sm.RawSourceMap { const smg = new sm.SourceMapGenerator({ file: rsm.file, sourceRoot: rsm.sourceRoot }); patches = patches.reverse(); let currentLine = -1; let currentLineDiff = 0; let source: string | null = null; smc.eachMapping(m => { const patch = patches[patches.length - 1]; const original = { line: m.originalLine, column: m.originalColumn }; const generated = { line: m.generatedLine, column: m.generatedColumn }; if (currentLine !== generated.line) { currentLineDiff = 0; } currentLine = generated.line; generated.column += currentLineDiff; if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) { const originalLength = patch.span.end.character - patch.span.start.character; const modifiedLength = patch.content.length; const lengthDiff = modifiedLength - originalLength; currentLineDiff += lengthDiff; generated.column += lengthDiff; patches.pop(); } source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source; source = source.replace(/\\/g, '/'); smg.addMapping({ source, name: m.name, original, generated }); }, null, sm.SourceMapConsumer.GENERATED_ORDER); if (source) { smg.setSourceContent(source, smc.sourceContentFor(source)); } return JSON.parse(smg.toString()); } function parseLocalizeKeyOrValue(sourceExpression: string) { // sourceValue can be "foo", 'foo', `foo` or { .... } // in its evalulated form // we want to return either the string or the object // eslint-disable-next-line no-eval return eval(`(${sourceExpression})`); } function patch(ts: typeof import('typescript'), typescript: string, javascript: string, sourcemap: sm.RawSourceMap, options: { preserveEnglish: boolean }): INlsPatchResult { const { localizeCalls } = analyze(ts, typescript, 'localize'); const { localizeCalls: localize2Calls } = analyze(ts, typescript, 'localize2'); if (localizeCalls.length === 0 && localize2Calls.length === 0) { return { javascript, sourcemap }; } const nlsKeys = localizeCalls.map(lc => parseLocalizeKeyOrValue(lc.key)).concat(localize2Calls.map(lc => parseLocalizeKeyOrValue(lc.key))); const nlsMessages = localizeCalls.map(lc => parseLocalizeKeyOrValue(lc.value)).concat(localize2Calls.map(lc => parseLocalizeKeyOrValue(lc.value))); const smc = new sm.SourceMapConsumer(sourcemap); const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]); // build patches const toPatch = (c: { range: ISpan; content: string }): IPatch => { const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start))); const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end))); return { span: { start, end }, content: c.content }; }; const localizePatches = lazy(localizeCalls) .map(lc => ( options.preserveEnglish ? [ { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") ] : [ { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) { range: lc.valueSpan, content: 'null' } ])) .flatten() .map(toPatch); const localize2Patches = lazy(localize2Calls) .map(lc => ( { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize2('key', "message") => localize(, "message") )) .map(toPatch); // Sort patches by their start position const patches = localizePatches.concat(localize2Patches).toArray().sort((a, b) => { if (a.span.start.line < b.span.start.line) { return -1; } else if (a.span.start.line > b.span.start.line) { return 1; } else if (a.span.start.character < b.span.start.character) { return -1; } else if (a.span.start.character > b.span.start.character) { return 1; } else { return 0; } }); javascript = patchJavascript(patches, javascript); sourcemap = patchSourcemap(patches, sourcemap, smc); return { javascript, sourcemap, nlsKeys, nlsMessages }; } export function patchFile(javascriptFile: File, typescript: string, options: { preserveEnglish: boolean }): File { const ts = require('typescript') as typeof import('typescript'); // hack? const moduleId = javascriptFile.relative .replace(/\.js$/, '') .replace(/\\/g, '/'); const { javascript, sourcemap, nlsKeys, nlsMessages } = patch( ts, typescript, javascriptFile.contents.toString(), (javascriptFile).sourceMap, options ); const result = fileFrom(javascriptFile, javascript); (result).sourceMap = sourcemap; if (nlsKeys) { moduleToNLSKeys[moduleId] = nlsKeys; allNLSModulesAndKeys.push([moduleId, nlsKeys.map(nlsKey => typeof nlsKey === 'string' ? nlsKey : nlsKey.key)]); } if (nlsMessages) { moduleToNLSMessages[moduleId] = nlsMessages; allNLSMessages.push(...nlsMessages); } return result; } } ================================================ FILE: build/lib/node.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const npmrcPath = path_1.default.join(root, 'remote', '.npmrc'); const npmrc = fs_1.default.readFileSync(npmrcPath, 'utf8'); const version = /^target="(.*)"$/m.exec(npmrc)[1]; const platform = process.platform; const arch = process.arch; const node = platform === 'win32' ? 'node.exe' : 'node'; const nodePath = path_1.default.join(root, '.build', 'node', `v${version}`, `${platform}-${arch}`, node); console.log(nodePath); //# sourceMappingURL=node.js.map ================================================ FILE: build/lib/node.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import fs from 'fs'; const root = path.dirname(path.dirname(__dirname)); const npmrcPath = path.join(root, 'remote', '.npmrc'); const npmrc = fs.readFileSync(npmrcPath, 'utf8'); const version = /^target="(.*)"$/m.exec(npmrc)![1]; const platform = process.platform; const arch = process.arch; const node = platform === 'win32' ? 'node.exe' : 'node'; const nodePath = path.join(root, '.build', 'node', `v${version}`, `${platform}-${arch}`, node); console.log(nodePath); ================================================ FILE: build/lib/optimize.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.bundleTask = bundleTask; exports.minifyTask = minifyTask; const event_stream_1 = __importDefault(require("event-stream")); const gulp_1 = __importDefault(require("gulp")); const gulp_filter_1 = __importDefault(require("gulp-filter")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const pump_1 = __importDefault(require("pump")); const vinyl_1 = __importDefault(require("vinyl")); const bundle = __importStar(require("./bundle")); const postcss_1 = require("./postcss"); const esbuild_1 = __importDefault(require("esbuild")); const gulp_sourcemaps_1 = __importDefault(require("gulp-sourcemaps")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const REPO_ROOT_PATH = path_1.default.join(__dirname, '../..'); const DEFAULT_FILE_HEADER = [ '/*!--------------------------------------------------------', ' * Copyright (C) Microsoft Corporation. All rights reserved.', ' *--------------------------------------------------------*/' ].join('\n'); function bundleESMTask(opts) { const resourcesStream = event_stream_1.default.through(); // this stream will contain the resources const bundlesStream = event_stream_1.default.through(); // this stream will contain the bundled files const entryPoints = opts.entryPoints.map(entryPoint => { if (typeof entryPoint === 'string') { return { name: path_1.default.parse(entryPoint).name }; } return entryPoint; }); const bundleAsync = async () => { const files = []; const tasks = []; for (const entryPoint of entryPoints) { (0, fancy_log_1.default)(`Bundled entry point: ${ansi_colors_1.default.yellow(entryPoint.name)}...`); // support for 'dest' via esbuild#in/out const dest = entryPoint.dest?.replace(/\.[^/.]+$/, '') ?? entryPoint.name; // banner contents const banner = { js: DEFAULT_FILE_HEADER, css: DEFAULT_FILE_HEADER }; // TS Boilerplate if (!opts.skipTSBoilerplateRemoval?.(entryPoint.name)) { const tslibPath = path_1.default.join(require.resolve('tslib'), '../tslib.es6.js'); banner.js += await fs_1.default.promises.readFile(tslibPath, 'utf-8'); } const contentsMapper = { name: 'contents-mapper', setup(build) { build.onLoad({ filter: /\.js$/ }, async ({ path }) => { const contents = await fs_1.default.promises.readFile(path, 'utf-8'); // TS Boilerplate let newContents; if (!opts.skipTSBoilerplateRemoval?.(entryPoint.name)) { newContents = bundle.removeAllTSBoilerplate(contents); } else { newContents = contents; } // File Content Mapper const mapper = opts.fileContentMapper?.(path.replace(/\\/g, '/')); if (mapper) { newContents = await mapper(newContents); } return { contents: newContents }; }); } }; const externalOverride = { name: 'external-override', setup(build) { // We inline selected modules that are we depend on on startup without // a conditional `await import(...)` by hooking into the resolution. build.onResolve({ filter: /^minimist$/ }, () => { return { path: path_1.default.join(REPO_ROOT_PATH, 'node_modules', 'minimist', 'index.js'), external: false }; }); }, }; const task = esbuild_1.default.build({ bundle: true, packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages platform: 'neutral', // makes esm format: 'esm', sourcemap: 'external', plugins: [contentsMapper, externalOverride], target: ['es2022'], loader: { '.ttf': 'file', '.svg': 'file', '.png': 'file', '.sh': 'file', }, assetNames: 'media/[name]', // moves media assets into a sub-folder "media" banner: entryPoint.name === 'vs/workbench/workbench.web.main' ? undefined : banner, // TODO@esm remove line when we stop supporting web-amd-esm-bridge entryPoints: [ { in: path_1.default.join(REPO_ROOT_PATH, opts.src, `${entryPoint.name}.js`), out: dest, } ], outdir: path_1.default.join(REPO_ROOT_PATH, opts.src), write: false, // enables res.outputFiles metafile: true, // enables res.metafile // minify: NOT enabled because we have a separate minify task that takes care of the TSLib banner as well }).then(res => { for (const file of res.outputFiles) { let sourceMapFile = undefined; if (file.path.endsWith('.js')) { sourceMapFile = res.outputFiles.find(f => f.path === `${file.path}.map`); } const fileProps = { contents: Buffer.from(file.contents), sourceMap: sourceMapFile ? JSON.parse(sourceMapFile.text) : undefined, // support gulp-sourcemaps path: file.path, base: path_1.default.join(REPO_ROOT_PATH, opts.src) }; files.push(new vinyl_1.default(fileProps)); } }); tasks.push(task); } await Promise.all(tasks); return { files }; }; bundleAsync().then((output) => { // bundle output (JS, CSS, SVG...) event_stream_1.default.readArray(output.files).pipe(bundlesStream); // forward all resources gulp_1.default.src(opts.resources ?? [], { base: `${opts.src}`, allowEmpty: true }).pipe(resourcesStream); }); const result = event_stream_1.default.merge(bundlesStream, resourcesStream); return result .pipe(gulp_sourcemaps_1.default.write('./', { sourceRoot: undefined, addComment: true, includeContent: true })); } function bundleTask(opts) { return function () { return bundleESMTask(opts.esm).pipe(gulp_1.default.dest(opts.out)); }; } function minifyTask(src, sourceMapBaseUrl) { const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined; return cb => { const cssnano = require('cssnano'); const svgmin = require('gulp-svgmin'); const jsFilter = (0, gulp_filter_1.default)('**/*.js', { restore: true }); const cssFilter = (0, gulp_filter_1.default)('**/*.css', { restore: true }); const svgFilter = (0, gulp_filter_1.default)('**/*.svg', { restore: true }); (0, pump_1.default)(gulp_1.default.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, gulp_sourcemaps_1.default.init({ loadMaps: true }), event_stream_1.default.map((f, cb) => { esbuild_1.default.build({ entryPoints: [f.path], minify: true, sourcemap: 'external', outdir: '.', packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages platform: 'neutral', // makes esm target: ['es2022'], write: false }).then(res => { const jsFile = res.outputFiles.find(f => /\.js$/.test(f.path)); const sourceMapFile = res.outputFiles.find(f => /\.js\.map$/.test(f.path)); const contents = Buffer.from(jsFile.contents); const unicodeMatch = contents.toString().match(/[^\x00-\xFF]+/g); if (unicodeMatch) { cb(new Error(`Found non-ascii character ${unicodeMatch[0]} in the minified output of ${f.path}. Non-ASCII characters in the output can cause performance problems when loading. Please review if you have introduced a regular expression that esbuild is not automatically converting and convert it to using unicode escape sequences.`)); } else { f.contents = contents; f.sourceMap = JSON.parse(sourceMapFile.text); cb(undefined, f); } }, cb); }), jsFilter.restore, cssFilter, (0, postcss_1.gulpPostcss)([cssnano({ preset: 'default' })]), cssFilter.restore, svgFilter, svgmin(), svgFilter.restore, gulp_sourcemaps_1.default.write('./', { sourceMappingURL, sourceRoot: undefined, includeContent: true, addComment: true }), gulp_1.default.dest(src + '-min'), (err) => cb(err)); }; } //# sourceMappingURL=optimize.js.map ================================================ FILE: build/lib/optimize.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import gulp from 'gulp'; import filter from 'gulp-filter'; import path from 'path'; import fs from 'fs'; import pump from 'pump'; import VinylFile from 'vinyl'; import * as bundle from './bundle'; import { gulpPostcss } from './postcss'; import esbuild from 'esbuild'; import sourcemaps from 'gulp-sourcemaps'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; const REPO_ROOT_PATH = path.join(__dirname, '../..'); export interface IBundleESMTaskOpts { /** * The folder to read files from. */ src: string; /** * The entry points to bundle. */ entryPoints: Array; /** * Other resources to consider (svg, etc.) */ resources?: string[]; /** * File contents interceptor for a given path. */ fileContentMapper?: (path: string) => ((contents: string) => Promise | string) | undefined; /** * Allows to skip the removal of TS boilerplate. Use this when * the entry point is small and the overhead of removing the * boilerplate makes the file larger in the end. */ skipTSBoilerplateRemoval?: (entryPointName: string) => boolean; } const DEFAULT_FILE_HEADER = [ '/*!--------------------------------------------------------', ' * Copyright (C) Microsoft Corporation. All rights reserved.', ' *--------------------------------------------------------*/' ].join('\n'); function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream { const resourcesStream = es.through(); // this stream will contain the resources const bundlesStream = es.through(); // this stream will contain the bundled files const entryPoints = opts.entryPoints.map(entryPoint => { if (typeof entryPoint === 'string') { return { name: path.parse(entryPoint).name }; } return entryPoint; }); const bundleAsync = async () => { const files: VinylFile[] = []; const tasks: Promise[] = []; for (const entryPoint of entryPoints) { fancyLog(`Bundled entry point: ${ansiColors.yellow(entryPoint.name)}...`); // support for 'dest' via esbuild#in/out const dest = entryPoint.dest?.replace(/\.[^/.]+$/, '') ?? entryPoint.name; // banner contents const banner = { js: DEFAULT_FILE_HEADER, css: DEFAULT_FILE_HEADER }; // TS Boilerplate if (!opts.skipTSBoilerplateRemoval?.(entryPoint.name)) { const tslibPath = path.join(require.resolve('tslib'), '../tslib.es6.js'); banner.js += await fs.promises.readFile(tslibPath, 'utf-8'); } const contentsMapper: esbuild.Plugin = { name: 'contents-mapper', setup(build) { build.onLoad({ filter: /\.js$/ }, async ({ path }) => { const contents = await fs.promises.readFile(path, 'utf-8'); // TS Boilerplate let newContents: string; if (!opts.skipTSBoilerplateRemoval?.(entryPoint.name)) { newContents = bundle.removeAllTSBoilerplate(contents); } else { newContents = contents; } // File Content Mapper const mapper = opts.fileContentMapper?.(path.replace(/\\/g, '/')); if (mapper) { newContents = await mapper(newContents); } return { contents: newContents }; }); } }; const externalOverride: esbuild.Plugin = { name: 'external-override', setup(build) { // We inline selected modules that are we depend on on startup without // a conditional `await import(...)` by hooking into the resolution. build.onResolve({ filter: /^minimist$/ }, () => { return { path: path.join(REPO_ROOT_PATH, 'node_modules', 'minimist', 'index.js'), external: false }; }); }, }; const task = esbuild.build({ bundle: true, packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages platform: 'neutral', // makes esm format: 'esm', sourcemap: 'external', plugins: [contentsMapper, externalOverride], target: ['es2022'], loader: { '.ttf': 'file', '.svg': 'file', '.png': 'file', '.sh': 'file', }, assetNames: 'media/[name]', // moves media assets into a sub-folder "media" banner: entryPoint.name === 'vs/workbench/workbench.web.main' ? undefined : banner, // TODO@esm remove line when we stop supporting web-amd-esm-bridge entryPoints: [ { in: path.join(REPO_ROOT_PATH, opts.src, `${entryPoint.name}.js`), out: dest, } ], outdir: path.join(REPO_ROOT_PATH, opts.src), write: false, // enables res.outputFiles metafile: true, // enables res.metafile // minify: NOT enabled because we have a separate minify task that takes care of the TSLib banner as well }).then(res => { for (const file of res.outputFiles) { let sourceMapFile: esbuild.OutputFile | undefined = undefined; if (file.path.endsWith('.js')) { sourceMapFile = res.outputFiles.find(f => f.path === `${file.path}.map`); } const fileProps = { contents: Buffer.from(file.contents), sourceMap: sourceMapFile ? JSON.parse(sourceMapFile.text) : undefined, // support gulp-sourcemaps path: file.path, base: path.join(REPO_ROOT_PATH, opts.src) }; files.push(new VinylFile(fileProps)); } }); tasks.push(task); } await Promise.all(tasks); return { files }; }; bundleAsync().then((output) => { // bundle output (JS, CSS, SVG...) es.readArray(output.files).pipe(bundlesStream); // forward all resources gulp.src(opts.resources ?? [], { base: `${opts.src}`, allowEmpty: true }).pipe(resourcesStream); }); const result = es.merge( bundlesStream, resourcesStream ); return result .pipe(sourcemaps.write('./', { sourceRoot: undefined, addComment: true, includeContent: true })); } export interface IBundleESMTaskOpts { /** * Destination folder for the bundled files. */ out: string; /** * Bundle ESM modules (using esbuild). */ esm: IBundleESMTaskOpts; } export function bundleTask(opts: IBundleESMTaskOpts): () => NodeJS.ReadWriteStream { return function () { return bundleESMTask(opts.esm).pipe(gulp.dest(opts.out)); }; } export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => void { const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined; return cb => { const cssnano = require('cssnano') as typeof import('cssnano'); const svgmin = require('gulp-svgmin') as typeof import('gulp-svgmin'); const jsFilter = filter('**/*.js', { restore: true }); const cssFilter = filter('**/*.css', { restore: true }); const svgFilter = filter('**/*.svg', { restore: true }); pump( gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), es.map((f: any, cb) => { esbuild.build({ entryPoints: [f.path], minify: true, sourcemap: 'external', outdir: '.', packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages platform: 'neutral', // makes esm target: ['es2022'], write: false }).then(res => { const jsFile = res.outputFiles.find(f => /\.js$/.test(f.path))!; const sourceMapFile = res.outputFiles.find(f => /\.js\.map$/.test(f.path))!; const contents = Buffer.from(jsFile.contents); const unicodeMatch = contents.toString().match(/[^\x00-\xFF]+/g); if (unicodeMatch) { cb(new Error(`Found non-ascii character ${unicodeMatch[0]} in the minified output of ${f.path}. Non-ASCII characters in the output can cause performance problems when loading. Please review if you have introduced a regular expression that esbuild is not automatically converting and convert it to using unicode escape sequences.`)); } else { f.contents = contents; f.sourceMap = JSON.parse(sourceMapFile.text); cb(undefined, f); } }, cb); }), jsFilter.restore, cssFilter, gulpPostcss([cssnano({ preset: 'default' })]), cssFilter.restore, svgFilter, svgmin(), svgFilter.restore, sourcemaps.write('./', { sourceMappingURL, sourceRoot: undefined, includeContent: true, addComment: true } as any), gulp.dest(src + '-min'), (err: any) => cb(err)); }; } ================================================ FILE: build/lib/policies.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const byline_1 = __importDefault(require("byline")); const ripgrep_1 = require("@vscode/ripgrep"); const tree_sitter_1 = __importDefault(require("tree-sitter")); const { typescript } = require('tree-sitter-typescript'); const product = require('../../product.json'); const packageJson = require('../../package.json'); function isNlsString(value) { return value ? typeof value !== 'string' : false; } function isStringArray(value) { return !value.some(s => isNlsString(s)); } function isNlsStringArray(value) { return value.every(s => isNlsString(s)); } var PolicyType; (function (PolicyType) { PolicyType["Boolean"] = "boolean"; PolicyType["Number"] = "number"; PolicyType["Object"] = "object"; PolicyType["String"] = "string"; PolicyType["StringEnum"] = "stringEnum"; })(PolicyType || (PolicyType = {})); function renderADMLString(prefix, moduleName, nlsString, translations) { let value; if (translations) { const moduleTranslations = translations[moduleName]; if (moduleTranslations) { value = moduleTranslations[nlsString.nlsKey]; } } if (!value) { value = nlsString.value; } return `${value}`; } function renderProfileString(_prefix, moduleName, nlsString, translations) { let value; if (translations) { const moduleTranslations = translations[moduleName]; if (moduleTranslations) { value = moduleTranslations[nlsString.nlsKey]; } } if (!value) { value = nlsString.value; } return value; } class BasePolicy { type; name; category; minimumVersion; description; moduleName; constructor(type, name, category, minimumVersion, description, moduleName) { this.type = type; this.name = name; this.category = category; this.minimumVersion = minimumVersion; this.description = description; this.moduleName = moduleName; } renderADMLString(nlsString, translations) { return renderADMLString(this.name, this.moduleName, nlsString, translations); } renderADMX(regKey) { return [ ``, ` `, ` `, ` `, ...this.renderADMXElements(), ` `, `` ]; } renderADMLStrings(translations) { return [ `${this.name}`, this.renderADMLString(this.description, translations) ]; } renderADMLPresentation() { return `${this.renderADMLPresentationContents()}`; } renderProfile() { return [`${this.name}`, this.renderProfileValue()]; } renderProfileManifest(translations) { return ` ${this.renderProfileManifestValue(translations)} `; } } class BooleanPolicy extends BasePolicy { static from(name, category, minimumVersion, description, moduleName, settingNode) { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'boolean') { return undefined; } return new BooleanPolicy(name, category, minimumVersion, description, moduleName); } constructor(name, category, minimumVersion, description, moduleName) { super(PolicyType.Boolean, name, category, minimumVersion, description, moduleName); } renderADMXElements() { return [ ``, ` `, `` ]; } renderADMLPresentationContents() { return `${this.name}`; } renderProfileValue() { return ``; } renderProfileManifestValue(translations) { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type boolean`; } } class ParseError extends Error { constructor(message, moduleName, node) { super(`${message}. ${moduleName}.ts:${node.startPosition.row + 1}`); } } class NumberPolicy extends BasePolicy { defaultValue; static from(name, category, minimumVersion, description, moduleName, settingNode) { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'number') { return undefined; } const defaultValue = getNumberProperty(moduleName, settingNode, 'default'); if (typeof defaultValue === 'undefined') { throw new ParseError(`Missing required 'default' property.`, moduleName, settingNode); } return new NumberPolicy(name, category, minimumVersion, description, moduleName, defaultValue); } constructor(name, category, minimumVersion, description, moduleName, defaultValue) { super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); this.defaultValue = defaultValue; } renderADMXElements() { return [ `` // `` ]; } renderADMLPresentationContents() { return `${this.name}`; } renderProfileValue() { return `${this.defaultValue}`; } renderProfileManifestValue(translations) { return `pfm_default ${this.defaultValue} pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type integer`; } } class StringPolicy extends BasePolicy { static from(name, category, minimumVersion, description, moduleName, settingNode) { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'string') { return undefined; } return new StringPolicy(name, category, minimumVersion, description, moduleName); } constructor(name, category, minimumVersion, description, moduleName) { super(PolicyType.String, name, category, minimumVersion, description, moduleName); } renderADMXElements() { return [``]; } renderADMLPresentationContents() { return ``; } renderProfileValue() { return ``; } renderProfileManifestValue(translations) { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string`; } } class ObjectPolicy extends BasePolicy { static from(name, category, minimumVersion, description, moduleName, settingNode) { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'object' && type !== 'array') { return undefined; } return new ObjectPolicy(name, category, minimumVersion, description, moduleName); } constructor(name, category, minimumVersion, description, moduleName) { super(PolicyType.Object, name, category, minimumVersion, description, moduleName); } renderADMXElements() { return [``]; } renderADMLPresentationContents() { return ``; } renderProfileValue() { return ``; } renderProfileManifestValue(translations) { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string `; } } class StringEnumPolicy extends BasePolicy { enum_; enumDescriptions; static from(name, category, minimumVersion, description, moduleName, settingNode) { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'string') { return undefined; } const enum_ = getStringArrayProperty(moduleName, settingNode, 'enum'); if (!enum_) { return undefined; } if (!isStringArray(enum_)) { throw new ParseError(`Property 'enum' should not be localized.`, moduleName, settingNode); } const enumDescriptions = getStringArrayProperty(moduleName, settingNode, 'enumDescriptions'); if (!enumDescriptions) { throw new ParseError(`Missing required 'enumDescriptions' property.`, moduleName, settingNode); } else if (!isNlsStringArray(enumDescriptions)) { throw new ParseError(`Property 'enumDescriptions' should be localized.`, moduleName, settingNode); } return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions); } constructor(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions) { super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); this.enum_ = enum_; this.enumDescriptions = enumDescriptions; } renderADMXElements() { return [ ``, ...this.enum_.map((value, index) => ` ${value}`), `` ]; } renderADMLStrings(translations) { return [ ...super.renderADMLStrings(translations), ...this.enumDescriptions.map(e => this.renderADMLString(e, translations)) ]; } renderADMLPresentationContents() { return ``; } renderProfileValue() { return `${this.enum_[0]}`; } renderProfileManifestValue(translations) { return `pfm_default ${this.enum_[0]} pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string pfm_range_list ${this.enum_.map(e => `${e}`).join('\n ')} `; } } const NumberQ = { Q: `(number) @value`, value(matches) { const match = matches[0]; if (!match) { return undefined; } const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; if (!value) { throw new Error(`Missing required 'value' property.`); } return parseInt(value); } }; const StringQ = { Q: `[ (string (string_fragment) @value) (call_expression function: [ (identifier) @localizeFn (#eq? @localizeFn localize) (member_expression object: (identifier) @nlsObj (#eq? @nlsObj nls) property: (property_identifier) @localizeFn (#eq? @localizeFn localize) ) ] arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) ) ]`, value(matches) { const match = matches[0]; if (!match) { return undefined; } const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; if (!value) { throw new Error(`Missing required 'value' property.`); } const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text; if (nlsKey) { return { value, nlsKey }; } else { return value; } } }; const StringArrayQ = { Q: `(array ${StringQ.Q})`, value(matches) { if (matches.length === 0) { return undefined; } return matches.map(match => { return StringQ.value([match]); }); } }; function getProperty(qtype, moduleName, node, key) { const query = new tree_sitter_1.default.Query(typescript, `( (pair key: [(property_identifier)(string)] @key value: ${qtype.Q} ) (#any-of? @key "${key}" "'${key}'") )`); try { const matches = query.matches(node).filter(m => m.captures[0].node.parent?.parent === node); return qtype.value(matches); } catch (e) { throw new ParseError(e.message, moduleName, node); } } function getNumberProperty(moduleName, node, key) { return getProperty(NumberQ, moduleName, node, key); } function getStringProperty(moduleName, node, key) { return getProperty(StringQ, moduleName, node, key); } function getStringArrayProperty(moduleName, node, key) { return getProperty(StringArrayQ, moduleName, node, key); } // TODO: add more policy types const PolicyTypes = [ BooleanPolicy, NumberPolicy, StringEnumPolicy, StringPolicy, ObjectPolicy ]; function getPolicy(moduleName, configurationNode, settingNode, policyNode, categories) { const name = getStringProperty(moduleName, policyNode, 'name'); if (!name) { throw new ParseError(`Missing required 'name' property`, moduleName, policyNode); } else if (isNlsString(name)) { throw new ParseError(`Property 'name' should be a literal string`, moduleName, policyNode); } const categoryName = getStringProperty(moduleName, configurationNode, 'title'); if (!categoryName) { throw new ParseError(`Missing required 'title' property`, moduleName, configurationNode); } else if (!isNlsString(categoryName)) { throw new ParseError(`Property 'title' should be localized`, moduleName, configurationNode); } const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`; let category = categories.get(categoryKey); if (!category) { category = { moduleName, name: categoryName }; categories.set(categoryKey, category); } const minimumVersion = getStringProperty(moduleName, policyNode, 'minimumVersion'); if (!minimumVersion) { throw new ParseError(`Missing required 'minimumVersion' property.`, moduleName, policyNode); } else if (isNlsString(minimumVersion)) { throw new ParseError(`Property 'minimumVersion' should be a literal string.`, moduleName, policyNode); } const description = getStringProperty(moduleName, policyNode, 'description') ?? getStringProperty(moduleName, settingNode, 'description'); if (!description) { throw new ParseError(`Missing required 'description' property.`, moduleName, settingNode); } if (!isNlsString(description)) { throw new ParseError(`Property 'description' should be localized.`, moduleName, settingNode); } let result; for (const policyType of PolicyTypes) { if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) { break; } } if (!result) { throw new ParseError(`Failed to parse policy '${name}'.`, moduleName, settingNode); } return result; } function getPolicies(moduleName, node) { const query = new tree_sitter_1.default.Query(typescript, ` ( (call_expression function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration) arguments: (arguments (object (pair key: [(property_identifier)(string)] @propertiesKey (#any-of? @propertiesKey "properties" "'properties'") value: (object (pair key: [(property_identifier)(string)(computed_property_name)] value: (object (pair key: [(property_identifier)(string)] @policyKey (#any-of? @policyKey "policy" "'policy'") value: (object) @policy )) @setting )) )) @configuration) ) ) `); const categories = new Map(); return query.matches(node).map(m => { const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node; const settingNode = m.captures.filter(c => c.name === 'setting')[0].node; const policyNode = m.captures.filter(c => c.name === 'policy')[0].node; return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories); }); } async function getFiles(root) { return new Promise((c, e) => { const result = []; const rg = (0, child_process_1.spawn)(ripgrep_1.rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]); const stream = (0, byline_1.default)(rg.stdout.setEncoding('utf8')); stream.on('data', path => result.push(path)); stream.on('error', err => e(err)); stream.on('end', () => c(result)); }); } function renderADMX(regKey, versions, categories, policies) { versions = versions.map(v => v.replace(/\./g, '_')); return ` ${versions.map(v => ``).join(`\n `)} ${categories.map(c => ``).join(`\n `)} ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)} `; } function renderADML(appName, versions, categories, policies, translations) { return ` ${appName} ${versions.map(v => `${appName} >= ${v}`).join(`\n `)} ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations)).join(`\n `)} ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)} ${policies.map(p => p.renderADMLPresentation()).join(`\n `)} `; } function renderProfileManifest(appName, bundleIdentifier, _versions, _categories, policies, translations) { const requiredPayloadFields = ` pfm_default Configure ${appName} pfm_name PayloadDescription pfm_title Payload Description pfm_type string pfm_default ${appName} pfm_name PayloadDisplayName pfm_require always pfm_title Payload Display Name pfm_type string pfm_default ${bundleIdentifier} pfm_name PayloadIdentifier pfm_require always pfm_title Payload Identifier pfm_type string pfm_default ${bundleIdentifier} pfm_name PayloadType pfm_require always pfm_title Payload Type pfm_type string pfm_default pfm_name PayloadUUID pfm_require always pfm_title Payload UUID pfm_type string pfm_default 1 pfm_name PayloadVersion pfm_range_list 1 pfm_require always pfm_title Payload Version pfm_type integer pfm_default Microsoft pfm_name PayloadOrganization pfm_title Payload Organization pfm_type string `; const profileManifestSubkeys = policies.map(policy => { return policy.renderProfileManifest(translations); }).join(''); return ` pfm_app_url https://code.visualstudio.com/ pfm_description ${appName} Managed Settings pfm_documentation_url https://code.visualstudio.com/docs/setup/enterprise pfm_domain ${bundleIdentifier} pfm_format_version 1 pfm_interaction combined pfm_last_modified ${new Date().toISOString().replace(/\.\d+Z$/, 'Z')} pfm_platforms macOS pfm_subkeys ${requiredPayloadFields} ${profileManifestSubkeys} pfm_title ${appName} pfm_unique pfm_version 1 `; } function renderMacOSPolicy(policies, translations) { const appName = product.nameLong; const bundleIdentifier = product.darwinBundleIdentifier; const payloadUUID = product.darwinProfilePayloadUUID; const UUID = product.darwinProfileUUID; const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); const categories = [...new Set(policies.map(p => p.category))]; const policyEntries = policies.map(policy => policy.renderProfile()) .flat() .map(entry => `\t\t\t\t${entry}`) .join('\n'); return { profile: ` PayloadContent PayloadDisplayName ${appName} PayloadIdentifier ${bundleIdentifier}.${UUID} PayloadType ${bundleIdentifier} PayloadUUID ${UUID} PayloadVersion 1 ${policyEntries} PayloadDescription This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise PayloadDisplayName ${appName} PayloadIdentifier ${bundleIdentifier} PayloadOrganization Microsoft PayloadType Configuration PayloadUUID ${payloadUUID} PayloadVersion 1 TargetDeviceType 5 `, manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) }, ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) })) ] }; } function renderGP(policies, translations) { const appName = product.nameLong; const regKey = product.win32RegValueName; const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); const categories = [...new Set(policies.map(p => p.category))]; return { admx: renderADMX(regKey, versions, categories, policies), adml: [ { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) }, ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) })) ] }; } const Languages = { 'fr': 'fr-fr', 'it': 'it-it', 'de': 'de-de', 'es': 'es-es', 'ru': 'ru-ru', 'zh-hans': 'zh-cn', 'zh-hant': 'zh-tw', 'ja': 'ja-jp', 'ko': 'ko-kr', 'cs': 'cs-cz', 'pt-br': 'pt-br', 'tr': 'tr-tr', 'pl': 'pl-pl', }; async function getSpecificNLS(resourceUrlTemplate, languageId, version) { const resource = { publisher: 'ms-ceintl', name: `vscode-language-pack-${languageId}`, version: `${version[0]}.${version[1]}.${version[2]}`, path: 'extension/translations/main.i18n.json' }; const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key]); const res = await fetch(url); if (res.status !== 200) { throw new Error(`[${res.status}] Error downloading language pack ${languageId}@${version}`); } const { contents: result } = await res.json(); return result; } function parseVersion(version) { const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)/.exec(version); return [parseInt(major), parseInt(minor), parseInt(patch)]; } function compareVersions(a, b) { if (a[0] !== b[0]) { return a[0] - b[0]; } if (a[1] !== b[1]) { return a[1] - b[1]; } return a[2] - b[2]; } async function queryVersions(serviceUrl, languageId) { const res = await fetch(`${serviceUrl}/extensionquery`, { method: 'POST', headers: { 'Accept': 'application/json;api-version=3.0-preview.1', 'Content-Type': 'application/json', 'User-Agent': 'VS Code Build', }, body: JSON.stringify({ filters: [{ criteria: [{ filterType: 7, value: `ms-ceintl.vscode-language-pack-${languageId}` }] }], flags: 0x1 }) }); if (res.status !== 200) { throw new Error(`[${res.status}] Error querying for extension: ${languageId}`); } const result = await res.json(); return result.results[0].extensions[0].versions.map(v => parseVersion(v.version)).sort(compareVersions); } async function getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version) { const versions = await queryVersions(extensionGalleryServiceUrl, languageId); const nextMinor = [version[0], version[1] + 1, 0]; const compatibleVersions = versions.filter(v => compareVersions(v, nextMinor) < 0); const latestCompatibleVersion = compatibleVersions.at(-1); // order is newest to oldest if (!latestCompatibleVersion) { throw new Error(`No compatible language pack found for ${languageId} for version ${version}`); } return await getSpecificNLS(resourceUrlTemplate, languageId, latestCompatibleVersion); } async function parsePolicies() { const parser = new tree_sitter_1.default(); parser.setLanguage(typescript); const files = await getFiles(process.cwd()); const base = path_1.default.join(process.cwd(), 'src'); const policies = []; for (const file of files) { const moduleName = path_1.default.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/'); const contents = await fs_1.promises.readFile(file, { encoding: 'utf8' }); const tree = parser.parse(contents); policies.push(...getPolicies(moduleName, tree.rootNode)); } return policies; } async function getTranslations() { const extensionGalleryServiceUrl = product.extensionsGallery?.serviceUrl; if (!extensionGalleryServiceUrl) { console.warn(`Skipping policy localization: No 'extensionGallery.serviceUrl' found in 'product.json'.`); return []; } const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate; if (!resourceUrlTemplate) { console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`); return []; } const version = parseVersion(packageJson.version); const languageIds = Object.keys(Languages); return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version) .then(languageTranslations => ({ languageId, languageTranslations })))); } async function windowsMain(policies, translations) { const root = '.build/policies/win32'; const { admx, adml } = await renderGP(policies, translations); await fs_1.promises.rm(root, { recursive: true, force: true }); await fs_1.promises.mkdir(root, { recursive: true }); await fs_1.promises.writeFile(path_1.default.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n')); for (const { languageId, contents } of adml) { const languagePath = path_1.default.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]); await fs_1.promises.mkdir(languagePath, { recursive: true }); await fs_1.promises.writeFile(path_1.default.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n')); } } async function darwinMain(policies, translations) { const bundleIdentifier = product.darwinBundleIdentifier; if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) { throw new Error(`Missing required product information.`); } const root = '.build/policies/darwin'; const { profile, manifests } = await renderMacOSPolicy(policies, translations); await fs_1.promises.rm(root, { recursive: true, force: true }); await fs_1.promises.mkdir(root, { recursive: true }); await fs_1.promises.writeFile(path_1.default.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n')); for (const { languageId, contents } of manifests) { const languagePath = path_1.default.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]); await fs_1.promises.mkdir(languagePath, { recursive: true }); await fs_1.promises.writeFile(path_1.default.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n')); } } async function main() { const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]); const platform = process.argv[2]; if (platform === 'darwin') { await darwinMain(policies, translations); } else if (platform === 'win32') { await windowsMain(policies, translations); } else { console.error(`Usage: node build/lib/policies `); process.exit(1); } } if (require.main === module) { main().catch(err => { if (err instanceof ParseError) { console.error(`Parse Error:`, err.message); } else { console.error(err); } process.exit(1); }); } //# sourceMappingURL=policies.js.map ================================================ FILE: build/lib/policies.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawn } from 'child_process'; import { promises as fs } from 'fs'; import path from 'path'; import byline from 'byline'; import { rgPath } from '@vscode/ripgrep'; import Parser from 'tree-sitter'; const { typescript } = require('tree-sitter-typescript'); const product = require('../../product.json'); const packageJson = require('../../package.json'); type NlsString = { value: string; nlsKey: string }; function isNlsString(value: string | NlsString | undefined): value is NlsString { return value ? typeof value !== 'string' : false; } function isStringArray(value: (string | NlsString)[]): value is string[] { return !value.some(s => isNlsString(s)); } function isNlsStringArray(value: (string | NlsString)[]): value is NlsString[] { return value.every(s => isNlsString(s)); } interface Category { readonly moduleName: string; readonly name: NlsString; } enum PolicyType { Boolean = 'boolean', Number = 'number', Object = 'object', String = 'string', StringEnum = 'stringEnum', } interface Policy { readonly name: string; readonly type: PolicyType; readonly category: Category; readonly minimumVersion: string; renderADMX(regKey: string): string[]; renderADMLStrings(translations?: LanguageTranslations): string[]; renderADMLPresentation(): string; renderProfile(): string[]; // https://github.com/ProfileManifests/ProfileManifests/wiki/Manifest-Format renderProfileManifest(translations?: LanguageTranslations): string; } function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string { let value: string | undefined; if (translations) { const moduleTranslations = translations[moduleName]; if (moduleTranslations) { value = moduleTranslations[nlsString.nlsKey]; } } if (!value) { value = nlsString.value; } return `${value}`; } function renderProfileString(_prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string { let value: string | undefined; if (translations) { const moduleTranslations = translations[moduleName]; if (moduleTranslations) { value = moduleTranslations[nlsString.nlsKey]; } } if (!value) { value = nlsString.value; } return value; } abstract class BasePolicy implements Policy { constructor( readonly type: PolicyType, readonly name: string, readonly category: Category, readonly minimumVersion: string, protected description: NlsString, protected moduleName: string, ) { } protected renderADMLString(nlsString: NlsString, translations?: LanguageTranslations): string { return renderADMLString(this.name, this.moduleName, nlsString, translations); } renderADMX(regKey: string) { return [ ``, ` `, ` `, ` `, ...this.renderADMXElements(), ` `, `` ]; } protected abstract renderADMXElements(): string[]; renderADMLStrings(translations?: LanguageTranslations) { return [ `${this.name}`, this.renderADMLString(this.description, translations) ]; } renderADMLPresentation(): string { return `${this.renderADMLPresentationContents()}`; } protected abstract renderADMLPresentationContents(): string; renderProfile() { return [`${this.name}`, this.renderProfileValue()]; } renderProfileManifest(translations?: LanguageTranslations): string { return ` ${this.renderProfileManifestValue(translations)} `; } abstract renderProfileValue(): string; abstract renderProfileManifestValue(translations?: LanguageTranslations): string; } class BooleanPolicy extends BasePolicy { static from( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, settingNode: Parser.SyntaxNode ): BooleanPolicy | undefined { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'boolean') { return undefined; } return new BooleanPolicy(name, category, minimumVersion, description, moduleName); } private constructor( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, ) { super(PolicyType.Boolean, name, category, minimumVersion, description, moduleName); } protected renderADMXElements(): string[] { return [ ``, ` `, `` ]; } renderADMLPresentationContents() { return `${this.name}`; } renderProfileValue(): string { return ``; } renderProfileManifestValue(translations?: LanguageTranslations): string { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type boolean`; } } class ParseError extends Error { constructor(message: string, moduleName: string, node: Parser.SyntaxNode) { super(`${message}. ${moduleName}.ts:${node.startPosition.row + 1}`); } } class NumberPolicy extends BasePolicy { static from( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, settingNode: Parser.SyntaxNode ): NumberPolicy | undefined { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'number') { return undefined; } const defaultValue = getNumberProperty(moduleName, settingNode, 'default'); if (typeof defaultValue === 'undefined') { throw new ParseError(`Missing required 'default' property.`, moduleName, settingNode); } return new NumberPolicy(name, category, minimumVersion, description, moduleName, defaultValue); } private constructor( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, protected readonly defaultValue: number, ) { super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); } protected renderADMXElements(): string[] { return [ `` // `` ]; } renderADMLPresentationContents() { return `${this.name}`; } renderProfileValue() { return `${this.defaultValue}`; } renderProfileManifestValue(translations?: LanguageTranslations) { return `pfm_default ${this.defaultValue} pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type integer`; } } class StringPolicy extends BasePolicy { static from( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, settingNode: Parser.SyntaxNode ): StringPolicy | undefined { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'string') { return undefined; } return new StringPolicy(name, category, minimumVersion, description, moduleName); } private constructor( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, ) { super(PolicyType.String, name, category, minimumVersion, description, moduleName); } protected renderADMXElements(): string[] { return [``]; } renderADMLPresentationContents() { return ``; } renderProfileValue(): string { return ``; } renderProfileManifestValue(translations?: LanguageTranslations): string { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string`; } } class ObjectPolicy extends BasePolicy { static from( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, settingNode: Parser.SyntaxNode ): ObjectPolicy | undefined { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'object' && type !== 'array') { return undefined; } return new ObjectPolicy(name, category, minimumVersion, description, moduleName); } private constructor( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, ) { super(PolicyType.Object, name, category, minimumVersion, description, moduleName); } protected renderADMXElements(): string[] { return [``]; } renderADMLPresentationContents() { return ``; } renderProfileValue(): string { return ``; } renderProfileManifestValue(translations?: LanguageTranslations): string { return `pfm_default pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string `; } } class StringEnumPolicy extends BasePolicy { static from( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, settingNode: Parser.SyntaxNode ): StringEnumPolicy | undefined { const type = getStringProperty(moduleName, settingNode, 'type'); if (type !== 'string') { return undefined; } const enum_ = getStringArrayProperty(moduleName, settingNode, 'enum'); if (!enum_) { return undefined; } if (!isStringArray(enum_)) { throw new ParseError(`Property 'enum' should not be localized.`, moduleName, settingNode); } const enumDescriptions = getStringArrayProperty(moduleName, settingNode, 'enumDescriptions'); if (!enumDescriptions) { throw new ParseError(`Missing required 'enumDescriptions' property.`, moduleName, settingNode); } else if (!isNlsStringArray(enumDescriptions)) { throw new ParseError(`Property 'enumDescriptions' should be localized.`, moduleName, settingNode); } return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions); } private constructor( name: string, category: Category, minimumVersion: string, description: NlsString, moduleName: string, protected enum_: string[], protected enumDescriptions: NlsString[], ) { super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); } protected renderADMXElements(): string[] { return [ ``, ...this.enum_.map((value, index) => ` ${value}`), `` ]; } renderADMLStrings(translations?: LanguageTranslations) { return [ ...super.renderADMLStrings(translations), ...this.enumDescriptions.map(e => this.renderADMLString(e, translations)) ]; } renderADMLPresentationContents() { return ``; } renderProfileValue() { return `${this.enum_[0]}`; } renderProfileManifestValue(translations?: LanguageTranslations): string { return `pfm_default ${this.enum_[0]} pfm_description ${renderProfileString(this.name, this.moduleName, this.description, translations)} pfm_name ${this.name} pfm_title ${this.name} pfm_type string pfm_range_list ${this.enum_.map(e => `${e}`).join('\n ')} `; } } interface QType { Q: string; value(matches: Parser.QueryMatch[]): T | undefined; } const NumberQ: QType = { Q: `(number) @value`, value(matches: Parser.QueryMatch[]): number | undefined { const match = matches[0]; if (!match) { return undefined; } const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; if (!value) { throw new Error(`Missing required 'value' property.`); } return parseInt(value); } }; const StringQ: QType = { Q: `[ (string (string_fragment) @value) (call_expression function: [ (identifier) @localizeFn (#eq? @localizeFn localize) (member_expression object: (identifier) @nlsObj (#eq? @nlsObj nls) property: (property_identifier) @localizeFn (#eq? @localizeFn localize) ) ] arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) ) ]`, value(matches: Parser.QueryMatch[]): string | NlsString | undefined { const match = matches[0]; if (!match) { return undefined; } const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; if (!value) { throw new Error(`Missing required 'value' property.`); } const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text; if (nlsKey) { return { value, nlsKey }; } else { return value; } } }; const StringArrayQ: QType<(string | NlsString)[]> = { Q: `(array ${StringQ.Q})`, value(matches: Parser.QueryMatch[]): (string | NlsString)[] | undefined { if (matches.length === 0) { return undefined; } return matches.map(match => { return StringQ.value([match]) as string | NlsString; }); } }; function getProperty(qtype: QType, moduleName: string, node: Parser.SyntaxNode, key: string): T | undefined { const query = new Parser.Query( typescript, `( (pair key: [(property_identifier)(string)] @key value: ${qtype.Q} ) (#any-of? @key "${key}" "'${key}'") )` ); try { const matches = query.matches(node).filter(m => m.captures[0].node.parent?.parent === node); return qtype.value(matches); } catch (e) { throw new ParseError(e.message, moduleName, node); } } function getNumberProperty(moduleName: string, node: Parser.SyntaxNode, key: string): number | undefined { return getProperty(NumberQ, moduleName, node, key); } function getStringProperty(moduleName: string, node: Parser.SyntaxNode, key: string): string | NlsString | undefined { return getProperty(StringQ, moduleName, node, key); } function getStringArrayProperty(moduleName: string, node: Parser.SyntaxNode, key: string): (string | NlsString)[] | undefined { return getProperty(StringArrayQ, moduleName, node, key); } // TODO: add more policy types const PolicyTypes = [ BooleanPolicy, NumberPolicy, StringEnumPolicy, StringPolicy, ObjectPolicy ]; function getPolicy( moduleName: string, configurationNode: Parser.SyntaxNode, settingNode: Parser.SyntaxNode, policyNode: Parser.SyntaxNode, categories: Map ): Policy { const name = getStringProperty(moduleName, policyNode, 'name'); if (!name) { throw new ParseError(`Missing required 'name' property`, moduleName, policyNode); } else if (isNlsString(name)) { throw new ParseError(`Property 'name' should be a literal string`, moduleName, policyNode); } const categoryName = getStringProperty(moduleName, configurationNode, 'title'); if (!categoryName) { throw new ParseError(`Missing required 'title' property`, moduleName, configurationNode); } else if (!isNlsString(categoryName)) { throw new ParseError(`Property 'title' should be localized`, moduleName, configurationNode); } const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`; let category = categories.get(categoryKey); if (!category) { category = { moduleName, name: categoryName }; categories.set(categoryKey, category); } const minimumVersion = getStringProperty(moduleName, policyNode, 'minimumVersion'); if (!minimumVersion) { throw new ParseError(`Missing required 'minimumVersion' property.`, moduleName, policyNode); } else if (isNlsString(minimumVersion)) { throw new ParseError(`Property 'minimumVersion' should be a literal string.`, moduleName, policyNode); } const description = getStringProperty(moduleName, policyNode, 'description') ?? getStringProperty(moduleName, settingNode, 'description'); if (!description) { throw new ParseError(`Missing required 'description' property.`, moduleName, settingNode); } if (!isNlsString(description)) { throw new ParseError(`Property 'description' should be localized.`, moduleName, settingNode); } let result: Policy | undefined; for (const policyType of PolicyTypes) { if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) { break; } } if (!result) { throw new ParseError(`Failed to parse policy '${name}'.`, moduleName, settingNode); } return result; } function getPolicies(moduleName: string, node: Parser.SyntaxNode): Policy[] { const query = new Parser.Query(typescript, ` ( (call_expression function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration) arguments: (arguments (object (pair key: [(property_identifier)(string)] @propertiesKey (#any-of? @propertiesKey "properties" "'properties'") value: (object (pair key: [(property_identifier)(string)(computed_property_name)] value: (object (pair key: [(property_identifier)(string)] @policyKey (#any-of? @policyKey "policy" "'policy'") value: (object) @policy )) @setting )) )) @configuration) ) ) `); const categories = new Map(); return query.matches(node).map(m => { const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node; const settingNode = m.captures.filter(c => c.name === 'setting')[0].node; const policyNode = m.captures.filter(c => c.name === 'policy')[0].node; return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories); }); } async function getFiles(root: string): Promise { return new Promise((c, e) => { const result: string[] = []; const rg = spawn(rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]); const stream = byline(rg.stdout.setEncoding('utf8')); stream.on('data', path => result.push(path)); stream.on('error', err => e(err)); stream.on('end', () => c(result)); }); } function renderADMX(regKey: string, versions: string[], categories: Category[], policies: Policy[]) { versions = versions.map(v => v.replace(/\./g, '_')); return ` ${versions.map(v => ``).join(`\n `)} ${categories.map(c => ``).join(`\n `)} ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)} `; } function renderADML(appName: string, versions: string[], categories: Category[], policies: Policy[], translations?: LanguageTranslations) { return ` ${appName} ${versions.map(v => `${appName} >= ${v}`).join(`\n `)} ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations)).join(`\n `)} ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)} ${policies.map(p => p.renderADMLPresentation()).join(`\n `)} `; } function renderProfileManifest(appName: string, bundleIdentifier: string, _versions: string[], _categories: Category[], policies: Policy[], translations?: LanguageTranslations) { const requiredPayloadFields = ` pfm_default Configure ${appName} pfm_name PayloadDescription pfm_title Payload Description pfm_type string pfm_default ${appName} pfm_name PayloadDisplayName pfm_require always pfm_title Payload Display Name pfm_type string pfm_default ${bundleIdentifier} pfm_name PayloadIdentifier pfm_require always pfm_title Payload Identifier pfm_type string pfm_default ${bundleIdentifier} pfm_name PayloadType pfm_require always pfm_title Payload Type pfm_type string pfm_default pfm_name PayloadUUID pfm_require always pfm_title Payload UUID pfm_type string pfm_default 1 pfm_name PayloadVersion pfm_range_list 1 pfm_require always pfm_title Payload Version pfm_type integer pfm_default Microsoft pfm_name PayloadOrganization pfm_title Payload Organization pfm_type string `; const profileManifestSubkeys = policies.map(policy => { return policy.renderProfileManifest(translations); }).join(''); return ` pfm_app_url https://code.visualstudio.com/ pfm_description ${appName} Managed Settings pfm_documentation_url https://code.visualstudio.com/docs/setup/enterprise pfm_domain ${bundleIdentifier} pfm_format_version 1 pfm_interaction combined pfm_last_modified ${new Date().toISOString().replace(/\.\d+Z$/, 'Z')} pfm_platforms macOS pfm_subkeys ${requiredPayloadFields} ${profileManifestSubkeys} pfm_title ${appName} pfm_unique pfm_version 1 `; } function renderMacOSPolicy(policies: Policy[], translations: Translations) { const appName = product.nameLong; const bundleIdentifier = product.darwinBundleIdentifier; const payloadUUID = product.darwinProfilePayloadUUID; const UUID = product.darwinProfileUUID; const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); const categories = [...new Set(policies.map(p => p.category))]; const policyEntries = policies.map(policy => policy.renderProfile()) .flat() .map(entry => `\t\t\t\t${entry}`) .join('\n'); return { profile: ` PayloadContent PayloadDisplayName ${appName} PayloadIdentifier ${bundleIdentifier}.${UUID} PayloadType ${bundleIdentifier} PayloadUUID ${UUID} PayloadVersion 1 ${policyEntries} PayloadDescription This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise PayloadDisplayName ${appName} PayloadIdentifier ${bundleIdentifier} PayloadOrganization Microsoft PayloadType Configuration PayloadUUID ${payloadUUID} PayloadVersion 1 TargetDeviceType 5 `, manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) }, ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) })) ] }; } function renderGP(policies: Policy[], translations: Translations) { const appName = product.nameLong; const regKey = product.win32RegValueName; const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); const categories = [...new Set(policies.map(p => p.category))]; return { admx: renderADMX(regKey, versions, categories, policies), adml: [ { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) }, ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) })) ] }; } const Languages = { 'fr': 'fr-fr', 'it': 'it-it', 'de': 'de-de', 'es': 'es-es', 'ru': 'ru-ru', 'zh-hans': 'zh-cn', 'zh-hant': 'zh-tw', 'ja': 'ja-jp', 'ko': 'ko-kr', 'cs': 'cs-cz', 'pt-br': 'pt-br', 'tr': 'tr-tr', 'pl': 'pl-pl', }; type LanguageTranslations = { [moduleName: string]: { [nlsKey: string]: string } }; type Translations = { languageId: string; languageTranslations: LanguageTranslations }[]; type Version = [number, number, number]; async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, version: Version) { const resource = { publisher: 'ms-ceintl', name: `vscode-language-pack-${languageId}`, version: `${version[0]}.${version[1]}.${version[2]}`, path: 'extension/translations/main.i18n.json' }; const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key as keyof typeof resource]); const res = await fetch(url); if (res.status !== 200) { throw new Error(`[${res.status}] Error downloading language pack ${languageId}@${version}`); } const { contents: result } = await res.json() as { contents: LanguageTranslations }; return result; } function parseVersion(version: string): Version { const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)/.exec(version)!; return [parseInt(major), parseInt(minor), parseInt(patch)]; } function compareVersions(a: Version, b: Version): number { if (a[0] !== b[0]) { return a[0] - b[0]; } if (a[1] !== b[1]) { return a[1] - b[1]; } return a[2] - b[2]; } async function queryVersions(serviceUrl: string, languageId: string): Promise { const res = await fetch(`${serviceUrl}/extensionquery`, { method: 'POST', headers: { 'Accept': 'application/json;api-version=3.0-preview.1', 'Content-Type': 'application/json', 'User-Agent': 'VS Code Build', }, body: JSON.stringify({ filters: [{ criteria: [{ filterType: 7, value: `ms-ceintl.vscode-language-pack-${languageId}` }] }], flags: 0x1 }) }); if (res.status !== 200) { throw new Error(`[${res.status}] Error querying for extension: ${languageId}`); } const result = await res.json() as { results: [{ extensions: { versions: { version: string }[] }[] }] }; return result.results[0].extensions[0].versions.map(v => parseVersion(v.version)).sort(compareVersions); } async function getNLS(extensionGalleryServiceUrl: string, resourceUrlTemplate: string, languageId: string, version: Version) { const versions = await queryVersions(extensionGalleryServiceUrl, languageId); const nextMinor: Version = [version[0], version[1] + 1, 0]; const compatibleVersions = versions.filter(v => compareVersions(v, nextMinor) < 0); const latestCompatibleVersion = compatibleVersions.at(-1)!; // order is newest to oldest if (!latestCompatibleVersion) { throw new Error(`No compatible language pack found for ${languageId} for version ${version}`); } return await getSpecificNLS(resourceUrlTemplate, languageId, latestCompatibleVersion); } async function parsePolicies(): Promise { const parser = new Parser(); parser.setLanguage(typescript); const files = await getFiles(process.cwd()); const base = path.join(process.cwd(), 'src'); const policies = []; for (const file of files) { const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/'); const contents = await fs.readFile(file, { encoding: 'utf8' }); const tree = parser.parse(contents); policies.push(...getPolicies(moduleName, tree.rootNode)); } return policies; } async function getTranslations(): Promise { const extensionGalleryServiceUrl = product.extensionsGallery?.serviceUrl; if (!extensionGalleryServiceUrl) { console.warn(`Skipping policy localization: No 'extensionGallery.serviceUrl' found in 'product.json'.`); return []; } const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate; if (!resourceUrlTemplate) { console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`); return []; } const version = parseVersion(packageJson.version); const languageIds = Object.keys(Languages); return await Promise.all(languageIds.map( languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version) .then(languageTranslations => ({ languageId, languageTranslations })) )); } async function windowsMain(policies: Policy[], translations: Translations) { const root = '.build/policies/win32'; const { admx, adml } = await renderGP(policies, translations); await fs.rm(root, { recursive: true, force: true }); await fs.mkdir(root, { recursive: true }); await fs.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n')); for (const { languageId, contents } of adml) { const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]); await fs.mkdir(languagePath, { recursive: true }); await fs.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n')); } } async function darwinMain(policies: Policy[], translations: Translations) { const bundleIdentifier = product.darwinBundleIdentifier; if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) { throw new Error(`Missing required product information.`); } const root = '.build/policies/darwin'; const { profile, manifests } = await renderMacOSPolicy(policies, translations); await fs.rm(root, { recursive: true, force: true }); await fs.mkdir(root, { recursive: true }); await fs.writeFile(path.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n')); for (const { languageId, contents } of manifests) { const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]); await fs.mkdir(languagePath, { recursive: true }); await fs.writeFile(path.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n')); } } async function main() { const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]); const platform = process.argv[2]; if (platform === 'darwin') { await darwinMain(policies, translations); } else if (platform === 'win32') { await windowsMain(policies, translations); } else { console.error(`Usage: node build/lib/policies `); process.exit(1); } } if (require.main === module) { main().catch(err => { if (err instanceof ParseError) { console.error(`Parse Error:`, err.message); } else { console.error(err); } process.exit(1); }); } ================================================ FILE: build/lib/postcss.js ================================================ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.gulpPostcss = gulpPostcss; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const postcss_1 = __importDefault(require("postcss")); const event_stream_1 = __importDefault(require("event-stream")); function gulpPostcss(plugins, handleError) { const instance = (0, postcss_1.default)(plugins); return event_stream_1.default.map((file, callback) => { if (file.isNull()) { return callback(null, file); } if (file.isStream()) { return callback(new Error('Streaming not supported')); } instance .process(file.contents.toString(), { from: file.path }) .then((result) => { file.contents = Buffer.from(result.css); callback(null, file); }) .catch((error) => { if (handleError) { handleError(error); callback(); } else { callback(error); } }); }); } //# sourceMappingURL=postcss.js.map ================================================ FILE: build/lib/postcss.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import postcss from 'postcss'; import File from 'vinyl'; import es from 'event-stream'; export function gulpPostcss(plugins: postcss.AcceptedPlugin[], handleError?: (err: Error) => void) { const instance = postcss(plugins); return es.map((file: File, callback: (error?: any, file?: any) => void) => { if (file.isNull()) { return callback(null, file); } if (file.isStream()) { return callback(new Error('Streaming not supported')); } instance .process(file.contents.toString(), { from: file.path }) .then((result) => { file.contents = Buffer.from(result.css); callback(null, file); }) .catch((error) => { if (handleError) { handleError(error); callback(); } else { callback(error); } }); }); } ================================================ FILE: build/lib/preLaunch.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); // @ts-check const path_1 = __importDefault(require("path")); const child_process_1 = require("child_process"); const fs_1 = require("fs"); const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'; const rootDir = path_1.default.resolve(__dirname, '..', '..'); function runProcess(command, args = []) { return new Promise((resolve, reject) => { const child = (0, child_process_1.spawn)(command, args, { cwd: rootDir, stdio: 'inherit', env: process.env, shell: process.platform === 'win32' }); child.on('exit', err => !err ? resolve() : process.exit(err ?? 1)); child.on('error', reject); }); } async function exists(subdir) { try { await fs_1.promises.stat(path_1.default.join(rootDir, subdir)); return true; } catch { return false; } } async function ensureNodeModules() { if (!(await exists('node_modules'))) { await runProcess(npm, ['ci']); } } async function getElectron() { await runProcess(npm, ['run', 'electron']); } async function ensureCompiled() { if (!(await exists('out'))) { await runProcess(npm, ['run', 'compile']); } } async function main() { await ensureNodeModules(); await getElectron(); await ensureCompiled(); // Can't require this until after dependencies are installed const { getBuiltInExtensions } = require('./builtInExtensions'); await getBuiltInExtensions(); } if (require.main === module) { main().catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=preLaunch.js.map ================================================ FILE: build/lib/preLaunch.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // @ts-check import path from 'path'; import { spawn } from 'child_process'; import { promises as fs } from 'fs'; const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'; const rootDir = path.resolve(__dirname, '..', '..'); function runProcess(command: string, args: ReadonlyArray = []) { return new Promise((resolve, reject) => { const child = spawn(command, args, { cwd: rootDir, stdio: 'inherit', env: process.env, shell: process.platform === 'win32' }); child.on('exit', err => !err ? resolve() : process.exit(err ?? 1)); child.on('error', reject); }); } async function exists(subdir: string) { try { await fs.stat(path.join(rootDir, subdir)); return true; } catch { return false; } } async function ensureNodeModules() { if (!(await exists('node_modules'))) { await runProcess(npm, ['ci']); } } async function getElectron() { await runProcess(npm, ['run', 'electron']); } async function ensureCompiled() { if (!(await exists('out'))) { await runProcess(npm, ['run', 'compile']); } } async function main() { await ensureNodeModules(); await getElectron(); await ensureCompiled(); // Can't require this until after dependencies are installed const { getBuiltInExtensions } = require('./builtInExtensions'); await getBuiltInExtensions(); } if (require.main === module) { main().catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/lib/propertyInitOrderChecker.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.EntryKind = void 0; const ts = __importStar(require("typescript")); const path = __importStar(require("path")); const fs = __importStar(require("fs")); const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json'); // // ############################################################################################# // // A custom typescript checker that ensure constructor properties are NOT used to initialize // defined properties. This is needed for the times when `useDefineForClassFields` is gone. // // see https://github.com/microsoft/vscode/issues/243049, https://github.com/microsoft/vscode/issues/186726, // https://github.com/microsoft/vscode/pull/241544 // // ############################################################################################# // const ignored = new Set([ 'vs/base/common/arrays.ts', 'vs/platform/extensionManagement/common/extensionsScannerService.ts', 'vs/platform/configuration/common/configurations.ts', 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts', 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts', 'vs/editor/common/model/textModelTokens.ts', 'vs/editor/common/model/tokenizationTextModelPart.ts', 'vs/editor/common/core/textEdit.ts', 'vs/workbench/contrib/debug/common/debugStorage.ts', 'vs/workbench/contrib/debug/common/debugModel.ts', 'vs/workbench/api/common/extHostCommands.ts', 'vs/editor/browser/view/viewLayer.ts', 'vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts', 'vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts', 'vs/editor/browser/widget/diffEditor/utils.ts', 'vs/editor/browser/observableCodeEditor.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts', 'vs/editor/browser/widget/diffEditor/diffEditorOptions.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts', 'vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts', 'vs/editor/browser/widget/diffEditor/utils/editorGutter.ts', 'vs/editor/browser/widget/diffEditor/features/gutterFeature.ts', 'vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts', 'vs/editor/browser/widget/diffEditor/diffEditorWidget.ts', 'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts', 'vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts', 'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts', 'vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts', 'vs/editor/contrib/inlayHints/browser/inlayHintsController.ts', 'vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts', 'vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineCompletionsView.ts', 'vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts', 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts', 'vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts', 'vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts', 'vs/workbench/contrib/chat/common/promptSyntax/parsers/basePromptParser.ts', 'vs/workbench/contrib/files/browser/views/openEditorsView.ts', 'vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts', 'vs/workbench/contrib/chat/browser/contrib/chatImplicitContext.ts', 'vs/workbench/contrib/chat/browser/chatInputPart.ts', 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts', 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts', 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts', 'vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts', 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts', 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts', 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts', 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts', 'vs/platform/terminal/common/capabilities/commandDetectionCapability.ts', 'vs/workbench/contrib/testing/common/testExclusions.ts', 'vs/workbench/contrib/testing/common/testResultStorage.ts', 'vs/workbench/services/userDataProfile/browser/snippetsResource.ts', 'vs/platform/quickinput/browser/quickInputController.ts', 'vs/platform/userDataSync/common/abstractSynchronizer.ts', 'vs/workbench/services/authentication/browser/authenticationExtensionsService.ts', 'vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts', 'vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts', 'vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts', 'vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts', 'vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts', 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts', 'vs/workbench/contrib/notebook/browser/diff/notebookMultiDiffEditor.ts', 'vs/workbench/contrib/chat/common/promptSyntax/contentProviders/textModelContentsProvider.ts', 'vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts', 'vs/workbench/contrib/search/common/cacheState.ts', 'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts', 'vs/workbench/contrib/search/browser/anythingQuickAccess.ts', 'vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts', 'vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts', 'vs/workbench/contrib/testing/common/testExplorerFilterState.ts', 'vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.ts', 'vs/workbench/contrib/testing/browser/testingOutputPeek.ts', 'vs/workbench/contrib/testing/browser/explorerProjections/index.ts', 'vs/workbench/contrib/testing/browser/testingExplorerFilter.ts', 'vs/workbench/contrib/testing/browser/testingExplorerView.ts', 'vs/workbench/contrib/testing/common/testServiceImpl.ts', 'vs/platform/quickinput/browser/commandsQuickAccess.ts', 'vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts', 'vs/workbench/contrib/multiDiffEditor/browser/scmMultiDiffSourceResolver.ts', 'vs/workbench/contrib/debug/browser/debugMemory.ts', 'vs/workbench/contrib/markers/browser/markersViewActions.ts', 'vs/workbench/contrib/mergeEditor/browser/view/viewZones.ts', 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts', 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts', 'vs/workbench/contrib/output/browser/outputServices.ts', 'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminalTypeAheadAddon.ts', 'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts', 'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts', 'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts', 'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts', 'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts', 'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts', 'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts', 'vs/platform/terminal/node/ptyService.ts', 'vs/workbench/api/common/extHostLanguageFeatures.ts', 'vs/workbench/api/common/extHostSearch.ts', 'vs/workbench/contrib/testing/test/common/testStubs.ts' ]); const cancellationToken = { isCancellationRequested: () => false, throwIfCancellationRequested: () => { }, }; const seenFiles = new Set(); let errorCount = 0; function createProgram(tsconfigPath) { const tsConfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile); const configHostParser = { fileExists: fs.existsSync, readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' }; const tsConfigParsed = ts.parseJsonConfigFileContent(tsConfig.config, configHostParser, path.resolve(path.dirname(tsconfigPath)), { noEmit: true }); const compilerHost = ts.createCompilerHost(tsConfigParsed.options, true); return ts.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost); } const program = createProgram(TS_CONFIG_PATH); program.getTypeChecker(); for (const file of program.getSourceFiles()) { if (!file || file.isDeclarationFile) { continue; } const relativePath = path.relative(path.dirname(TS_CONFIG_PATH), file.fileName).replace(/\\/g, '/'); if (ignored.has(relativePath)) { continue; } visit(file); } if (seenFiles.size) { console.log(); console.log(`Found ${errorCount} error${errorCount === 1 ? '' : 's'} in ${seenFiles.size} file${seenFiles.size === 1 ? '' : 's'}.`); process.exit(errorCount); } function visit(node) { if (ts.isParameter(node) && ts.isParameterPropertyDeclaration(node, node.parent)) { checkParameterPropertyDeclaration(node); } ts.forEachChild(node, visit); } function checkParameterPropertyDeclaration(param) { const uses = [...collectReferences(param.name, [])]; if (!uses.length) { return; } const sourceFile = param.getSourceFile(); if (!seenFiles.has(sourceFile)) { if (seenFiles.size) { console.log(``); } console.log(`${formatFileName(param)}:`); seenFiles.add(sourceFile); } else { console.log(``); } console.log(` Parameter property '${param.name.getText()}' is used before its declaration.`); for (const { stack, container } of uses) { const use = stack[stack.length - 1]; console.log(` at ${formatLocation(use)}: ${formatMember(container)} -> ${formatStack(stack)}`); errorCount++; } } function* collectReferences(node, stack, requiresInvocationDepth = 0, seen = new Set()) { for (const use of findAllReferencesInClass(node)) { const container = findContainer(use); if (!container || seen.has(container) || ts.isConstructorDeclaration(container)) { continue; } seen.add(container); const nextStack = [...stack, use]; let nextRequiresInvocationDepth = requiresInvocationDepth; if (isInvocation(use) && nextRequiresInvocationDepth > 0) { nextRequiresInvocationDepth--; } if (ts.isPropertyDeclaration(container) && nextRequiresInvocationDepth === 0) { yield { stack: nextStack, container }; } else if (requiresInvocation(container)) { nextRequiresInvocationDepth++; } yield* collectReferences(container.name ?? container, nextStack, nextRequiresInvocationDepth, seen); } } function requiresInvocation(definition) { return ts.isMethodDeclaration(definition) || ts.isFunctionDeclaration(definition) || ts.isFunctionExpression(definition) || ts.isArrowFunction(definition); } function isInvocation(use) { let location = use; if (ts.isPropertyAccessExpression(location.parent) && location.parent.name === location) { location = location.parent; } else if (ts.isElementAccessExpression(location.parent) && location.parent.argumentExpression === location) { location = location.parent; } return ts.isCallExpression(location.parent) && location.parent.expression === location || ts.isTaggedTemplateExpression(location.parent) && location.parent.tag === location; } function formatFileName(node) { const sourceFile = node.getSourceFile(); return path.resolve(sourceFile.fileName); } function formatLocation(node) { const sourceFile = node.getSourceFile(); const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); return `${formatFileName(sourceFile)}(${line + 1},${character + 1})`; } function formatStack(stack) { return stack.slice().reverse().map((use) => formatUse(use)).join(' -> '); } function formatMember(container) { const name = container.name?.getText(); if (name) { const className = findClass(container)?.name?.getText(); if (className) { return `${className}.${name}`; } return name; } return ''; } function formatUse(use) { let text = use.getText(); if (use.parent && ts.isPropertyAccessExpression(use.parent) && use.parent.name === use) { if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) { text = `this.${text}`; } use = use.parent; } else if (use.parent && ts.isElementAccessExpression(use.parent) && use.parent.argumentExpression === use) { if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) { text = `this['${text}']`; } use = use.parent; } if (ts.isCallExpression(use.parent)) { text = `${text}(...)`; } return text; } function findContainer(node) { return ts.findAncestor(node, ancestor => { switch (ancestor.kind) { case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.MethodDeclaration: case ts.SyntaxKind.GetAccessor: case ts.SyntaxKind.SetAccessor: case ts.SyntaxKind.Constructor: case ts.SyntaxKind.ClassStaticBlockDeclaration: case ts.SyntaxKind.ArrowFunction: case ts.SyntaxKind.FunctionExpression: case ts.SyntaxKind.FunctionDeclaration: case ts.SyntaxKind.Parameter: return true; } return false; }); } function findClass(node) { return ts.findAncestor(node, ts.isClassLike); } function* findAllReferencesInClass(node) { const classDecl = findClass(node); if (!classDecl) { return []; } for (const ref of findAllReferences(node)) { for (const entry of ref.references) { if (entry.kind !== 1 /* EntryKind.Node */ || entry.node === node) { continue; } if (findClass(entry.node) === classDecl) { yield entry.node; } } } } // NOTE: The following uses TypeScript internals and are subject to change from version to version. function findAllReferences(node) { const sourceFile = node.getSourceFile(); const position = node.getStart(); const name = ts.getTouchingPropertyName(sourceFile, position); const options = { use: ts.FindAllReferences.FindReferencesUse.References }; return ts.FindAllReferences.Core.getReferencedSymbolsForNode(position, name, program, [sourceFile], cancellationToken, options) ?? []; } var DefinitionKind; (function (DefinitionKind) { DefinitionKind[DefinitionKind["Symbol"] = 0] = "Symbol"; DefinitionKind[DefinitionKind["Label"] = 1] = "Label"; DefinitionKind[DefinitionKind["Keyword"] = 2] = "Keyword"; DefinitionKind[DefinitionKind["This"] = 3] = "This"; DefinitionKind[DefinitionKind["String"] = 4] = "String"; DefinitionKind[DefinitionKind["TripleSlashReference"] = 5] = "TripleSlashReference"; })(DefinitionKind || (DefinitionKind = {})); /** @internal */ var EntryKind; (function (EntryKind) { EntryKind[EntryKind["Span"] = 0] = "Span"; EntryKind[EntryKind["Node"] = 1] = "Node"; EntryKind[EntryKind["StringLiteral"] = 2] = "StringLiteral"; EntryKind[EntryKind["SearchedLocalFoundProperty"] = 3] = "SearchedLocalFoundProperty"; EntryKind[EntryKind["SearchedPropertyFoundLocal"] = 4] = "SearchedPropertyFoundLocal"; })(EntryKind || (exports.EntryKind = EntryKind = {})); //# sourceMappingURL=propertyInitOrderChecker.js.map ================================================ FILE: build/lib/propertyInitOrderChecker.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as ts from 'typescript'; import * as path from 'path'; import * as fs from 'fs'; const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json'); // // ############################################################################################# // // A custom typescript checker that ensure constructor properties are NOT used to initialize // defined properties. This is needed for the times when `useDefineForClassFields` is gone. // // see https://github.com/microsoft/vscode/issues/243049, https://github.com/microsoft/vscode/issues/186726, // https://github.com/microsoft/vscode/pull/241544 // // ############################################################################################# // const ignored = new Set([ 'vs/base/common/arrays.ts', 'vs/platform/extensionManagement/common/extensionsScannerService.ts', 'vs/platform/configuration/common/configurations.ts', 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts', 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts', 'vs/editor/common/model/textModelTokens.ts', 'vs/editor/common/model/tokenizationTextModelPart.ts', 'vs/editor/common/core/textEdit.ts', 'vs/workbench/contrib/debug/common/debugStorage.ts', 'vs/workbench/contrib/debug/common/debugModel.ts', 'vs/workbench/api/common/extHostCommands.ts', 'vs/editor/browser/view/viewLayer.ts', 'vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts', 'vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts', 'vs/editor/browser/widget/diffEditor/utils.ts', 'vs/editor/browser/observableCodeEditor.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts', 'vs/editor/browser/widget/diffEditor/diffEditorOptions.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts', 'vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts', 'vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts', 'vs/editor/browser/widget/diffEditor/utils/editorGutter.ts', 'vs/editor/browser/widget/diffEditor/features/gutterFeature.ts', 'vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts', 'vs/editor/browser/widget/diffEditor/diffEditorWidget.ts', 'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts', 'vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts', 'vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts', 'vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts', 'vs/editor/contrib/inlayHints/browser/inlayHintsController.ts', 'vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts', 'vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineCompletionsView.ts', 'vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts', 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts', 'vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts', 'vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts', 'vs/workbench/contrib/chat/common/promptSyntax/parsers/basePromptParser.ts', 'vs/workbench/contrib/files/browser/views/openEditorsView.ts', 'vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts', 'vs/workbench/contrib/chat/browser/contrib/chatImplicitContext.ts', 'vs/workbench/contrib/chat/browser/chatInputPart.ts', 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts', 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts', 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts', 'vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts', 'vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts', 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts', 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts', 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts', 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts', 'vs/platform/terminal/common/capabilities/commandDetectionCapability.ts', 'vs/workbench/contrib/testing/common/testExclusions.ts', 'vs/workbench/contrib/testing/common/testResultStorage.ts', 'vs/workbench/services/userDataProfile/browser/snippetsResource.ts', 'vs/platform/quickinput/browser/quickInputController.ts', 'vs/platform/userDataSync/common/abstractSynchronizer.ts', 'vs/workbench/services/authentication/browser/authenticationExtensionsService.ts', 'vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts', 'vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts', 'vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts', 'vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts', 'vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts', 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts', 'vs/workbench/contrib/notebook/browser/diff/notebookMultiDiffEditor.ts', 'vs/workbench/contrib/chat/common/promptSyntax/contentProviders/textModelContentsProvider.ts', 'vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts', 'vs/workbench/contrib/search/common/cacheState.ts', 'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts', 'vs/workbench/contrib/search/browser/anythingQuickAccess.ts', 'vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts', 'vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts', 'vs/workbench/contrib/testing/common/testExplorerFilterState.ts', 'vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.ts', 'vs/workbench/contrib/testing/browser/testingOutputPeek.ts', 'vs/workbench/contrib/testing/browser/explorerProjections/index.ts', 'vs/workbench/contrib/testing/browser/testingExplorerFilter.ts', 'vs/workbench/contrib/testing/browser/testingExplorerView.ts', 'vs/workbench/contrib/testing/common/testServiceImpl.ts', 'vs/platform/quickinput/browser/commandsQuickAccess.ts', 'vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts', 'vs/workbench/contrib/multiDiffEditor/browser/scmMultiDiffSourceResolver.ts', 'vs/workbench/contrib/debug/browser/debugMemory.ts', 'vs/workbench/contrib/markers/browser/markersViewActions.ts', 'vs/workbench/contrib/mergeEditor/browser/view/viewZones.ts', 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts', 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts', 'vs/workbench/contrib/output/browser/outputServices.ts', 'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminalTypeAheadAddon.ts', 'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts', 'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts', 'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts', 'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts', 'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts', 'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts', 'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts', 'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts', 'vs/platform/terminal/node/ptyService.ts', 'vs/workbench/api/common/extHostLanguageFeatures.ts', 'vs/workbench/api/common/extHostSearch.ts', 'vs/workbench/contrib/testing/test/common/testStubs.ts' ]); const cancellationToken: ts.CancellationToken = { isCancellationRequested: () => false, throwIfCancellationRequested: () => { }, }; const seenFiles = new Set(); let errorCount = 0; function createProgram(tsconfigPath: string): ts.Program { const tsConfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile); const configHostParser: ts.ParseConfigHost = { fileExists: fs.existsSync, readDirectory: ts.sys.readDirectory, readFile: file => fs.readFileSync(file, 'utf8'), useCaseSensitiveFileNames: process.platform === 'linux' }; const tsConfigParsed = ts.parseJsonConfigFileContent(tsConfig.config, configHostParser, path.resolve(path.dirname(tsconfigPath)), { noEmit: true }); const compilerHost = ts.createCompilerHost(tsConfigParsed.options, true); return ts.createProgram(tsConfigParsed.fileNames, tsConfigParsed.options, compilerHost); } const program = createProgram(TS_CONFIG_PATH); program.getTypeChecker(); for (const file of program.getSourceFiles()) { if (!file || file.isDeclarationFile) { continue; } const relativePath = path.relative(path.dirname(TS_CONFIG_PATH), file.fileName).replace(/\\/g, '/'); if (ignored.has(relativePath)) { continue; } visit(file); } if (seenFiles.size) { console.log(); console.log(`Found ${errorCount} error${errorCount === 1 ? '' : 's'} in ${seenFiles.size} file${seenFiles.size === 1 ? '' : 's'}.`); process.exit(errorCount); } function visit(node: ts.Node) { if (ts.isParameter(node) && ts.isParameterPropertyDeclaration(node, node.parent)) { checkParameterPropertyDeclaration(node); } ts.forEachChild(node, visit); } function checkParameterPropertyDeclaration(param: ts.ParameterPropertyDeclaration) { const uses = [...collectReferences(param.name, [])]; if (!uses.length) { return; } const sourceFile = param.getSourceFile(); if (!seenFiles.has(sourceFile)) { if (seenFiles.size) { console.log(``); } console.log(`${formatFileName(param)}:`); seenFiles.add(sourceFile); } else { console.log(``); } console.log(` Parameter property '${param.name.getText()}' is used before its declaration.`); for (const { stack, container } of uses) { const use = stack[stack.length - 1]; console.log(` at ${formatLocation(use)}: ${formatMember(container)} -> ${formatStack(stack)}`); errorCount++; } } interface InvalidUse { stack: ts.Node[]; container: ReferenceContainer; } function* collectReferences(node: ts.Node, stack: ts.Node[], requiresInvocationDepth: number = 0, seen = new Set()): Generator { for (const use of findAllReferencesInClass(node)) { const container = findContainer(use); if (!container || seen.has(container) || ts.isConstructorDeclaration(container)) { continue; } seen.add(container); const nextStack = [...stack, use]; let nextRequiresInvocationDepth = requiresInvocationDepth; if (isInvocation(use) && nextRequiresInvocationDepth > 0) { nextRequiresInvocationDepth--; } if (ts.isPropertyDeclaration(container) && nextRequiresInvocationDepth === 0) { yield { stack: nextStack, container }; } else if (requiresInvocation(container)) { nextRequiresInvocationDepth++; } yield* collectReferences(container.name ?? container, nextStack, nextRequiresInvocationDepth, seen); } } function requiresInvocation(definition: ReferenceContainer): boolean { return ts.isMethodDeclaration(definition) || ts.isFunctionDeclaration(definition) || ts.isFunctionExpression(definition) || ts.isArrowFunction(definition); } function isInvocation(use: ts.Node): boolean { let location = use; if (ts.isPropertyAccessExpression(location.parent) && location.parent.name === location) { location = location.parent; } else if (ts.isElementAccessExpression(location.parent) && location.parent.argumentExpression === location) { location = location.parent; } return ts.isCallExpression(location.parent) && location.parent.expression === location || ts.isTaggedTemplateExpression(location.parent) && location.parent.tag === location; } function formatFileName(node: ts.Node): string { const sourceFile = node.getSourceFile(); return path.resolve(sourceFile.fileName); } function formatLocation(node: ts.Node): string { const sourceFile = node.getSourceFile(); const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); return `${formatFileName(sourceFile)}(${line + 1},${character + 1})`; } function formatStack(stack: ts.Node[]): string { return stack.slice().reverse().map((use) => formatUse(use)).join(' -> '); } function formatMember(container: ReferenceContainer): string { const name = container.name?.getText(); if (name) { const className = findClass(container)?.name?.getText(); if (className) { return `${className}.${name}`; } return name; } return ''; } function formatUse(use: ts.Node): string { let text = use.getText(); if (use.parent && ts.isPropertyAccessExpression(use.parent) && use.parent.name === use) { if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) { text = `this.${text}`; } use = use.parent; } else if (use.parent && ts.isElementAccessExpression(use.parent) && use.parent.argumentExpression === use) { if (use.parent.expression.kind === ts.SyntaxKind.ThisKeyword) { text = `this['${text}']`; } use = use.parent; } if (ts.isCallExpression(use.parent)) { text = `${text}(...)`; } return text; } type ReferenceContainer = | ts.PropertyDeclaration | ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration | ts.ConstructorDeclaration | ts.ClassStaticBlockDeclaration | ts.ArrowFunction | ts.FunctionExpression | ts.FunctionDeclaration | ts.ParameterDeclaration; function findContainer(node: ts.Node): ReferenceContainer | undefined { return ts.findAncestor(node, ancestor => { switch (ancestor.kind) { case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.MethodDeclaration: case ts.SyntaxKind.GetAccessor: case ts.SyntaxKind.SetAccessor: case ts.SyntaxKind.Constructor: case ts.SyntaxKind.ClassStaticBlockDeclaration: case ts.SyntaxKind.ArrowFunction: case ts.SyntaxKind.FunctionExpression: case ts.SyntaxKind.FunctionDeclaration: case ts.SyntaxKind.Parameter: return true; } return false; }) as ReferenceContainer | undefined; } function findClass(node: ts.Node): ts.ClassLikeDeclaration | undefined { return ts.findAncestor(node, ts.isClassLike); } function* findAllReferencesInClass(node: ts.Node): Generator { const classDecl = findClass(node); if (!classDecl) { return []; } for (const ref of findAllReferences(node)) { for (const entry of ref.references) { if (entry.kind !== EntryKind.Node || entry.node === node) { continue; } if (findClass(entry.node) === classDecl) { yield entry.node; } } } } // NOTE: The following uses TypeScript internals and are subject to change from version to version. function findAllReferences(node: ts.Node): readonly SymbolAndEntries[] { const sourceFile = node.getSourceFile(); const position = node.getStart(); const name: ts.Node = (ts as any).getTouchingPropertyName(sourceFile, position); const options = { use: (ts as any).FindAllReferences.FindReferencesUse.References }; return (ts as any).FindAllReferences.Core.getReferencedSymbolsForNode(position, name, program, [sourceFile], cancellationToken, options) ?? []; } interface SymbolAndEntries { readonly definition: Definition | undefined; readonly references: readonly Entry[]; } const enum DefinitionKind { Symbol, Label, Keyword, This, String, TripleSlashReference, } type Definition = | { readonly type: DefinitionKind.Symbol; readonly symbol: ts.Symbol } | { readonly type: DefinitionKind.Label; readonly node: ts.Identifier } | { readonly type: DefinitionKind.Keyword; readonly node: ts.Node } | { readonly type: DefinitionKind.This; readonly node: ts.Node } | { readonly type: DefinitionKind.String; readonly node: ts.StringLiteralLike } | { readonly type: DefinitionKind.TripleSlashReference; readonly reference: ts.FileReference; readonly file: ts.SourceFile }; /** @internal */ export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal, } type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal; type Entry = NodeEntry | SpanEntry; interface ContextWithStartAndEndNode { start: ts.Node; end: ts.Node; } type ContextNode = ts.Node | ContextWithStartAndEndNode; interface NodeEntry { readonly kind: NodeEntryKind; readonly node: ts.Node; readonly context?: ContextNode; } interface SpanEntry { readonly kind: EntryKind.Span; readonly fileName: string; readonly textSpan: ts.TextSpan; } ================================================ FILE: build/lib/reporter.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReporter = createReporter; const event_stream_1 = __importDefault(require("event-stream")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); class ErrorLog { id; constructor(id) { this.id = id; } allErrors = []; startTime = null; count = 0; onStart() { if (this.count++ > 0) { return; } this.startTime = new Date().getTime(); (0, fancy_log_1.default)(`Starting ${ansi_colors_1.default.green('compilation')}${this.id ? ansi_colors_1.default.blue(` ${this.id}`) : ''}...`); } onEnd() { if (--this.count > 0) { return; } this.log(); } log() { const errors = this.allErrors.flat(); const seen = new Set(); errors.map(err => { if (!seen.has(err)) { seen.add(err); (0, fancy_log_1.default)(`${ansi_colors_1.default.red('Error')}: ${err}`); } }); (0, fancy_log_1.default)(`Finished ${ansi_colors_1.default.green('compilation')}${this.id ? ansi_colors_1.default.blue(` ${this.id}`) : ''} with ${errors.length} errors after ${ansi_colors_1.default.magenta((new Date().getTime() - this.startTime) + ' ms')}`); const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/s; const messages = errors .map(err => regex.exec(err)) .filter(match => !!match) .map(x => x) .map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message })); try { const logFileName = 'log' + (this.id ? `_${this.id}` : ''); fs_1.default.writeFileSync(path_1.default.join(buildLogFolder, logFileName), JSON.stringify(messages)); } catch (err) { //noop } } } const errorLogsById = new Map(); function getErrorLog(id = '') { let errorLog = errorLogsById.get(id); if (!errorLog) { errorLog = new ErrorLog(id); errorLogsById.set(id, errorLog); } return errorLog; } const buildLogFolder = path_1.default.join(path_1.default.dirname(path_1.default.dirname(__dirname)), '.build'); try { fs_1.default.mkdirSync(buildLogFolder); } catch (err) { // ignore } function createReporter(id) { const errorLog = getErrorLog(id); const errors = []; errorLog.allErrors.push(errors); const result = (err) => errors.push(err); result.hasErrors = () => errors.length > 0; result.end = (emitError) => { errors.length = 0; errorLog.onStart(); return event_stream_1.default.through(undefined, function () { errorLog.onEnd(); if (emitError && errors.length > 0) { if (!errors.__logged__) { errorLog.log(); } errors.__logged__ = true; const err = new Error(`Found ${errors.length} errors`); err.__reporter__ = true; this.emit('error', err); } else { this.emit('end'); } }); }; return result; } //# sourceMappingURL=reporter.js.map ================================================ FILE: build/lib/reporter.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import fs from 'fs'; import path from 'path'; class ErrorLog { constructor(public id: string) { } allErrors: string[][] = []; startTime: number | null = null; count = 0; onStart(): void { if (this.count++ > 0) { return; } this.startTime = new Date().getTime(); fancyLog(`Starting ${ansiColors.green('compilation')}${this.id ? ansiColors.blue(` ${this.id}`) : ''}...`); } onEnd(): void { if (--this.count > 0) { return; } this.log(); } log(): void { const errors = this.allErrors.flat(); const seen = new Set(); errors.map(err => { if (!seen.has(err)) { seen.add(err); fancyLog(`${ansiColors.red('Error')}: ${err}`); } }); fancyLog(`Finished ${ansiColors.green('compilation')}${this.id ? ansiColors.blue(` ${this.id}`) : ''} with ${errors.length} errors after ${ansiColors.magenta((new Date().getTime() - this.startTime!) + ' ms')}`); const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/s; const messages = errors .map(err => regex.exec(err)) .filter(match => !!match) .map(x => x as string[]) .map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message })); try { const logFileName = 'log' + (this.id ? `_${this.id}` : ''); fs.writeFileSync(path.join(buildLogFolder, logFileName), JSON.stringify(messages)); } catch (err) { //noop } } } const errorLogsById = new Map(); function getErrorLog(id: string = '') { let errorLog = errorLogsById.get(id); if (!errorLog) { errorLog = new ErrorLog(id); errorLogsById.set(id, errorLog); } return errorLog; } const buildLogFolder = path.join(path.dirname(path.dirname(__dirname)), '.build'); try { fs.mkdirSync(buildLogFolder); } catch (err) { // ignore } export interface IReporter { (err: string): void; hasErrors(): boolean; end(emitError: boolean): NodeJS.ReadWriteStream; } export function createReporter(id?: string): IReporter { const errorLog = getErrorLog(id); const errors: string[] = []; errorLog.allErrors.push(errors); const result = (err: string) => errors.push(err); result.hasErrors = () => errors.length > 0; result.end = (emitError: boolean): NodeJS.ReadWriteStream => { errors.length = 0; errorLog.onStart(); return es.through(undefined, function () { errorLog.onEnd(); if (emitError && errors.length > 0) { if (!(errors as any).__logged__) { errorLog.log(); } (errors as any).__logged__ = true; const err = new Error(`Found ${errors.length} errors`); (err as any).__reporter__ = true; this.emit('error', err); } else { this.emit('end'); } }); }; return result; } ================================================ FILE: build/lib/snapshotLoader.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.snaps = void 0; var snaps; (function (snaps) { const fs = require('fs'); const path = require('path'); const os = require('os'); const cp = require('child_process'); const mksnapshot = path.join(__dirname, `../../node_modules/.bin/${process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'}`); const product = require('../../product.json'); const arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1]; // let loaderFilepath; let startupBlobFilepath; switch (process.platform) { case 'darwin': loaderFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Resources/app/out/vs/loader.js`; startupBlobFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`; break; case 'win32': case 'linux': loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`; startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`; break; default: throw new Error('Unknown platform'); } loaderFilepath = path.join(__dirname, '../../../', loaderFilepath); startupBlobFilepath = path.join(__dirname, '../../../', startupBlobFilepath); snapshotLoader(loaderFilepath, startupBlobFilepath); function snapshotLoader(loaderFilepath, startupBlobFilepath) { const inputFile = fs.readFileSync(loaderFilepath); const wrappedInputFile = ` var Monaco_Loader_Init; (function() { var doNotInitLoader = true; ${inputFile.toString()}; Monaco_Loader_Init = function() { AMDLoader.init(); CSSLoaderPlugin.init(); NLSLoaderPlugin.init(); return { define, require }; } })(); `; const wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js'); console.log(wrappedInputFilepath); fs.writeFileSync(wrappedInputFilepath, wrappedInputFile); cp.execFileSync(mksnapshot, [wrappedInputFilepath, `--startup_blob`, startupBlobFilepath]); } })(snaps || (exports.snaps = snaps = {})); //# sourceMappingURL=snapshotLoader.js.map ================================================ FILE: build/lib/snapshotLoader.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export namespace snaps { const fs = require('fs'); const path = require('path'); const os = require('os'); const cp = require('child_process'); const mksnapshot = path.join(__dirname, `../../node_modules/.bin/${process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'}`); const product = require('../../product.json'); const arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1]; // let loaderFilepath: string; let startupBlobFilepath: string; switch (process.platform) { case 'darwin': loaderFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Resources/app/out/vs/loader.js`; startupBlobFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`; break; case 'win32': case 'linux': loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`; startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`; break; default: throw new Error('Unknown platform'); } loaderFilepath = path.join(__dirname, '../../../', loaderFilepath); startupBlobFilepath = path.join(__dirname, '../../../', startupBlobFilepath); snapshotLoader(loaderFilepath, startupBlobFilepath); function snapshotLoader(loaderFilepath: string, startupBlobFilepath: string): void { const inputFile = fs.readFileSync(loaderFilepath); const wrappedInputFile = ` var Monaco_Loader_Init; (function() { var doNotInitLoader = true; ${inputFile.toString()}; Monaco_Loader_Init = function() { AMDLoader.init(); CSSLoaderPlugin.init(); NLSLoaderPlugin.init(); return { define, require }; } })(); `; const wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js'); console.log(wrappedInputFilepath); fs.writeFileSync(wrappedInputFilepath, wrappedInputFile); cp.execFileSync(mksnapshot, [wrappedInputFilepath, `--startup_blob`, startupBlobFilepath]); } } ================================================ FILE: build/lib/standalone.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractEditor = extractEditor; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const tss = __importStar(require("./treeshaking")); const REPO_ROOT = path_1.default.join(__dirname, '../../'); const SRC_DIR = path_1.default.join(REPO_ROOT, 'src'); const dirCache = {}; function writeFile(filePath, contents) { function ensureDirs(dirPath) { if (dirCache[dirPath]) { return; } dirCache[dirPath] = true; ensureDirs(path_1.default.dirname(dirPath)); if (fs_1.default.existsSync(dirPath)) { return; } fs_1.default.mkdirSync(dirPath); } ensureDirs(path_1.default.dirname(filePath)); fs_1.default.writeFileSync(filePath, contents); } function extractEditor(options) { const ts = require('typescript'); const tsConfig = JSON.parse(fs_1.default.readFileSync(path_1.default.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString()); let compilerOptions; if (tsConfig.extends) { compilerOptions = Object.assign({}, require(path_1.default.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions); delete tsConfig.extends; } else { compilerOptions = tsConfig.compilerOptions; } tsConfig.compilerOptions = compilerOptions; tsConfig.compilerOptions.sourceMap = true; tsConfig.compilerOptions.module = 'es2022'; tsConfig.compilerOptions.outDir = options.tsOutDir; compilerOptions.noEmit = false; compilerOptions.noUnusedLocals = false; compilerOptions.preserveConstEnums = false; compilerOptions.declaration = false; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; options.compilerOptions = compilerOptions; console.log(`Running tree shaker with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`); // Take the extra included .d.ts files from `tsconfig.monaco.json` options.typings = tsConfig.include.filter(includedFile => /\.d\.ts$/.test(includedFile)); // Add extra .d.ts files from `node_modules/@types/` if (Array.isArray(options.compilerOptions?.types)) { options.compilerOptions.types.forEach((type) => { if (type === '@webgpu/types') { options.typings.push(`../node_modules/${type}/dist/index.d.ts`); } else { options.typings.push(`../node_modules/@types/${type}/index.d.ts`); } }); } const result = tss.shake(options); for (const fileName in result) { if (result.hasOwnProperty(fileName)) { writeFile(path_1.default.join(options.destRoot, fileName), result[fileName]); } } const copied = {}; const copyFile = (fileName) => { if (copied[fileName]) { return; } copied[fileName] = true; const srcPath = path_1.default.join(options.sourcesRoot, fileName); const dstPath = path_1.default.join(options.destRoot, fileName); writeFile(dstPath, fs_1.default.readFileSync(srcPath)); }; const writeOutputFile = (fileName, contents) => { writeFile(path_1.default.join(options.destRoot, fileName), contents); }; for (const fileName in result) { if (result.hasOwnProperty(fileName)) { const fileContents = result[fileName]; const info = ts.preProcessFile(fileContents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { const importedFileName = info.importedFiles[i].fileName; let importedFilePath = importedFileName; if (/(^\.\/)|(^\.\.\/)/.test(importedFilePath)) { importedFilePath = path_1.default.join(path_1.default.dirname(fileName), importedFilePath); } if (/\.css$/.test(importedFilePath)) { transportCSS(importedFilePath, copyFile, writeOutputFile); } else { const pathToCopy = path_1.default.join(options.sourcesRoot, importedFilePath); if (fs_1.default.existsSync(pathToCopy) && !fs_1.default.statSync(pathToCopy).isDirectory()) { copyFile(importedFilePath); } } } } } delete tsConfig.compilerOptions.moduleResolution; writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ 'vs/loader.js' ].forEach(copyFile); } function transportCSS(module, enqueue, write) { if (!/\.css/.test(module)) { return false; } const filename = path_1.default.join(SRC_DIR, module); const fileContents = fs_1.default.readFileSync(filename).toString(); const inlineResources = 'base64'; // see https://github.com/microsoft/monaco-editor/issues/148 const newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64'); write(module, newContents); return true; function _rewriteOrInlineUrls(contents, forceBase64) { return _replaceURL(contents, (url) => { const fontMatch = url.match(/^(.*).ttf\?(.*)$/); if (fontMatch) { const relativeFontPath = `${fontMatch[1]}.ttf`; // trim the query parameter const fontPath = path_1.default.join(path_1.default.dirname(module), relativeFontPath); enqueue(fontPath); return relativeFontPath; } const imagePath = path_1.default.join(path_1.default.dirname(module), url); const fileContents = fs_1.default.readFileSync(path_1.default.join(SRC_DIR, imagePath)); const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; let DATA = ';base64,' + fileContents.toString('base64'); if (!forceBase64 && /\.svg$/.test(url)) { // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris const newText = fileContents.toString() .replace(/"/g, '\'') .replace(//g, '%3E') .replace(/&/g, '%26') .replace(/#/g, '%23') .replace(/\s+/g, ' '); const encodedData = ',' + newText; if (encodedData.length < DATA.length) { DATA = encodedData; } } return '"data:' + MIME + DATA + '"'; }); } function _replaceURL(contents, replacer) { // Use ")" as the terminator as quotes are oftentimes not used at all return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_, ...matches) => { let url = matches[0]; // Eliminate starting quotes (the initial whitespace is not captured) if (url.charAt(0) === '"' || url.charAt(0) === '\'') { url = url.substring(1); } // The ending whitespace is captured while (url.length > 0 && (url.charAt(url.length - 1) === ' ' || url.charAt(url.length - 1) === '\t')) { url = url.substring(0, url.length - 1); } // Eliminate ending quotes if (url.charAt(url.length - 1) === '"' || url.charAt(url.length - 1) === '\'') { url = url.substring(0, url.length - 1); } if (!_startsWith(url, 'data:') && !_startsWith(url, 'http://') && !_startsWith(url, 'https://')) { url = replacer(url); } return 'url(' + url + ')'; }); } function _startsWith(haystack, needle) { return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; } } //# sourceMappingURL=standalone.js.map ================================================ FILE: build/lib/standalone.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import * as tss from './treeshaking'; const REPO_ROOT = path.join(__dirname, '../../'); const SRC_DIR = path.join(REPO_ROOT, 'src'); const dirCache: { [dir: string]: boolean } = {}; function writeFile(filePath: string, contents: Buffer | string): void { function ensureDirs(dirPath: string): void { if (dirCache[dirPath]) { return; } dirCache[dirPath] = true; ensureDirs(path.dirname(dirPath)); if (fs.existsSync(dirPath)) { return; } fs.mkdirSync(dirPath); } ensureDirs(path.dirname(filePath)); fs.writeFileSync(filePath, contents); } export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string; tsOutDir: string }): void { const ts = require('typescript') as typeof import('typescript'); const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString()); let compilerOptions: { [key: string]: any }; if (tsConfig.extends) { compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions); delete tsConfig.extends; } else { compilerOptions = tsConfig.compilerOptions; } tsConfig.compilerOptions = compilerOptions; tsConfig.compilerOptions.sourceMap = true; tsConfig.compilerOptions.module = 'es2022'; tsConfig.compilerOptions.outDir = options.tsOutDir; compilerOptions.noEmit = false; compilerOptions.noUnusedLocals = false; compilerOptions.preserveConstEnums = false; compilerOptions.declaration = false; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; options.compilerOptions = compilerOptions; console.log(`Running tree shaker with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`); // Take the extra included .d.ts files from `tsconfig.monaco.json` options.typings = (tsConfig.include).filter(includedFile => /\.d\.ts$/.test(includedFile)); // Add extra .d.ts files from `node_modules/@types/` if (Array.isArray(options.compilerOptions?.types)) { options.compilerOptions.types.forEach((type: string) => { if (type === '@webgpu/types') { options.typings.push(`../node_modules/${type}/dist/index.d.ts`); } else { options.typings.push(`../node_modules/@types/${type}/index.d.ts`); } }); } const result = tss.shake(options); for (const fileName in result) { if (result.hasOwnProperty(fileName)) { writeFile(path.join(options.destRoot, fileName), result[fileName]); } } const copied: { [fileName: string]: boolean } = {}; const copyFile = (fileName: string) => { if (copied[fileName]) { return; } copied[fileName] = true; const srcPath = path.join(options.sourcesRoot, fileName); const dstPath = path.join(options.destRoot, fileName); writeFile(dstPath, fs.readFileSync(srcPath)); }; const writeOutputFile = (fileName: string, contents: string | Buffer) => { writeFile(path.join(options.destRoot, fileName), contents); }; for (const fileName in result) { if (result.hasOwnProperty(fileName)) { const fileContents = result[fileName]; const info = ts.preProcessFile(fileContents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { const importedFileName = info.importedFiles[i].fileName; let importedFilePath = importedFileName; if (/(^\.\/)|(^\.\.\/)/.test(importedFilePath)) { importedFilePath = path.join(path.dirname(fileName), importedFilePath); } if (/\.css$/.test(importedFilePath)) { transportCSS(importedFilePath, copyFile, writeOutputFile); } else { const pathToCopy = path.join(options.sourcesRoot, importedFilePath); if (fs.existsSync(pathToCopy) && !fs.statSync(pathToCopy).isDirectory()) { copyFile(importedFilePath); } } } } } delete tsConfig.compilerOptions.moduleResolution; writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ 'vs/loader.js' ].forEach(copyFile); } function transportCSS(module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { if (!/\.css/.test(module)) { return false; } const filename = path.join(SRC_DIR, module); const fileContents = fs.readFileSync(filename).toString(); const inlineResources = 'base64'; // see https://github.com/microsoft/monaco-editor/issues/148 const newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64'); write(module, newContents); return true; function _rewriteOrInlineUrls(contents: string, forceBase64: boolean): string { return _replaceURL(contents, (url) => { const fontMatch = url.match(/^(.*).ttf\?(.*)$/); if (fontMatch) { const relativeFontPath = `${fontMatch[1]}.ttf`; // trim the query parameter const fontPath = path.join(path.dirname(module), relativeFontPath); enqueue(fontPath); return relativeFontPath; } const imagePath = path.join(path.dirname(module), url); const fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath)); const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; let DATA = ';base64,' + fileContents.toString('base64'); if (!forceBase64 && /\.svg$/.test(url)) { // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris const newText = fileContents.toString() .replace(/"/g, '\'') .replace(//g, '%3E') .replace(/&/g, '%26') .replace(/#/g, '%23') .replace(/\s+/g, ' '); const encodedData = ',' + newText; if (encodedData.length < DATA.length) { DATA = encodedData; } } return '"data:' + MIME + DATA + '"'; }); } function _replaceURL(contents: string, replacer: (url: string) => string): string { // Use ")" as the terminator as quotes are oftentimes not used at all return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_: string, ...matches: string[]) => { let url = matches[0]; // Eliminate starting quotes (the initial whitespace is not captured) if (url.charAt(0) === '"' || url.charAt(0) === '\'') { url = url.substring(1); } // The ending whitespace is captured while (url.length > 0 && (url.charAt(url.length - 1) === ' ' || url.charAt(url.length - 1) === '\t')) { url = url.substring(0, url.length - 1); } // Eliminate ending quotes if (url.charAt(url.length - 1) === '"' || url.charAt(url.length - 1) === '\'') { url = url.substring(0, url.length - 1); } if (!_startsWith(url, 'data:') && !_startsWith(url, 'http://') && !_startsWith(url, 'https://')) { url = replacer(url); } return 'url(' + url + ')'; }); } function _startsWith(haystack: string, needle: string): boolean { return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; } } ================================================ FILE: build/lib/stats.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createStatsStream = createStatsStream; const event_stream_1 = __importDefault(require("event-stream")); const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); class Entry { name; totalCount; totalSize; constructor(name, totalCount, totalSize) { this.name = name; this.totalCount = totalCount; this.totalSize = totalSize; } toString(pretty) { if (!pretty) { if (this.totalCount === 1) { return `${this.name}: ${this.totalSize} bytes`; } else { return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`; } } else { if (this.totalCount === 1) { return `Stats for '${ansi_colors_1.default.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`; } else { const count = this.totalCount < 100 ? ansi_colors_1.default.green(this.totalCount.toString()) : ansi_colors_1.default.red(this.totalCount.toString()); return `Stats for '${ansi_colors_1.default.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`; } } } } const _entries = new Map(); function createStatsStream(group, log) { const entry = new Entry(group, 0, 0); _entries.set(entry.name, entry); return event_stream_1.default.through(function (data) { const file = data; if (typeof file.path === 'string') { entry.totalCount += 1; if (Buffer.isBuffer(file.contents)) { entry.totalSize += file.contents.length; } else if (file.stat && typeof file.stat.size === 'number') { entry.totalSize += file.stat.size; } else { // funky file... } } this.emit('data', data); }, function () { if (log) { if (entry.totalCount === 1) { (0, fancy_log_1.default)(`Stats for '${ansi_colors_1.default.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`); } else { const count = entry.totalCount < 100 ? ansi_colors_1.default.green(entry.totalCount.toString()) : ansi_colors_1.default.red(entry.totalCount.toString()); (0, fancy_log_1.default)(`Stats for '${ansi_colors_1.default.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`); } } this.emit('end'); }); } //# sourceMappingURL=stats.js.map ================================================ FILE: build/lib/stats.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; import File from 'vinyl'; class Entry { constructor(readonly name: string, public totalCount: number, public totalSize: number) { } toString(pretty?: boolean): string { if (!pretty) { if (this.totalCount === 1) { return `${this.name}: ${this.totalSize} bytes`; } else { return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`; } } else { if (this.totalCount === 1) { return `Stats for '${ansiColors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`; } else { const count = this.totalCount < 100 ? ansiColors.green(this.totalCount.toString()) : ansiColors.red(this.totalCount.toString()); return `Stats for '${ansiColors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`; } } } } const _entries = new Map(); export function createStatsStream(group: string, log?: boolean): es.ThroughStream { const entry = new Entry(group, 0, 0); _entries.set(entry.name, entry); return es.through(function (data) { const file = data as File; if (typeof file.path === 'string') { entry.totalCount += 1; if (Buffer.isBuffer(file.contents)) { entry.totalSize += file.contents.length; } else if (file.stat && typeof file.stat.size === 'number') { entry.totalSize += file.stat.size; } else { // funky file... } } this.emit('data', data); }, function () { if (log) { if (entry.totalCount === 1) { fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`); } else { const count = entry.totalCount < 100 ? ansiColors.green(entry.totalCount.toString()) : ansiColors.red(entry.totalCount.toString()); fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`); } } this.emit('end'); }); } ================================================ FILE: build/lib/stylelint/validateVariableNames.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVariableNameValidator = getVariableNameValidator; const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const RE_VAR_PROP = /var\(\s*(--([\w\-\.]+))/g; let knownVariables; function getKnownVariableNames() { if (!knownVariables) { const knownVariablesFileContent = (0, fs_1.readFileSync)(path_1.default.join(__dirname, './vscode-known-variables.json'), 'utf8').toString(); const knownVariablesInfo = JSON.parse(knownVariablesFileContent); knownVariables = new Set([...knownVariablesInfo.colors, ...knownVariablesInfo.others]); } return knownVariables; } const iconVariable = /^--vscode-icon-.+-(content|font-family)$/; function getVariableNameValidator() { const allVariables = getKnownVariableNames(); return (value, report) => { RE_VAR_PROP.lastIndex = 0; // reset lastIndex just to be sure let match; while (match = RE_VAR_PROP.exec(value)) { const variableName = match[1]; if (variableName && !allVariables.has(variableName) && !iconVariable.test(variableName)) { report(variableName); } } }; } //# sourceMappingURL=validateVariableNames.js.map ================================================ FILE: build/lib/stylelint/validateVariableNames.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { readFileSync } from 'fs'; import path from 'path'; const RE_VAR_PROP = /var\(\s*(--([\w\-\.]+))/g; let knownVariables: Set | undefined; function getKnownVariableNames() { if (!knownVariables) { const knownVariablesFileContent = readFileSync(path.join(__dirname, './vscode-known-variables.json'), 'utf8').toString(); const knownVariablesInfo = JSON.parse(knownVariablesFileContent); knownVariables = new Set([...knownVariablesInfo.colors, ...knownVariablesInfo.others] as string[]); } return knownVariables; } const iconVariable = /^--vscode-icon-.+-(content|font-family)$/; export interface IValidator { (value: string, report: (message: string) => void): void; } export function getVariableNameValidator(): IValidator { const allVariables = getKnownVariableNames(); return (value: string, report: (unknwnVariable: string) => void) => { RE_VAR_PROP.lastIndex = 0; // reset lastIndex just to be sure let match; while (match = RE_VAR_PROP.exec(value)) { const variableName = match[1]; if (variableName && !allVariables.has(variableName) && !iconVariable.test(variableName)) { report(variableName); } } }; } ================================================ FILE: build/lib/stylelint/vscode-known-variables.json ================================================ { "colors": [ "--vscode-actionBar-toggledBackground", "--vscode-activityBar-activeBackground", "--vscode-activityBar-activeBorder", "--vscode-activityBar-activeFocusBorder", "--vscode-activityBar-background", "--vscode-activityBar-border", "--vscode-activityBar-dropBorder", "--vscode-activityBar-foreground", "--vscode-activityBar-inactiveForeground", "--vscode-activityBarBadge-background", "--vscode-activityBarBadge-foreground", "--vscode-activityBarTop-activeBackground", "--vscode-activityBarTop-activeBorder", "--vscode-activityBarTop-background", "--vscode-activityBarTop-dropBorder", "--vscode-activityBarTop-foreground", "--vscode-activityBarTop-inactiveForeground", "--vscode-activityErrorBadge-background", "--vscode-activityErrorBadge-foreground", "--vscode-activityWarningBadge-background", "--vscode-activityWarningBadge-foreground", "--vscode-badge-background", "--vscode-badge-foreground", "--vscode-banner-background", "--vscode-banner-foreground", "--vscode-banner-iconForeground", "--vscode-breadcrumb-activeSelectionForeground", "--vscode-breadcrumb-background", "--vscode-breadcrumb-focusForeground", "--vscode-breadcrumb-foreground", "--vscode-breadcrumbPicker-background", "--vscode-button-background", "--vscode-button-border", "--vscode-button-foreground", "--vscode-button-hoverBackground", "--vscode-button-secondaryBackground", "--vscode-button-secondaryForeground", "--vscode-button-secondaryHoverBackground", "--vscode-button-separator", "--vscode-chart-axis", "--vscode-chart-guide", "--vscode-chart-line", "--vscode-charts-blue", "--vscode-charts-foreground", "--vscode-charts-green", "--vscode-charts-lines", "--vscode-charts-orange", "--vscode-charts-purple", "--vscode-charts-red", "--vscode-charts-yellow", "--vscode-chat-avatarBackground", "--vscode-chat-avatarForeground", "--vscode-chat-editedFileForeground", "--vscode-chat-requestBackground", "--vscode-chat-requestBorder", "--vscode-chat-slashCommandBackground", "--vscode-chat-slashCommandForeground", "--vscode-checkbox-background", "--vscode-checkbox-border", "--vscode-checkbox-foreground", "--vscode-checkbox-selectBackground", "--vscode-checkbox-selectBorder", "--vscode-commandCenter-activeBackground", "--vscode-commandCenter-activeBorder", "--vscode-commandCenter-activeForeground", "--vscode-commandCenter-background", "--vscode-commandCenter-border", "--vscode-commandCenter-debuggingBackground", "--vscode-commandCenter-foreground", "--vscode-commandCenter-inactiveBorder", "--vscode-commandCenter-inactiveForeground", "--vscode-commentsView-resolvedIcon", "--vscode-commentsView-unresolvedIcon", "--vscode-contrastActiveBorder", "--vscode-contrastBorder", "--vscode-debugConsole-errorForeground", "--vscode-debugConsole-infoForeground", "--vscode-debugConsole-sourceForeground", "--vscode-debugConsole-warningForeground", "--vscode-debugConsoleInputIcon-foreground", "--vscode-debugExceptionWidget-background", "--vscode-debugExceptionWidget-border", "--vscode-debugIcon-breakpointCurrentStackframeForeground", "--vscode-debugIcon-breakpointDisabledForeground", "--vscode-debugIcon-breakpointForeground", "--vscode-debugIcon-breakpointStackframeForeground", "--vscode-debugIcon-breakpointUnverifiedForeground", "--vscode-debugIcon-continueForeground", "--vscode-debugIcon-disconnectForeground", "--vscode-debugIcon-pauseForeground", "--vscode-debugIcon-restartForeground", "--vscode-debugIcon-startForeground", "--vscode-debugIcon-stepBackForeground", "--vscode-debugIcon-stepIntoForeground", "--vscode-debugIcon-stepOutForeground", "--vscode-debugIcon-stepOverForeground", "--vscode-debugIcon-stopForeground", "--vscode-debugTokenExpression-boolean", "--vscode-debugTokenExpression-error", "--vscode-debugTokenExpression-name", "--vscode-debugTokenExpression-number", "--vscode-debugTokenExpression-string", "--vscode-debugTokenExpression-type", "--vscode-debugTokenExpression-value", "--vscode-debugToolBar-background", "--vscode-debugToolBar-border", "--vscode-debugView-exceptionLabelBackground", "--vscode-debugView-exceptionLabelForeground", "--vscode-debugView-stateLabelBackground", "--vscode-debugView-stateLabelForeground", "--vscode-debugView-valueChangedHighlight", "--vscode-descriptionForeground", "--vscode-diffEditor-border", "--vscode-diffEditor-diagonalFill", "--vscode-diffEditor-insertedLineBackground", "--vscode-diffEditor-insertedTextBackground", "--vscode-diffEditor-insertedTextBorder", "--vscode-diffEditor-move-border", "--vscode-diffEditor-moveActive-border", "--vscode-diffEditor-removedLineBackground", "--vscode-diffEditor-removedTextBackground", "--vscode-diffEditor-removedTextBorder", "--vscode-diffEditor-unchangedCodeBackground", "--vscode-diffEditor-unchangedRegionBackground", "--vscode-diffEditor-unchangedRegionForeground", "--vscode-diffEditor-unchangedRegionShadow", "--vscode-diffEditorGutter-insertedLineBackground", "--vscode-diffEditorGutter-removedLineBackground", "--vscode-diffEditorOverview-insertedForeground", "--vscode-diffEditorOverview-removedForeground", "--vscode-disabledForeground", "--vscode-dropdown-background", "--vscode-dropdown-border", "--vscode-dropdown-foreground", "--vscode-dropdown-listBackground", "--vscode-editor-background", "--vscode-editor-compositionBorder", "--vscode-editor-findMatchBackground", "--vscode-editor-findMatchBorder", "--vscode-editor-findMatchForeground", "--vscode-editor-findMatchHighlightBackground", "--vscode-editor-findMatchHighlightBorder", "--vscode-editor-findMatchHighlightForeground", "--vscode-editor-findRangeHighlightBackground", "--vscode-editor-findRangeHighlightBorder", "--vscode-editor-focusedStackFrameHighlightBackground", "--vscode-editor-foldBackground", "--vscode-editor-foldPlaceholderForeground", "--vscode-editor-foreground", "--vscode-editor-hoverHighlightBackground", "--vscode-editor-inactiveSelectionBackground", "--vscode-editor-inlineValuesBackground", "--vscode-editor-inlineValuesForeground", "--vscode-editor-lineHighlightBackground", "--vscode-editor-lineHighlightBorder", "--vscode-editor-linkedEditingBackground", "--vscode-editor-placeholder-foreground", "--vscode-editor-rangeHighlightBackground", "--vscode-editor-rangeHighlightBorder", "--vscode-editor-selectionBackground", "--vscode-editor-selectionForeground", "--vscode-editor-selectionHighlightBackground", "--vscode-editor-selectionHighlightBorder", "--vscode-editor-snippetFinalTabstopHighlightBackground", "--vscode-editor-snippetFinalTabstopHighlightBorder", "--vscode-editor-snippetTabstopHighlightBackground", "--vscode-editor-snippetTabstopHighlightBorder", "--vscode-editor-stackFrameHighlightBackground", "--vscode-editor-symbolHighlightBackground", "--vscode-editor-symbolHighlightBorder", "--vscode-editor-wordHighlightBackground", "--vscode-editor-wordHighlightBorder", "--vscode-editor-wordHighlightStrongBackground", "--vscode-editor-wordHighlightStrongBorder", "--vscode-editor-wordHighlightTextBackground", "--vscode-editor-wordHighlightTextBorder", "--vscode-editorActionList-background", "--vscode-editorActionList-focusBackground", "--vscode-editorActionList-focusForeground", "--vscode-editorActionList-foreground", "--vscode-editorActiveLineNumber-foreground", "--vscode-editorBracketHighlight-foreground1", "--vscode-editorBracketHighlight-foreground2", "--vscode-editorBracketHighlight-foreground3", "--vscode-editorBracketHighlight-foreground4", "--vscode-editorBracketHighlight-foreground5", "--vscode-editorBracketHighlight-foreground6", "--vscode-editorBracketHighlight-unexpectedBracket-foreground", "--vscode-editorBracketMatch-background", "--vscode-editorBracketMatch-border", "--vscode-editorBracketPairGuide-activeBackground1", "--vscode-editorBracketPairGuide-activeBackground2", "--vscode-editorBracketPairGuide-activeBackground3", "--vscode-editorBracketPairGuide-activeBackground4", "--vscode-editorBracketPairGuide-activeBackground5", "--vscode-editorBracketPairGuide-activeBackground6", "--vscode-editorBracketPairGuide-background1", "--vscode-editorBracketPairGuide-background2", "--vscode-editorBracketPairGuide-background3", "--vscode-editorBracketPairGuide-background4", "--vscode-editorBracketPairGuide-background5", "--vscode-editorBracketPairGuide-background6", "--vscode-editorCodeLens-foreground", "--vscode-editorCommentsWidget-rangeActiveBackground", "--vscode-editorCommentsWidget-rangeBackground", "--vscode-editorCommentsWidget-replyInputBackground", "--vscode-editorCommentsWidget-resolvedBorder", "--vscode-editorCommentsWidget-unresolvedBorder", "--vscode-editorCursor-background", "--vscode-editorCursor-foreground", "--vscode-editorError-background", "--vscode-editorError-border", "--vscode-editorError-foreground", "--vscode-editorGhostText-background", "--vscode-editorGhostText-border", "--vscode-editorGhostText-foreground", "--vscode-editorGroup-border", "--vscode-editorGroup-dropBackground", "--vscode-editorGroup-dropIntoPromptBackground", "--vscode-editorGroup-dropIntoPromptBorder", "--vscode-editorGroup-dropIntoPromptForeground", "--vscode-editorGroup-emptyBackground", "--vscode-editorGroup-focusedEmptyBorder", "--vscode-editorGroupHeader-border", "--vscode-editorGroupHeader-noTabsBackground", "--vscode-editorGroupHeader-tabsBackground", "--vscode-editorGroupHeader-tabsBorder", "--vscode-editorGutter-addedBackground", "--vscode-editorGutter-background", "--vscode-editorGutter-commentGlyphForeground", "--vscode-editorGutter-commentRangeForeground", "--vscode-editorGutter-commentUnresolvedGlyphForeground", "--vscode-editorGutter-deletedBackground", "--vscode-editorGutter-foldingControlForeground", "--vscode-editorGutter-itemBackground", "--vscode-editorGutter-itemGlyphForeground", "--vscode-editorGutter-modifiedBackground", "--vscode-editorHint-border", "--vscode-editorHint-foreground", "--vscode-editorHoverWidget-background", "--vscode-editorHoverWidget-border", "--vscode-editorHoverWidget-foreground", "--vscode-editorHoverWidget-highlightForeground", "--vscode-editorHoverWidget-statusBarBackground", "--vscode-editorIndentGuide-activeBackground", "--vscode-editorIndentGuide-activeBackground1", "--vscode-editorIndentGuide-activeBackground2", "--vscode-editorIndentGuide-activeBackground3", "--vscode-editorIndentGuide-activeBackground4", "--vscode-editorIndentGuide-activeBackground5", "--vscode-editorIndentGuide-activeBackground6", "--vscode-editorIndentGuide-background", "--vscode-editorIndentGuide-background1", "--vscode-editorIndentGuide-background2", "--vscode-editorIndentGuide-background3", "--vscode-editorIndentGuide-background4", "--vscode-editorIndentGuide-background5", "--vscode-editorIndentGuide-background6", "--vscode-editorInfo-background", "--vscode-editorInfo-border", "--vscode-editorInfo-foreground", "--vscode-editorInlayHint-background", "--vscode-editorInlayHint-foreground", "--vscode-editorInlayHint-parameterBackground", "--vscode-editorInlayHint-parameterForeground", "--vscode-editorInlayHint-typeBackground", "--vscode-editorInlayHint-typeForeground", "--vscode-editorLightBulb-foreground", "--vscode-editorLightBulbAi-foreground", "--vscode-editorLightBulbAutoFix-foreground", "--vscode-editorLineNumber-activeForeground", "--vscode-editorLineNumber-dimmedForeground", "--vscode-editorLineNumber-foreground", "--vscode-editorLink-activeForeground", "--vscode-editorMarkerNavigation-background", "--vscode-editorMarkerNavigationError-background", "--vscode-editorMarkerNavigationError-headerBackground", "--vscode-editorMarkerNavigationInfo-background", "--vscode-editorMarkerNavigationInfo-headerBackground", "--vscode-editorMarkerNavigationWarning-background", "--vscode-editorMarkerNavigationWarning-headerBackground", "--vscode-editorMinimap-inlineChatInserted", "--vscode-editorMultiCursor-primary-background", "--vscode-editorMultiCursor-primary-foreground", "--vscode-editorMultiCursor-secondary-background", "--vscode-editorMultiCursor-secondary-foreground", "--vscode-editorOverviewRuler-addedForeground", "--vscode-editorOverviewRuler-background", "--vscode-editorOverviewRuler-border", "--vscode-editorOverviewRuler-bracketMatchForeground", "--vscode-editorOverviewRuler-commentForeground", "--vscode-editorOverviewRuler-commentUnresolvedForeground", "--vscode-editorOverviewRuler-commonContentForeground", "--vscode-editorOverviewRuler-currentContentForeground", "--vscode-editorOverviewRuler-deletedForeground", "--vscode-editorOverviewRuler-errorForeground", "--vscode-editorOverviewRuler-findMatchForeground", "--vscode-editorOverviewRuler-incomingContentForeground", "--vscode-editorOverviewRuler-infoForeground", "--vscode-editorOverviewRuler-inlineChatInserted", "--vscode-editorOverviewRuler-inlineChatRemoved", "--vscode-editorOverviewRuler-modifiedForeground", "--vscode-editorOverviewRuler-rangeHighlightForeground", "--vscode-editorOverviewRuler-selectionHighlightForeground", "--vscode-editorOverviewRuler-warningForeground", "--vscode-editorOverviewRuler-wordHighlightForeground", "--vscode-editorOverviewRuler-wordHighlightStrongForeground", "--vscode-editorOverviewRuler-wordHighlightTextForeground", "--vscode-editorPane-background", "--vscode-editorRuler-foreground", "--vscode-editorStickyScroll-background", "--vscode-editorStickyScroll-border", "--vscode-editorStickyScroll-shadow", "--vscode-editorStickyScrollHover-background", "--vscode-editorSuggestWidget-background", "--vscode-editorSuggestWidget-border", "--vscode-editorSuggestWidget-focusHighlightForeground", "--vscode-editorSuggestWidget-foreground", "--vscode-editorSuggestWidget-highlightForeground", "--vscode-editorSuggestWidget-selectedBackground", "--vscode-editorSuggestWidget-selectedForeground", "--vscode-editorSuggestWidget-selectedIconForeground", "--vscode-editorSuggestWidgetStatus-foreground", "--vscode-editorUnicodeHighlight-background", "--vscode-editorUnicodeHighlight-border", "--vscode-editorUnnecessaryCode-border", "--vscode-editorUnnecessaryCode-opacity", "--vscode-editorWarning-background", "--vscode-editorWarning-border", "--vscode-editorWarning-foreground", "--vscode-editorWatermark-foreground", "--vscode-editorWhitespace-foreground", "--vscode-editorWidget-background", "--vscode-editorWidget-border", "--vscode-editorWidget-foreground", "--vscode-editorWidget-resizeBorder", "--vscode-errorForeground", "--vscode-extensionBadge-remoteBackground", "--vscode-extensionBadge-remoteForeground", "--vscode-extensionButton-background", "--vscode-extensionButton-foreground", "--vscode-extensionButton-hoverBackground", "--vscode-extensionButton-prominentBackground", "--vscode-extensionButton-prominentForeground", "--vscode-extensionButton-prominentHoverBackground", "--vscode-extensionButton-separator", "--vscode-extensionIcon-preReleaseForeground", "--vscode-extensionIcon-privateForeground", "--vscode-extensionIcon-sponsorForeground", "--vscode-extensionIcon-starForeground", "--vscode-extensionIcon-verifiedForeground", "--vscode-focusBorder", "--vscode-foreground", "--vscode-gauge-background", "--vscode-gauge-border", "--vscode-gauge-errorBackground", "--vscode-gauge-errorForeground", "--vscode-gauge-foreground", "--vscode-gauge-warningBackground", "--vscode-gauge-warningForeground", "--vscode-icon-foreground", "--vscode-inlineChat-background", "--vscode-inlineChat-border", "--vscode-inlineChat-foreground", "--vscode-inlineChat-shadow", "--vscode-inlineChatDiff-inserted", "--vscode-inlineChatDiff-removed", "--vscode-inlineChatInput-background", "--vscode-inlineChatInput-border", "--vscode-inlineChatInput-focusBorder", "--vscode-inlineChatInput-placeholderForeground", "--vscode-inlineEdit-gutterIndicator-background", "--vscode-inlineEdit-gutterIndicator-primaryBackground", "--vscode-inlineEdit-gutterIndicator-primaryBorder", "--vscode-inlineEdit-gutterIndicator-primaryForeground", "--vscode-inlineEdit-gutterIndicator-secondaryBackground", "--vscode-inlineEdit-gutterIndicator-secondaryBorder", "--vscode-inlineEdit-gutterIndicator-secondaryForeground", "--vscode-inlineEdit-gutterIndicator-successfulBackground", "--vscode-inlineEdit-gutterIndicator-successfulBorder", "--vscode-inlineEdit-gutterIndicator-successfulForeground", "--vscode-inlineEdit-modifiedBackground", "--vscode-inlineEdit-modifiedBorder", "--vscode-inlineEdit-modifiedChangedLineBackground", "--vscode-inlineEdit-modifiedChangedTextBackground", "--vscode-inlineEdit-originalBackground", "--vscode-inlineEdit-originalBorder", "--vscode-inlineEdit-originalChangedLineBackground", "--vscode-inlineEdit-originalChangedTextBackground", "--vscode-inlineEdit-tabWillAcceptModifiedBorder", "--vscode-inlineEdit-tabWillAcceptOriginalBorder", "--vscode-input-background", "--vscode-input-border", "--vscode-input-foreground", "--vscode-input-placeholderForeground", "--vscode-inputOption-activeBackground", "--vscode-inputOption-activeBorder", "--vscode-inputOption-activeForeground", "--vscode-inputOption-hoverBackground", "--vscode-inputValidation-errorBackground", "--vscode-inputValidation-errorBorder", "--vscode-inputValidation-errorForeground", "--vscode-inputValidation-infoBackground", "--vscode-inputValidation-infoBorder", "--vscode-inputValidation-infoForeground", "--vscode-inputValidation-warningBackground", "--vscode-inputValidation-warningBorder", "--vscode-inputValidation-warningForeground", "--vscode-interactive-activeCodeBorder", "--vscode-interactive-inactiveCodeBorder", "--vscode-keybindingLabel-background", "--vscode-keybindingLabel-border", "--vscode-keybindingLabel-bottomBorder", "--vscode-keybindingLabel-foreground", "--vscode-keybindingTable-headerBackground", "--vscode-keybindingTable-rowsBackground", "--vscode-list-activeSelectionBackground", "--vscode-list-activeSelectionForeground", "--vscode-list-activeSelectionIconForeground", "--vscode-list-deemphasizedForeground", "--vscode-list-dropBackground", "--vscode-list-dropBetweenBackground", "--vscode-list-errorForeground", "--vscode-list-filterMatchBackground", "--vscode-list-filterMatchBorder", "--vscode-list-focusAndSelectionOutline", "--vscode-list-focusBackground", "--vscode-list-focusForeground", "--vscode-list-focusHighlightForeground", "--vscode-list-focusOutline", "--vscode-list-highlightForeground", "--vscode-list-hoverBackground", "--vscode-list-hoverForeground", "--vscode-list-inactiveFocusBackground", "--vscode-list-inactiveFocusOutline", "--vscode-list-inactiveSelectionBackground", "--vscode-list-inactiveSelectionForeground", "--vscode-list-inactiveSelectionIconForeground", "--vscode-list-invalidItemForeground", "--vscode-list-warningForeground", "--vscode-listFilterWidget-background", "--vscode-listFilterWidget-noMatchesOutline", "--vscode-listFilterWidget-outline", "--vscode-listFilterWidget-shadow", "--vscode-menu-background", "--vscode-menu-border", "--vscode-menu-foreground", "--vscode-menu-selectionBackground", "--vscode-menu-selectionBorder", "--vscode-menu-selectionForeground", "--vscode-menu-separatorBackground", "--vscode-menubar-selectionBackground", "--vscode-menubar-selectionBorder", "--vscode-menubar-selectionForeground", "--vscode-merge-border", "--vscode-merge-commonContentBackground", "--vscode-merge-commonHeaderBackground", "--vscode-merge-currentContentBackground", "--vscode-merge-currentHeaderBackground", "--vscode-merge-incomingContentBackground", "--vscode-merge-incomingHeaderBackground", "--vscode-mergeEditor-change-background", "--vscode-mergeEditor-change-word-background", "--vscode-mergeEditor-changeBase-background", "--vscode-mergeEditor-changeBase-word-background", "--vscode-mergeEditor-conflict-handled-minimapOverViewRuler", "--vscode-mergeEditor-conflict-handledFocused-border", "--vscode-mergeEditor-conflict-handledUnfocused-border", "--vscode-mergeEditor-conflict-input1-background", "--vscode-mergeEditor-conflict-input2-background", "--vscode-mergeEditor-conflict-unhandled-minimapOverViewRuler", "--vscode-mergeEditor-conflict-unhandledFocused-border", "--vscode-mergeEditor-conflict-unhandledUnfocused-border", "--vscode-mergeEditor-conflictingLines-background", "--vscode-minimap-background", "--vscode-minimap-chatEditHighlight", "--vscode-minimap-errorHighlight", "--vscode-minimap-findMatchHighlight", "--vscode-minimap-foregroundOpacity", "--vscode-minimap-infoHighlight", "--vscode-minimap-selectionHighlight", "--vscode-minimap-selectionOccurrenceHighlight", "--vscode-minimap-warningHighlight", "--vscode-minimapGutter-addedBackground", "--vscode-minimapGutter-deletedBackground", "--vscode-minimapGutter-modifiedBackground", "--vscode-minimapSlider-activeBackground", "--vscode-minimapSlider-background", "--vscode-minimapSlider-hoverBackground", "--vscode-multiDiffEditor-background", "--vscode-multiDiffEditor-border", "--vscode-multiDiffEditor-headerBackground", "--vscode-notebook-cellBorderColor", "--vscode-notebook-cellEditorBackground", "--vscode-notebook-cellHoverBackground", "--vscode-notebook-cellInsertionIndicator", "--vscode-notebook-cellStatusBarItemHoverBackground", "--vscode-notebook-cellToolbarSeparator", "--vscode-notebook-editorBackground", "--vscode-notebook-focusedCellBackground", "--vscode-notebook-focusedCellBorder", "--vscode-notebook-focusedEditorBorder", "--vscode-notebook-inactiveFocusedCellBorder", "--vscode-notebook-inactiveSelectedCellBorder", "--vscode-notebook-outputContainerBackgroundColor", "--vscode-notebook-outputContainerBorderColor", "--vscode-notebook-selectedCellBackground", "--vscode-notebook-selectedCellBorder", "--vscode-notebook-symbolHighlightBackground", "--vscode-notebookEditorOverviewRuler-runningCellForeground", "--vscode-notebookScrollbarSlider-activeBackground", "--vscode-notebookScrollbarSlider-background", "--vscode-notebookScrollbarSlider-hoverBackground", "--vscode-notebookStatusErrorIcon-foreground", "--vscode-notebookStatusRunningIcon-foreground", "--vscode-notebookStatusSuccessIcon-foreground", "--vscode-notificationCenter-border", "--vscode-notificationCenterHeader-background", "--vscode-notificationCenterHeader-foreground", "--vscode-notificationLink-foreground", "--vscode-notificationToast-border", "--vscode-notifications-background", "--vscode-notifications-border", "--vscode-notifications-foreground", "--vscode-notificationsErrorIcon-foreground", "--vscode-notificationsInfoIcon-foreground", "--vscode-notificationsWarningIcon-foreground", "--vscode-outputView-background", "--vscode-outputViewStickyScroll-background", "--vscode-panel-background", "--vscode-panel-border", "--vscode-panel-dropBorder", "--vscode-panelInput-border", "--vscode-panelSection-border", "--vscode-panelSection-dropBackground", "--vscode-panelSectionHeader-background", "--vscode-panelSectionHeader-border", "--vscode-panelSectionHeader-foreground", "--vscode-panelStickyScroll-background", "--vscode-panelStickyScroll-border", "--vscode-panelStickyScroll-shadow", "--vscode-panelTitle-activeBorder", "--vscode-panelTitle-activeForeground", "--vscode-panelTitle-border", "--vscode-panelTitle-inactiveForeground", "--vscode-panelTitleBadge-background", "--vscode-panelTitleBadge-foreground", "--vscode-peekView-border", "--vscode-peekViewEditor-background", "--vscode-peekViewEditor-matchHighlightBackground", "--vscode-peekViewEditor-matchHighlightBorder", "--vscode-peekViewEditorGutter-background", "--vscode-peekViewEditorStickyScroll-background", "--vscode-peekViewResult-background", "--vscode-peekViewResult-fileForeground", "--vscode-peekViewResult-lineForeground", "--vscode-peekViewResult-matchHighlightBackground", "--vscode-peekViewResult-selectionBackground", "--vscode-peekViewResult-selectionForeground", "--vscode-peekViewTitle-background", "--vscode-peekViewTitleDescription-foreground", "--vscode-peekViewTitleLabel-foreground", "--vscode-pickerGroup-border", "--vscode-pickerGroup-foreground", "--vscode-ports-iconRunningProcessForeground", "--vscode-problemsErrorIcon-foreground", "--vscode-problemsInfoIcon-foreground", "--vscode-problemsWarningIcon-foreground", "--vscode-profileBadge-background", "--vscode-profileBadge-foreground", "--vscode-profiles-sashBorder", "--vscode-progressBar-background", "--vscode-quickInput-background", "--vscode-quickInput-foreground", "--vscode-quickInput-list-focusBackground", "--vscode-quickInputList-focusBackground", "--vscode-quickInputList-focusForeground", "--vscode-quickInputList-focusIconForeground", "--vscode-quickInputTitle-background", "--vscode-radio-activeBackground", "--vscode-radio-activeBorder", "--vscode-radio-activeForeground", "--vscode-radio-inactiveBackground", "--vscode-radio-inactiveBorder", "--vscode-radio-inactiveForeground", "--vscode-radio-inactiveHoverBackground", "--vscode-sash-hoverBorder", "--vscode-scmGraph-foreground1", "--vscode-scmGraph-foreground2", "--vscode-scmGraph-foreground3", "--vscode-scmGraph-foreground4", "--vscode-scmGraph-foreground5", "--vscode-scmGraph-historyItemBaseRefColor", "--vscode-scmGraph-historyItemHoverAdditionsForeground", "--vscode-scmGraph-historyItemHoverDefaultLabelBackground", "--vscode-scmGraph-historyItemHoverDefaultLabelForeground", "--vscode-scmGraph-historyItemHoverDeletionsForeground", "--vscode-scmGraph-historyItemHoverLabelForeground", "--vscode-scmGraph-historyItemRefColor", "--vscode-scmGraph-historyItemRemoteRefColor", "--vscode-scrollbar-shadow", "--vscode-scrollbarSlider-activeBackground", "--vscode-scrollbarSlider-background", "--vscode-scrollbarSlider-hoverBackground", "--vscode-search-resultsInfoForeground", "--vscode-searchEditor-findMatchBackground", "--vscode-searchEditor-findMatchBorder", "--vscode-searchEditor-textInputBorder", "--vscode-selection-background", "--vscode-settings-checkboxBackground", "--vscode-settings-checkboxBorder", "--vscode-settings-checkboxForeground", "--vscode-settings-dropdownBackground", "--vscode-settings-dropdownBorder", "--vscode-settings-dropdownForeground", "--vscode-settings-dropdownListBorder", "--vscode-settings-focusedRowBackground", "--vscode-settings-focusedRowBorder", "--vscode-settings-headerBorder", "--vscode-settings-headerForeground", "--vscode-settings-modifiedItemIndicator", "--vscode-settings-numberInputBackground", "--vscode-settings-numberInputBorder", "--vscode-settings-numberInputForeground", "--vscode-settings-rowHoverBackground", "--vscode-settings-sashBorder", "--vscode-settings-settingsHeaderHoverForeground", "--vscode-settings-textInputBackground", "--vscode-settings-textInputBorder", "--vscode-settings-textInputForeground", "--vscode-sideBar-background", "--vscode-sideBar-border", "--vscode-sideBar-dropBackground", "--vscode-sideBar-foreground", "--vscode-sideBarActivityBarTop-border", "--vscode-sideBarSectionHeader-background", "--vscode-sideBarSectionHeader-border", "--vscode-sideBarSectionHeader-foreground", "--vscode-sideBarStickyScroll-background", "--vscode-sideBarStickyScroll-border", "--vscode-sideBarStickyScroll-shadow", "--vscode-sideBarTitle-background", "--vscode-sideBarTitle-border", "--vscode-sideBarTitle-foreground", "--vscode-sideBySideEditor-horizontalBorder", "--vscode-sideBySideEditor-verticalBorder", "--vscode-simpleFindWidget-sashBorder", "--vscode-statusBar-background", "--vscode-statusBar-border", "--vscode-statusBar-debuggingBackground", "--vscode-statusBar-debuggingBorder", "--vscode-statusBar-debuggingForeground", "--vscode-statusBar-focusBorder", "--vscode-statusBar-foreground", "--vscode-statusBar-noFolderBackground", "--vscode-statusBar-noFolderBorder", "--vscode-statusBar-noFolderForeground", "--vscode-statusBarItem-activeBackground", "--vscode-statusBarItem-compactHoverBackground", "--vscode-statusBarItem-errorBackground", "--vscode-statusBarItem-errorForeground", "--vscode-statusBarItem-errorHoverBackground", "--vscode-statusBarItem-errorHoverForeground", "--vscode-statusBarItem-focusBorder", "--vscode-statusBarItem-hoverBackground", "--vscode-statusBarItem-hoverForeground", "--vscode-statusBarItem-offlineBackground", "--vscode-statusBarItem-offlineForeground", "--vscode-statusBarItem-offlineHoverBackground", "--vscode-statusBarItem-offlineHoverForeground", "--vscode-statusBarItem-prominentBackground", "--vscode-statusBarItem-prominentForeground", "--vscode-statusBarItem-prominentHoverBackground", "--vscode-statusBarItem-prominentHoverForeground", "--vscode-statusBarItem-remoteBackground", "--vscode-statusBarItem-remoteForeground", "--vscode-statusBarItem-remoteHoverBackground", "--vscode-statusBarItem-remoteHoverForeground", "--vscode-statusBarItem-warningBackground", "--vscode-statusBarItem-warningForeground", "--vscode-statusBarItem-warningHoverBackground", "--vscode-statusBarItem-warningHoverForeground", "--vscode-symbolIcon-arrayForeground", "--vscode-symbolIcon-booleanForeground", "--vscode-symbolIcon-classForeground", "--vscode-symbolIcon-colorForeground", "--vscode-symbolIcon-constantForeground", "--vscode-symbolIcon-constructorForeground", "--vscode-symbolIcon-enumeratorForeground", "--vscode-symbolIcon-enumeratorMemberForeground", "--vscode-symbolIcon-eventForeground", "--vscode-symbolIcon-fieldForeground", "--vscode-symbolIcon-fileForeground", "--vscode-symbolIcon-folderForeground", "--vscode-symbolIcon-functionForeground", "--vscode-symbolIcon-interfaceForeground", "--vscode-symbolIcon-keyForeground", "--vscode-symbolIcon-keywordForeground", "--vscode-symbolIcon-methodForeground", "--vscode-symbolIcon-moduleForeground", "--vscode-symbolIcon-namespaceForeground", "--vscode-symbolIcon-nullForeground", "--vscode-symbolIcon-numberForeground", "--vscode-symbolIcon-objectForeground", "--vscode-symbolIcon-operatorForeground", "--vscode-symbolIcon-packageForeground", "--vscode-symbolIcon-propertyForeground", "--vscode-symbolIcon-referenceForeground", "--vscode-symbolIcon-snippetForeground", "--vscode-symbolIcon-stringForeground", "--vscode-symbolIcon-structForeground", "--vscode-symbolIcon-textForeground", "--vscode-symbolIcon-typeParameterForeground", "--vscode-symbolIcon-unitForeground", "--vscode-symbolIcon-variableForeground", "--vscode-tab-activeBackground", "--vscode-tab-activeBorder", "--vscode-tab-activeBorderTop", "--vscode-tab-activeForeground", "--vscode-tab-activeModifiedBorder", "--vscode-tab-border", "--vscode-tab-dragAndDropBorder", "--vscode-tab-hoverBackground", "--vscode-tab-hoverBorder", "--vscode-tab-hoverForeground", "--vscode-tab-inactiveBackground", "--vscode-tab-inactiveForeground", "--vscode-tab-inactiveModifiedBorder", "--vscode-tab-lastPinnedBorder", "--vscode-tab-selectedBackground", "--vscode-tab-selectedBorderTop", "--vscode-tab-selectedForeground", "--vscode-tab-unfocusedActiveBackground", "--vscode-tab-unfocusedActiveBorder", "--vscode-tab-unfocusedActiveBorderTop", "--vscode-tab-unfocusedActiveForeground", "--vscode-tab-unfocusedActiveModifiedBorder", "--vscode-tab-unfocusedHoverBackground", "--vscode-tab-unfocusedHoverBorder", "--vscode-tab-unfocusedHoverForeground", "--vscode-tab-unfocusedInactiveBackground", "--vscode-tab-unfocusedInactiveForeground", "--vscode-tab-unfocusedInactiveModifiedBorder", "--vscode-terminal-ansiBlack", "--vscode-terminal-ansiBlue", "--vscode-terminal-ansiBrightBlack", "--vscode-terminal-ansiBrightBlue", "--vscode-terminal-ansiBrightCyan", "--vscode-terminal-ansiBrightGreen", "--vscode-terminal-ansiBrightMagenta", "--vscode-terminal-ansiBrightRed", "--vscode-terminal-ansiBrightWhite", "--vscode-terminal-ansiBrightYellow", "--vscode-terminal-ansiCyan", "--vscode-terminal-ansiGreen", "--vscode-terminal-ansiMagenta", "--vscode-terminal-ansiRed", "--vscode-terminal-ansiWhite", "--vscode-terminal-ansiYellow", "--vscode-terminal-background", "--vscode-terminal-border", "--vscode-terminal-dropBackground", "--vscode-terminal-findMatchBackground", "--vscode-terminal-findMatchBorder", "--vscode-terminal-findMatchHighlightBackground", "--vscode-terminal-findMatchHighlightBorder", "--vscode-terminal-foreground", "--vscode-terminal-hoverHighlightBackground", "--vscode-terminal-inactiveSelectionBackground", "--vscode-terminal-initialHintForeground", "--vscode-terminal-selectionBackground", "--vscode-terminal-selectionForeground", "--vscode-terminal-tab-activeBorder", "--vscode-terminalCommandDecoration-defaultBackground", "--vscode-terminalCommandDecoration-errorBackground", "--vscode-terminalCommandDecoration-successBackground", "--vscode-terminalCommandGuide-foreground", "--vscode-terminalCursor-background", "--vscode-terminalCursor-foreground", "--vscode-terminalOverviewRuler-border", "--vscode-terminalOverviewRuler-cursorForeground", "--vscode-terminalOverviewRuler-findMatchForeground", "--vscode-terminalStickyScroll-background", "--vscode-terminalStickyScroll-border", "--vscode-terminalStickyScrollHover-background", "--vscode-terminalSymbolIcon-aliasForeground", "--vscode-terminalSymbolIcon-argumentForeground", "--vscode-terminalSymbolIcon-fileForeground", "--vscode-terminalSymbolIcon-flagForeground", "--vscode-terminalSymbolIcon-folderForeground", "--vscode-terminalSymbolIcon-inlineSuggestionForeground", "--vscode-terminalSymbolIcon-methodForeground", "--vscode-terminalSymbolIcon-optionForeground", "--vscode-terminalSymbolIcon-optionValueForeground", "--vscode-testing-coverCountBadgeBackground", "--vscode-testing-coverCountBadgeForeground", "--vscode-testing-coveredBackground", "--vscode-testing-coveredBorder", "--vscode-testing-coveredGutterBackground", "--vscode-testing-iconErrored", "--vscode-testing-iconErrored-retired", "--vscode-testing-iconFailed", "--vscode-testing-iconFailed-retired", "--vscode-testing-iconPassed", "--vscode-testing-iconPassed-retired", "--vscode-testing-iconQueued", "--vscode-testing-iconQueued-retired", "--vscode-testing-iconSkipped", "--vscode-testing-iconSkipped-retired", "--vscode-testing-iconUnset", "--vscode-testing-iconUnset-retired", "--vscode-testing-message-error-badgeBackground", "--vscode-testing-message-error-badgeBorder", "--vscode-testing-message-error-badgeForeground", "--vscode-testing-message-error-lineBackground", "--vscode-testing-message-info-decorationForeground", "--vscode-testing-message-info-lineBackground", "--vscode-testing-messagePeekBorder", "--vscode-testing-messagePeekHeaderBackground", "--vscode-testing-peekBorder", "--vscode-testing-peekHeaderBackground", "--vscode-testing-runAction", "--vscode-testing-uncoveredBackground", "--vscode-testing-uncoveredBorder", "--vscode-testing-uncoveredBranchBackground", "--vscode-testing-uncoveredGutterBackground", "--vscode-textBlockQuote-background", "--vscode-textBlockQuote-border", "--vscode-textCodeBlock-background", "--vscode-textLink-activeForeground", "--vscode-textLink-foreground", "--vscode-textPreformat-background", "--vscode-textPreformat-foreground", "--vscode-textSeparator-foreground", "--vscode-titleBar-activeBackground", "--vscode-titleBar-activeForeground", "--vscode-titleBar-border", "--vscode-titleBar-inactiveBackground", "--vscode-titleBar-inactiveForeground", "--vscode-toolbar-activeBackground", "--vscode-toolbar-hoverBackground", "--vscode-toolbar-hoverOutline", "--vscode-tree-inactiveIndentGuidesStroke", "--vscode-tree-indentGuidesStroke", "--vscode-tree-tableColumnsBorder", "--vscode-tree-tableOddRowsBackground", "--vscode-walkThrough-embeddedEditorBackground", "--vscode-walkthrough-stepTitle-foreground", "--vscode-welcomePage-background", "--vscode-welcomePage-progress-background", "--vscode-welcomePage-progress-foreground", "--vscode-welcomePage-tileBackground", "--vscode-welcomePage-tileBorder", "--vscode-welcomePage-tileHoverBackground", "--vscode-widget-border", "--vscode-widget-shadow", "--vscode-window-activeBorder", "--vscode-window-inactiveBorder" ], "others": [ "--background-dark", "--background-light", "--chat-editing-last-edit-shift", "--chat-current-response-min-height", "--dropdown-padding-bottom", "--dropdown-padding-top", "--inline-chat-frame-progress", "--inline-chat-hint-progress", "--insert-border-color", "--last-tab-margin-right", "--monaco-monospace-font", "--monaco-monospace-font", "--notebook-cell-input-preview-font-family", "--notebook-cell-input-preview-font-size", "--notebook-cell-output-font-size", "--notebook-diff-view-viewport-slider", "--notebook-find-horizontal-padding", "--notebook-find-width", "--notebook-editor-font-family", "--notebook-editor-font-size", "--notebook-editor-font-weight", "--outline-element-color", "--separator-border", "--status-border-top-color", "--tab-border-bottom-color", "--tab-border-top-color", "--tab-dirty-border-top-color", "--tabs-border-bottom-color", "--tab-sizing-current-width", "--tab-sizing-fixed-min-width", "--tab-sizing-fixed-max-width", "--editor-group-tab-height", "--editor-group-tabs-height", "--testMessageDecorationFontFamily", "--testMessageDecorationFontSize", "--title-border-bottom-color", "--title-wco-width", "--vscode-chat-list-background", "--vscode-editorCodeLens-fontFamily", "--vscode-editorCodeLens-fontFamilyDefault", "--vscode-editorCodeLens-fontFeatureSettings", "--vscode-editorCodeLens-fontSize", "--vscode-editorCodeLens-lineHeight", "--vscode-explorer-align-offset-margin-left", "--vscode-hover-maxWidth", "--vscode-hover-sourceWhiteSpace", "--vscode-hover-whiteSpace", "--vscode-editor-dictation-widget-height", "--vscode-editor-dictation-widget-width", "--vscode-interactive-session-foreground", "--vscode-interactive-result-editor-background-color", "--vscode-repl-font-family", "--vscode-repl-font-size-for-twistie", "--vscode-repl-font-size", "--vscode-repl-line-height", "--vscode-sash-hover-size", "--vscode-sash-size", "--vscode-testing-coverage-lineHeight", "--vscode-editorStickyScroll-scrollableWidth", "--vscode-editorStickyScroll-foldingOpacityTransition", "--window-border-color", "--vscode-parameterHintsWidget-editorFontFamily", "--vscode-parameterHintsWidget-editorFontFamilyDefault", "--workspace-trust-check-color", "--workspace-trust-selected-color", "--workspace-trust-unselected-color", "--workspace-trust-x-color", "--z-index-notebook-cell-bottom-toolbar-container", "--z-index-notebook-cell-editor-outline", "--z-index-notebook-cell-expand-part-button", "--z-index-notebook-cell-output-toolbar", "--z-index-notebook-cell-status", "--z-index-notebook-cell-toolbar-dropdown-active", "--z-index-notebook-cell-toolbar", "--z-index-notebook-folding-indicator", "--z-index-notebook-input-collapse-condicon", "--z-index-notebook-list-insertion-indicator", "--z-index-notebook-output", "--z-index-notebook-progress-bar", "--z-index-notebook-scrollbar", "--z-index-run-button-container", "--zoom-factor", "--test-bar-width", "--widget-color", "--text-link-decoration", "--vscode-action-item-auto-timeout", "--monaco-editor-warning-decoration", "--animation-opacity" ] } ================================================ FILE: build/lib/task.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.series = series; exports.parallel = parallel; exports.define = define; const fancy_log_1 = __importDefault(require("fancy-log")); const ansi_colors_1 = __importDefault(require("ansi-colors")); function _isPromise(p) { if (typeof p.then === 'function') { return true; } return false; } function _renderTime(time) { return `${Math.round(time)} ms`; } async function _execute(task) { const name = task.taskName || task.displayName || ``; if (!task._tasks) { (0, fancy_log_1.default)('Starting', ansi_colors_1.default.cyan(name), '...'); } const startTime = process.hrtime(); await _doExecute(task); const elapsedArr = process.hrtime(startTime); const elapsedNanoseconds = (elapsedArr[0] * 1e9 + elapsedArr[1]); if (!task._tasks) { (0, fancy_log_1.default)(`Finished`, ansi_colors_1.default.cyan(name), 'after', ansi_colors_1.default.magenta(_renderTime(elapsedNanoseconds / 1e6))); } } async function _doExecute(task) { // Always invoke as if it were a callback task return new Promise((resolve, reject) => { if (task.length === 1) { // this is a callback task task((err) => { if (err) { return reject(err); } resolve(); }); return; } const taskResult = task(); if (typeof taskResult === 'undefined') { // this is a sync task resolve(); return; } if (_isPromise(taskResult)) { // this is a promise returning task taskResult.then(resolve, reject); return; } // this is a stream returning task taskResult.on('end', _ => resolve()); taskResult.on('error', err => reject(err)); }); } function series(...tasks) { const result = async () => { for (let i = 0; i < tasks.length; i++) { await _execute(tasks[i]); } }; result._tasks = tasks; return result; } function parallel(...tasks) { const result = async () => { await Promise.all(tasks.map(t => _execute(t))); }; result._tasks = tasks; return result; } function define(name, task) { if (task._tasks) { // This is a composite task const lastTask = task._tasks[task._tasks.length - 1]; if (lastTask._tasks || lastTask.taskName) { // This is a composite task without a real task function // => generate a fake task function return define(name, series(task, () => Promise.resolve())); } lastTask.taskName = name; task.displayName = name; return task; } // This is a simple task task.taskName = name; task.displayName = name; return task; } //# sourceMappingURL=task.js.map ================================================ FILE: build/lib/task.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fancyLog from 'fancy-log'; import ansiColors from 'ansi-colors'; export interface BaseTask { displayName?: string; taskName?: string; _tasks?: Task[]; } export interface PromiseTask extends BaseTask { (): Promise; } export interface StreamTask extends BaseTask { (): NodeJS.ReadWriteStream; } export interface CallbackTask extends BaseTask { (cb?: (err?: any) => void): void; } export type Task = PromiseTask | StreamTask | CallbackTask; function _isPromise(p: Promise | NodeJS.ReadWriteStream): p is Promise { if (typeof (p).then === 'function') { return true; } return false; } function _renderTime(time: number): string { return `${Math.round(time)} ms`; } async function _execute(task: Task): Promise { const name = task.taskName || task.displayName || ``; if (!task._tasks) { fancyLog('Starting', ansiColors.cyan(name), '...'); } const startTime = process.hrtime(); await _doExecute(task); const elapsedArr = process.hrtime(startTime); const elapsedNanoseconds = (elapsedArr[0] * 1e9 + elapsedArr[1]); if (!task._tasks) { fancyLog(`Finished`, ansiColors.cyan(name), 'after', ansiColors.magenta(_renderTime(elapsedNanoseconds / 1e6))); } } async function _doExecute(task: Task): Promise { // Always invoke as if it were a callback task return new Promise((resolve, reject) => { if (task.length === 1) { // this is a callback task task((err) => { if (err) { return reject(err); } resolve(); }); return; } const taskResult = task(); if (typeof taskResult === 'undefined') { // this is a sync task resolve(); return; } if (_isPromise(taskResult)) { // this is a promise returning task taskResult.then(resolve, reject); return; } // this is a stream returning task taskResult.on('end', _ => resolve()); taskResult.on('error', err => reject(err)); }); } export function series(...tasks: Task[]): PromiseTask { const result = async () => { for (let i = 0; i < tasks.length; i++) { await _execute(tasks[i]); } }; result._tasks = tasks; return result; } export function parallel(...tasks: Task[]): PromiseTask { const result = async () => { await Promise.all(tasks.map(t => _execute(t))); }; result._tasks = tasks; return result; } export function define(name: string, task: Task): Task { if (task._tasks) { // This is a composite task const lastTask = task._tasks[task._tasks.length - 1]; if (lastTask._tasks || lastTask.taskName) { // This is a composite task without a real task function // => generate a fake task function return define(name, series(task, () => Promise.resolve())); } lastTask.taskName = name; task.displayName = name; return task; } // This is a simple task task.taskName = name; task.displayName = name; return task; } ================================================ FILE: build/lib/test/i18n.test.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = __importDefault(require("assert")); const i18n = __importStar(require("../i18n")); suite('XLF Parser Tests', () => { const sampleXlf = 'Key #1Key #2 &'; const sampleTranslatedXlf = 'Key #1Кнопка #1Key #2 &Кнопка #2 &'; const name = 'vs/base/common/keybinding'; const keys = ['key1', 'key2']; const messages = ['Key #1', 'Key #2 &']; const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' }; test('Keys & messages to XLF conversion', () => { const xlf = new i18n.XLF('vscode-workbench'); xlf.addFile(name, keys, messages); const xlfString = xlf.toString(); assert_1.default.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf); }); test('XLF to keys & messages conversion', () => { i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) { assert_1.default.deepStrictEqual(resolvedFiles[0].messages, translatedMessages); assert_1.default.strictEqual(resolvedFiles[0].name, name); }); }); test('JSON file source path to Transifex resource match', () => { const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench'; const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/textfile', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject }; assert_1.default.deepStrictEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform); assert_1.default.deepStrictEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib); assert_1.default.deepStrictEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor); assert_1.default.deepStrictEqual(i18n.getResource('vs/base/common/errorMessage'), base); assert_1.default.deepStrictEqual(i18n.getResource('vs/code/electron-main/window'), code); assert_1.default.deepStrictEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts); assert_1.default.deepStrictEqual(i18n.getResource('vs/workbench/services/textfile/node/testFileService'), workbenchServices); assert_1.default.deepStrictEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench); }); }); //# sourceMappingURL=i18n.test.js.map ================================================ FILE: build/lib/test/i18n.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import assert from 'assert'; import * as i18n from '../i18n'; suite('XLF Parser Tests', () => { const sampleXlf = 'Key #1Key #2 &'; const sampleTranslatedXlf = 'Key #1Кнопка #1Key #2 &Кнопка #2 &'; const name = 'vs/base/common/keybinding'; const keys = ['key1', 'key2']; const messages = ['Key #1', 'Key #2 &']; const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' }; test('Keys & messages to XLF conversion', () => { const xlf = new i18n.XLF('vscode-workbench'); xlf.addFile(name, keys, messages); const xlfString = xlf.toString(); assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf); }); test('XLF to keys & messages conversion', () => { i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) { assert.deepStrictEqual(resolvedFiles[0].messages, translatedMessages); assert.strictEqual(resolvedFiles[0].name, name); }); }); test('JSON file source path to Transifex resource match', () => { const editorProject: string = 'vscode-editor', workbenchProject: string = 'vscode-workbench'; const platform: i18n.Resource = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/textfile', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject }; assert.deepStrictEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform); assert.deepStrictEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib); assert.deepStrictEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor); assert.deepStrictEqual(i18n.getResource('vs/base/common/errorMessage'), base); assert.deepStrictEqual(i18n.getResource('vs/code/electron-main/window'), code); assert.deepStrictEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts); assert.deepStrictEqual(i18n.getResource('vs/workbench/services/textfile/node/testFileService'), workbenchServices); assert.deepStrictEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench); }); }); ================================================ FILE: build/lib/treeshaking.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ShakeLevel = void 0; exports.toStringShakeLevel = toStringShakeLevel; exports.shake = shake; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const TYPESCRIPT_LIB_FOLDER = path_1.default.dirname(require.resolve('typescript/lib/lib.d.ts')); var ShakeLevel; (function (ShakeLevel) { ShakeLevel[ShakeLevel["Files"] = 0] = "Files"; ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile"; ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers"; })(ShakeLevel || (exports.ShakeLevel = ShakeLevel = {})); function toStringShakeLevel(shakeLevel) { switch (shakeLevel) { case 0 /* ShakeLevel.Files */: return 'Files (0)'; case 1 /* ShakeLevel.InnerFile */: return 'InnerFile (1)'; case 2 /* ShakeLevel.ClassMembers */: return 'ClassMembers (2)'; } } function printDiagnostics(options, diagnostics) { for (const diag of diagnostics) { let result = ''; if (diag.file) { result += `${path_1.default.join(options.sourcesRoot, diag.file.fileName)}`; } if (diag.file && diag.start) { const location = diag.file.getLineAndCharacterOfPosition(diag.start); result += `:${location.line + 1}:${location.character}`; } result += ` - ` + JSON.stringify(diag.messageText); console.log(result); } } function shake(options) { const ts = require('typescript'); const languageService = createTypeScriptLanguageService(ts, options); const program = languageService.getProgram(); const globalDiagnostics = program.getGlobalDiagnostics(); if (globalDiagnostics.length > 0) { printDiagnostics(options, globalDiagnostics); throw new Error(`Compilation Errors encountered.`); } const syntacticDiagnostics = program.getSyntacticDiagnostics(); if (syntacticDiagnostics.length > 0) { printDiagnostics(options, syntacticDiagnostics); throw new Error(`Compilation Errors encountered.`); } const semanticDiagnostics = program.getSemanticDiagnostics(); if (semanticDiagnostics.length > 0) { printDiagnostics(options, semanticDiagnostics); throw new Error(`Compilation Errors encountered.`); } markNodes(ts, languageService, options); return generateResult(ts, languageService, options.shakeLevel); } //#region Discovery, LanguageService & Setup function createTypeScriptLanguageService(ts, options) { // Discover referenced files const FILES = discoverAndReadFiles(ts, options); // Add fake usage files options.inlineEntryPoints.forEach((inlineEntryPoint, index) => { FILES[`inlineEntryPoint.${index}.ts`] = inlineEntryPoint; }); // Add additional typings options.typings.forEach((typing) => { const filePath = path_1.default.join(options.sourcesRoot, typing); FILES[typing] = fs_1.default.readFileSync(filePath).toString(); }); // Resolve libs const RESOLVED_LIBS = processLibFiles(ts, options); const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options; const host = new TypeScriptLanguageServiceHost(ts, RESOLVED_LIBS, FILES, compilerOptions); return ts.createLanguageService(host); } /** * Read imports and follow them until all files have been handled */ function discoverAndReadFiles(ts, options) { const FILES = {}; const in_queue = Object.create(null); const queue = []; const enqueue = (moduleId) => { // To make the treeshaker work on windows... moduleId = moduleId.replace(/\\/g, '/'); if (in_queue[moduleId]) { return; } in_queue[moduleId] = true; queue.push(moduleId); }; options.entryPoints.forEach((entryPoint) => enqueue(entryPoint)); while (queue.length > 0) { const moduleId = queue.shift(); let redirectedModuleId = moduleId; if (options.redirects[moduleId]) { redirectedModuleId = options.redirects[moduleId]; } const dts_filename = path_1.default.join(options.sourcesRoot, redirectedModuleId + '.d.ts'); if (fs_1.default.existsSync(dts_filename)) { const dts_filecontents = fs_1.default.readFileSync(dts_filename).toString(); FILES[`${moduleId}.d.ts`] = dts_filecontents; continue; } const js_filename = path_1.default.join(options.sourcesRoot, redirectedModuleId + '.js'); if (fs_1.default.existsSync(js_filename)) { // This is an import for a .js file, so ignore it... continue; } const ts_filename = path_1.default.join(options.sourcesRoot, redirectedModuleId + '.ts'); const ts_filecontents = fs_1.default.readFileSync(ts_filename).toString(); const info = ts.preProcessFile(ts_filecontents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { const importedFileName = info.importedFiles[i].fileName; if (options.importIgnorePattern.test(importedFileName)) { // Ignore *.css imports continue; } let importedModuleId = importedFileName; if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) { importedModuleId = path_1.default.join(path_1.default.dirname(moduleId), importedModuleId); if (importedModuleId.endsWith('.js')) { // ESM: code imports require to be relative and have a '.js' file extension importedModuleId = importedModuleId.substr(0, importedModuleId.length - 3); } } enqueue(importedModuleId); } FILES[`${moduleId}.ts`] = ts_filecontents; } return FILES; } /** * Read lib files and follow lib references */ function processLibFiles(ts, options) { const stack = [...options.compilerOptions.lib]; const result = {}; while (stack.length > 0) { const filename = `lib.${stack.shift().toLowerCase()}.d.ts`; const key = `defaultLib:${filename}`; if (!result[key]) { // add this file const filepath = path_1.default.join(TYPESCRIPT_LIB_FOLDER, filename); const sourceText = fs_1.default.readFileSync(filepath).toString(); result[key] = sourceText; // precess dependencies and "recurse" const info = ts.preProcessFile(sourceText); for (const ref of info.libReferenceDirectives) { stack.push(ref.fileName); } } } return result; } /** * A TypeScript language service host */ class TypeScriptLanguageServiceHost { _ts; _libs; _files; _compilerOptions; constructor(ts, libs, files, compilerOptions) { this._ts = ts; this._libs = libs; this._files = files; this._compilerOptions = compilerOptions; } // --- language service host --------------- getCompilationSettings() { return this._compilerOptions; } getScriptFileNames() { return ([] .concat(Object.keys(this._libs)) .concat(Object.keys(this._files))); } getScriptVersion(_fileName) { return '1'; } getProjectVersion() { return '1'; } getScriptSnapshot(fileName) { if (this._files.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._files[fileName]); } else if (this._libs.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._libs[fileName]); } else { return this._ts.ScriptSnapshot.fromString(''); } } getScriptKind(_fileName) { return this._ts.ScriptKind.TS; } getCurrentDirectory() { return ''; } getDefaultLibFileName(_options) { return 'defaultLib:lib.d.ts'; } isDefaultLibFileName(fileName) { return fileName === this.getDefaultLibFileName(this._compilerOptions); } readFile(path, _encoding) { return this._files[path] || this._libs[path]; } fileExists(path) { return path in this._files || path in this._libs; } } //#endregion //#region Tree Shaking var NodeColor; (function (NodeColor) { NodeColor[NodeColor["White"] = 0] = "White"; NodeColor[NodeColor["Gray"] = 1] = "Gray"; NodeColor[NodeColor["Black"] = 2] = "Black"; })(NodeColor || (NodeColor = {})); function getColor(node) { return node.$$$color || 0 /* NodeColor.White */; } function setColor(node, color) { node.$$$color = color; } function markNeededSourceFile(node) { node.$$$neededSourceFile = true; } function isNeededSourceFile(node) { return Boolean(node.$$$neededSourceFile); } function nodeOrParentIsBlack(node) { while (node) { const color = getColor(node); if (color === 2 /* NodeColor.Black */) { return true; } node = node.parent; } return false; } function nodeOrChildIsBlack(node) { if (getColor(node) === 2 /* NodeColor.Black */) { return true; } for (const child of node.getChildren()) { if (nodeOrChildIsBlack(child)) { return true; } } return false; } function isSymbolWithDeclarations(symbol) { return !!(symbol && symbol.declarations); } function isVariableStatementWithSideEffects(ts, node) { if (!ts.isVariableStatement(node)) { return false; } let hasSideEffects = false; const visitNode = (node) => { if (hasSideEffects) { // no need to go on return; } if (ts.isCallExpression(node) || ts.isNewExpression(node)) { // TODO: assuming `createDecorator` and `refineServiceDecorator` calls are side-effect free const isSideEffectFree = /(createDecorator|refineServiceDecorator)/.test(node.expression.getText()); if (!isSideEffectFree) { hasSideEffects = true; } } node.forEachChild(visitNode); }; node.forEachChild(visitNode); return hasSideEffects; } function isStaticMemberWithSideEffects(ts, node) { if (!ts.isPropertyDeclaration(node)) { return false; } if (!node.modifiers) { return false; } if (!node.modifiers.some(mod => mod.kind === ts.SyntaxKind.StaticKeyword)) { return false; } let hasSideEffects = false; const visitNode = (node) => { if (hasSideEffects) { // no need to go on return; } if (ts.isCallExpression(node) || ts.isNewExpression(node)) { hasSideEffects = true; } node.forEachChild(visitNode); }; node.forEachChild(visitNode); return hasSideEffects; } function markNodes(ts, languageService, options) { const program = languageService.getProgram(); if (!program) { throw new Error('Could not get program from language service'); } if (options.shakeLevel === 0 /* ShakeLevel.Files */) { // Mark all source files Black program.getSourceFiles().forEach((sourceFile) => { setColor(sourceFile, 2 /* NodeColor.Black */); }); return; } const black_queue = []; const gray_queue = []; const export_import_queue = []; const sourceFilesLoaded = {}; function enqueueTopLevelModuleStatements(sourceFile) { sourceFile.forEachChild((node) => { if (ts.isImportDeclaration(node)) { if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) { setColor(node, 2 /* NodeColor.Black */); enqueueImport(node, node.moduleSpecifier.text); } return; } if (ts.isExportDeclaration(node)) { if (!node.exportClause && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { // export * from "foo"; setColor(node, 2 /* NodeColor.Black */); enqueueImport(node, node.moduleSpecifier.text); } if (node.exportClause && ts.isNamedExports(node.exportClause)) { for (const exportSpecifier of node.exportClause.elements) { export_import_queue.push(exportSpecifier); } } return; } if (isVariableStatementWithSideEffects(ts, node)) { enqueue_black(node); } if (ts.isExpressionStatement(node) || ts.isIfStatement(node) || ts.isIterationStatement(node, true) || ts.isExportAssignment(node)) { enqueue_black(node); } if (ts.isImportEqualsDeclaration(node)) { if (/export/.test(node.getFullText(sourceFile))) { // e.g. "export import Severity = BaseSeverity;" enqueue_black(node); } } }); } /** * Return the parent of `node` which is an ImportDeclaration */ function findParentImportDeclaration(node) { let _node = node; do { if (ts.isImportDeclaration(_node)) { return _node; } _node = _node.parent; } while (_node); return null; } function enqueue_gray(node) { if (nodeOrParentIsBlack(node) || getColor(node) === 1 /* NodeColor.Gray */) { return; } setColor(node, 1 /* NodeColor.Gray */); gray_queue.push(node); } function enqueue_black(node) { const previousColor = getColor(node); if (previousColor === 2 /* NodeColor.Black */) { return; } if (previousColor === 1 /* NodeColor.Gray */) { // remove from gray queue gray_queue.splice(gray_queue.indexOf(node), 1); setColor(node, 0 /* NodeColor.White */); // add to black queue enqueue_black(node); // move from one queue to the other // black_queue.push(node); // setColor(node, NodeColor.Black); return; } if (nodeOrParentIsBlack(node)) { return; } const fileName = node.getSourceFile().fileName; if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) { setColor(node, 2 /* NodeColor.Black */); return; } const sourceFile = node.getSourceFile(); if (!sourceFilesLoaded[sourceFile.fileName]) { sourceFilesLoaded[sourceFile.fileName] = true; enqueueTopLevelModuleStatements(sourceFile); } if (ts.isSourceFile(node)) { return; } setColor(node, 2 /* NodeColor.Black */); black_queue.push(node); if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); if (references) { for (let i = 0, len = references.length; i < len; i++) { const reference = references[i]; const referenceSourceFile = program.getSourceFile(reference.fileName); if (!referenceSourceFile) { continue; } const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); if (ts.isMethodDeclaration(referenceNode.parent) || ts.isPropertyDeclaration(referenceNode.parent) || ts.isGetAccessor(referenceNode.parent) || ts.isSetAccessor(referenceNode.parent)) { enqueue_gray(referenceNode.parent); } } } } } function enqueueFile(filename) { const sourceFile = program.getSourceFile(filename); if (!sourceFile) { console.warn(`Cannot find source file ${filename}`); return; } // This source file should survive even if it is empty markNeededSourceFile(sourceFile); enqueue_black(sourceFile); } function enqueueImport(node, importText) { if (options.importIgnorePattern.test(importText)) { // this import should be ignored return; } const nodeSourceFile = node.getSourceFile(); let fullPath; if (/(^\.\/)|(^\.\.\/)/.test(importText)) { if (importText.endsWith('.js')) { // ESM: code imports require to be relative and to have a '.js' file extension importText = importText.substr(0, importText.length - 3); } fullPath = path_1.default.join(path_1.default.dirname(nodeSourceFile.fileName), importText) + '.ts'; } else { fullPath = importText + '.ts'; } enqueueFile(fullPath); } options.entryPoints.forEach(moduleId => enqueueFile(moduleId + '.ts')); // Add fake usage files options.inlineEntryPoints.forEach((_, index) => enqueueFile(`inlineEntryPoint.${index}.ts`)); let step = 0; const checker = program.getTypeChecker(); while (black_queue.length > 0 || gray_queue.length > 0) { ++step; let node; if (step % 100 === 0) { console.log(`Treeshaking - ${Math.floor(100 * step / (step + black_queue.length + gray_queue.length))}% - ${step}/${step + black_queue.length + gray_queue.length} (${black_queue.length}, ${gray_queue.length})`); } if (black_queue.length === 0) { for (let i = 0; i < gray_queue.length; i++) { const node = gray_queue[i]; const nodeParent = node.parent; if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) { gray_queue.splice(i, 1); black_queue.push(node); setColor(node, 2 /* NodeColor.Black */); i--; } } } if (black_queue.length > 0) { node = black_queue.shift(); } else { // only gray nodes remaining... break; } const nodeSourceFile = node.getSourceFile(); const loop = (node) => { const symbols = getRealNodeSymbol(ts, checker, node); for (const { symbol, symbolImportNode } of symbols) { if (symbolImportNode) { setColor(symbolImportNode, 2 /* NodeColor.Black */); const importDeclarationNode = findParentImportDeclaration(symbolImportNode); if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) { enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text); } } if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) { for (let i = 0, len = symbol.declarations.length; i < len; i++) { const declaration = symbol.declarations[i]; if (ts.isSourceFile(declaration)) { // Do not enqueue full source files // (they can be the declaration of a module import) continue; } if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { enqueue_black(declaration.name); for (let j = 0; j < declaration.members.length; j++) { const member = declaration.members[j]; const memberName = member.name ? member.name.getText() : null; if (ts.isConstructorDeclaration(member) || ts.isConstructSignatureDeclaration(member) || ts.isIndexSignatureDeclaration(member) || ts.isCallSignatureDeclaration(member) || memberName === '[Symbol.iterator]' || memberName === '[Symbol.toStringTag]' || memberName === 'toJSON' || memberName === 'toString' || memberName === 'dispose' // TODO: keeping all `dispose` methods || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... ) { enqueue_black(member); } if (isStaticMemberWithSideEffects(ts, member)) { enqueue_black(member); } } // queue the heritage clauses if (declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { enqueue_black(heritageClause); } } } else { enqueue_black(declaration); } } } } node.forEachChild(loop); }; node.forEachChild(loop); } while (export_import_queue.length > 0) { const node = export_import_queue.shift(); if (nodeOrParentIsBlack(node)) { continue; } const symbol = node.symbol; if (!symbol) { continue; } const aliased = checker.getAliasedSymbol(symbol); if (aliased.declarations && aliased.declarations.length > 0) { if (nodeOrParentIsBlack(aliased.declarations[0]) || nodeOrChildIsBlack(aliased.declarations[0])) { setColor(node, 2 /* NodeColor.Black */); } } } } function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) { for (let i = 0, len = symbol.declarations.length; i < len; i++) { const declaration = symbol.declarations[i]; const declarationSourceFile = declaration.getSourceFile(); if (nodeSourceFile === declarationSourceFile) { if (declaration.pos <= node.pos && node.end <= declaration.end) { return true; } } } return false; } function generateResult(ts, languageService, shakeLevel) { const program = languageService.getProgram(); if (!program) { throw new Error('Could not get program from language service'); } const result = {}; const writeFile = (filePath, contents) => { result[filePath] = contents; }; program.getSourceFiles().forEach((sourceFile) => { const fileName = sourceFile.fileName; if (/^defaultLib:/.test(fileName)) { return; } const destination = fileName; if (/\.d\.ts$/.test(fileName)) { if (nodeOrChildIsBlack(sourceFile)) { writeFile(destination, sourceFile.text); } return; } const text = sourceFile.text; let result = ''; function keep(node) { result += text.substring(node.pos, node.end); } function write(data) { result += data; } function writeMarkedNodes(node) { if (getColor(node) === 2 /* NodeColor.Black */) { return keep(node); } // Always keep certain top-level statements if (ts.isSourceFile(node.parent)) { if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && node.expression.text === 'use strict') { return keep(node); } if (ts.isVariableStatement(node) && nodeOrChildIsBlack(node)) { return keep(node); } } // Keep the entire import in import * as X cases if (ts.isImportDeclaration(node)) { if (node.importClause && node.importClause.namedBindings) { if (ts.isNamespaceImport(node.importClause.namedBindings)) { if (getColor(node.importClause.namedBindings) === 2 /* NodeColor.Black */) { return keep(node); } } else { const survivingImports = []; for (const importNode of node.importClause.namedBindings.elements) { if (getColor(importNode) === 2 /* NodeColor.Black */) { survivingImports.push(importNode.getFullText(sourceFile)); } } const leadingTriviaWidth = node.getLeadingTriviaWidth(); const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth); if (survivingImports.length > 0) { if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* NodeColor.Black */) { return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } else { if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* NodeColor.Black */) { return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`); } } } } else { if (node.importClause && getColor(node.importClause) === 2 /* NodeColor.Black */) { return keep(node); } } } if (ts.isExportDeclaration(node)) { if (node.exportClause && node.moduleSpecifier && ts.isNamedExports(node.exportClause)) { const survivingExports = []; for (const exportSpecifier of node.exportClause.elements) { if (getColor(exportSpecifier) === 2 /* NodeColor.Black */) { survivingExports.push(exportSpecifier.getFullText(sourceFile)); } } const leadingTriviaWidth = node.getLeadingTriviaWidth(); const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth); if (survivingExports.length > 0) { return write(`${leadingTrivia}export {${survivingExports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } } } if (shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { let toWrite = node.getFullText(); for (let i = node.members.length - 1; i >= 0; i--) { const member = node.members[i]; if (getColor(member) === 2 /* NodeColor.Black */ || !member.name) { // keep method continue; } const pos = member.pos - node.pos; const end = member.end - node.pos; toWrite = toWrite.substring(0, pos) + toWrite.substring(end); } return write(toWrite); } if (ts.isFunctionDeclaration(node)) { // Do not go inside functions if they haven't been marked return; } node.forEachChild(writeMarkedNodes); } if (getColor(sourceFile) !== 2 /* NodeColor.Black */) { if (!nodeOrChildIsBlack(sourceFile)) { // none of the elements are reachable if (isNeededSourceFile(sourceFile)) { // this source file must be written, even if nothing is used from it // because there is an import somewhere for it. // However, TS complains with empty files with the error "x" is not a module, // so we will export a dummy variable result = 'export const __dummy = 0;'; } else { // don't write this file at all! return; } } else { sourceFile.forEachChild(writeMarkedNodes); result += sourceFile.endOfFileToken.getFullText(sourceFile); } } else { result = text; } writeFile(destination, result); }); return result; } //#endregion //#region Utils function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration) { if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { for (const type of heritageClause.types) { const symbol = findSymbolFromHeritageType(ts, checker, type); if (symbol) { const decl = symbol.valueDeclaration || (symbol.declarations && symbol.declarations[0]); if (decl && program.isSourceFileDefaultLibrary(decl.getSourceFile())) { return true; } } } } } return false; } function findSymbolFromHeritageType(ts, checker, type) { if (ts.isExpressionWithTypeArguments(type)) { return findSymbolFromHeritageType(ts, checker, type.expression); } if (ts.isIdentifier(type)) { const tmp = getRealNodeSymbol(ts, checker, type); return (tmp.length > 0 ? tmp[0].symbol : null); } if (ts.isPropertyAccessExpression(type)) { return findSymbolFromHeritageType(ts, checker, type.name); } return null; } class SymbolImportTuple { symbol; symbolImportNode; constructor(symbol, symbolImportNode) { this.symbol = symbol; this.symbolImportNode = symbolImportNode; } } /** * Returns the node's symbol and the `import` node (if the symbol resolved from a different module) */ function getRealNodeSymbol(ts, checker, node) { const getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType; const getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement; const getNameFromPropertyName = ts.getNameFromPropertyName; // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). // (2) when the aliased symbol is originating from an import. // function shouldSkipAlias(node, declaration) { if (!ts.isShorthandPropertyAssignment(node) && node.kind !== ts.SyntaxKind.Identifier) { return false; } if (node.parent === declaration) { return true; } switch (declaration.kind) { case ts.SyntaxKind.ImportClause: case ts.SyntaxKind.ImportEqualsDeclaration: return true; case ts.SyntaxKind.ImportSpecifier: return declaration.parent.kind === ts.SyntaxKind.NamedImports; default: return false; } } if (!ts.isShorthandPropertyAssignment(node)) { if (node.getChildCount() !== 0) { return []; } } const { parent } = node; let symbol = (ts.isShorthandPropertyAssignment(node) ? checker.getShorthandAssignmentValueSymbol(node) : checker.getSymbolAtLocation(node)); let importNode = null; // If this is an alias, and the request came at the declaration location // get the aliased symbol instead. This allows for goto def on an import e.g. // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol && symbol.flags & ts.SymbolFlags.Alias && symbol.declarations && shouldSkipAlias(node, symbol.declarations[0])) { const aliased = checker.getAliasedSymbol(symbol); if (aliased.declarations) { // We should mark the import as visited importNode = symbol.declarations[0]; symbol = aliased; } } if (symbol) { // Because name in short-hand property assignment has two different meanings: property name and property value, // using go-to-definition at such position should go to the variable declaration of the property value rather than // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { symbol = checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); } // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern // and return the property declaration for the referenced property. // For example: // import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo" // // function bar(onfulfilled: (value: T) => void) { //....} // interface Test { // pr/*destination*/op1: number // } // bar(({pr/*goto*/op1})=>{}); if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) && (node === (parent.propertyName || parent.name))) { const name = getNameFromPropertyName(node); const type = checker.getTypeAtLocation(parent.parent); if (name && type) { if (type.isUnion()) { return generateMultipleSymbols(type, name, importNode); } else { const prop = type.getProperty(name); if (prop) { symbol = prop; } } } } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example // interface Props{ // /*first*/prop1: number // prop2: boolean // } // function Foo(arg: Props) {} // Foo( { pr/*1*/op1: 10, prop2: false }) const element = getContainingObjectLiteralElement(node); if (element) { const contextualType = element && checker.getContextualType(element.parent); if (contextualType) { const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false); if (propertySymbols) { symbol = propertySymbols[0]; } } } } if (symbol && symbol.declarations) { return [new SymbolImportTuple(symbol, importNode)]; } return []; function generateMultipleSymbols(type, name, importNode) { const result = []; for (const t of type.types) { const prop = t.getProperty(name); if (prop && prop.declarations) { result.push(new SymbolImportTuple(prop, importNode)); } } return result; } } /** Get the token whose text contains the position */ function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) { let current = sourceFile; outer: while (true) { // find the child that contains 'position' for (const child of current.getChildren()) { const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true); if (start > position) { // If this child begins after position, then all subsequent children will as well. break; } const end = child.getEnd(); if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) { current = child; continue outer; } } return current; } } //#endregion //# sourceMappingURL=treeshaking.js.map ================================================ FILE: build/lib/treeshaking.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import type * as ts from 'typescript'; const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts')); export const enum ShakeLevel { Files = 0, InnerFile = 1, ClassMembers = 2 } export function toStringShakeLevel(shakeLevel: ShakeLevel): string { switch (shakeLevel) { case ShakeLevel.Files: return 'Files (0)'; case ShakeLevel.InnerFile: return 'InnerFile (1)'; case ShakeLevel.ClassMembers: return 'ClassMembers (2)'; } } export interface ITreeShakingOptions { /** * The full path to the root where sources are. */ sourcesRoot: string; /** * Module ids. * e.g. `vs/editor/editor.main` or `index` */ entryPoints: string[]; /** * Inline usages. */ inlineEntryPoints: string[]; /** * Other .d.ts files */ typings: string[]; /** * TypeScript compiler options. */ compilerOptions?: any; /** * The shake level to perform. */ shakeLevel: ShakeLevel; /** * regex pattern to ignore certain imports e.g. `.css` imports */ importIgnorePattern: RegExp; redirects: { [module: string]: string }; } export interface ITreeShakingResult { [file: string]: string; } function printDiagnostics(options: ITreeShakingOptions, diagnostics: ReadonlyArray): void { for (const diag of diagnostics) { let result = ''; if (diag.file) { result += `${path.join(options.sourcesRoot, diag.file.fileName)}`; } if (diag.file && diag.start) { const location = diag.file.getLineAndCharacterOfPosition(diag.start); result += `:${location.line + 1}:${location.character}`; } result += ` - ` + JSON.stringify(diag.messageText); console.log(result); } } export function shake(options: ITreeShakingOptions): ITreeShakingResult { const ts = require('typescript') as typeof import('typescript'); const languageService = createTypeScriptLanguageService(ts, options); const program = languageService.getProgram()!; const globalDiagnostics = program.getGlobalDiagnostics(); if (globalDiagnostics.length > 0) { printDiagnostics(options, globalDiagnostics); throw new Error(`Compilation Errors encountered.`); } const syntacticDiagnostics = program.getSyntacticDiagnostics(); if (syntacticDiagnostics.length > 0) { printDiagnostics(options, syntacticDiagnostics); throw new Error(`Compilation Errors encountered.`); } const semanticDiagnostics = program.getSemanticDiagnostics(); if (semanticDiagnostics.length > 0) { printDiagnostics(options, semanticDiagnostics); throw new Error(`Compilation Errors encountered.`); } markNodes(ts, languageService, options); return generateResult(ts, languageService, options.shakeLevel); } //#region Discovery, LanguageService & Setup function createTypeScriptLanguageService(ts: typeof import('typescript'), options: ITreeShakingOptions): ts.LanguageService { // Discover referenced files const FILES = discoverAndReadFiles(ts, options); // Add fake usage files options.inlineEntryPoints.forEach((inlineEntryPoint, index) => { FILES[`inlineEntryPoint.${index}.ts`] = inlineEntryPoint; }); // Add additional typings options.typings.forEach((typing) => { const filePath = path.join(options.sourcesRoot, typing); FILES[typing] = fs.readFileSync(filePath).toString(); }); // Resolve libs const RESOLVED_LIBS = processLibFiles(ts, options); const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options; const host = new TypeScriptLanguageServiceHost(ts, RESOLVED_LIBS, FILES, compilerOptions); return ts.createLanguageService(host); } /** * Read imports and follow them until all files have been handled */ function discoverAndReadFiles(ts: typeof import('typescript'), options: ITreeShakingOptions): IFileMap { const FILES: IFileMap = {}; const in_queue: { [module: string]: boolean } = Object.create(null); const queue: string[] = []; const enqueue = (moduleId: string) => { // To make the treeshaker work on windows... moduleId = moduleId.replace(/\\/g, '/'); if (in_queue[moduleId]) { return; } in_queue[moduleId] = true; queue.push(moduleId); }; options.entryPoints.forEach((entryPoint) => enqueue(entryPoint)); while (queue.length > 0) { const moduleId = queue.shift()!; let redirectedModuleId: string = moduleId; if (options.redirects[moduleId]) { redirectedModuleId = options.redirects[moduleId]; } const dts_filename = path.join(options.sourcesRoot, redirectedModuleId + '.d.ts'); if (fs.existsSync(dts_filename)) { const dts_filecontents = fs.readFileSync(dts_filename).toString(); FILES[`${moduleId}.d.ts`] = dts_filecontents; continue; } const js_filename = path.join(options.sourcesRoot, redirectedModuleId + '.js'); if (fs.existsSync(js_filename)) { // This is an import for a .js file, so ignore it... continue; } const ts_filename = path.join(options.sourcesRoot, redirectedModuleId + '.ts'); const ts_filecontents = fs.readFileSync(ts_filename).toString(); const info = ts.preProcessFile(ts_filecontents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { const importedFileName = info.importedFiles[i].fileName; if (options.importIgnorePattern.test(importedFileName)) { // Ignore *.css imports continue; } let importedModuleId = importedFileName; if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) { importedModuleId = path.join(path.dirname(moduleId), importedModuleId); if (importedModuleId.endsWith('.js')) { // ESM: code imports require to be relative and have a '.js' file extension importedModuleId = importedModuleId.substr(0, importedModuleId.length - 3); } } enqueue(importedModuleId); } FILES[`${moduleId}.ts`] = ts_filecontents; } return FILES; } /** * Read lib files and follow lib references */ function processLibFiles(ts: typeof import('typescript'), options: ITreeShakingOptions): ILibMap { const stack: string[] = [...options.compilerOptions.lib]; const result: ILibMap = {}; while (stack.length > 0) { const filename = `lib.${stack.shift()!.toLowerCase()}.d.ts`; const key = `defaultLib:${filename}`; if (!result[key]) { // add this file const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename); const sourceText = fs.readFileSync(filepath).toString(); result[key] = sourceText; // precess dependencies and "recurse" const info = ts.preProcessFile(sourceText); for (const ref of info.libReferenceDirectives) { stack.push(ref.fileName); } } } return result; } interface ILibMap { [libName: string]: string } interface IFileMap { [fileName: string]: string } /** * A TypeScript language service host */ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost { private readonly _ts: typeof import('typescript'); private readonly _libs: ILibMap; private readonly _files: IFileMap; private readonly _compilerOptions: ts.CompilerOptions; constructor(ts: typeof import('typescript'), libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) { this._ts = ts; this._libs = libs; this._files = files; this._compilerOptions = compilerOptions; } // --- language service host --------------- getCompilationSettings(): ts.CompilerOptions { return this._compilerOptions; } getScriptFileNames(): string[] { return ( ([] as string[]) .concat(Object.keys(this._libs)) .concat(Object.keys(this._files)) ); } getScriptVersion(_fileName: string): string { return '1'; } getProjectVersion(): string { return '1'; } getScriptSnapshot(fileName: string): ts.IScriptSnapshot { if (this._files.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._files[fileName]); } else if (this._libs.hasOwnProperty(fileName)) { return this._ts.ScriptSnapshot.fromString(this._libs[fileName]); } else { return this._ts.ScriptSnapshot.fromString(''); } } getScriptKind(_fileName: string): ts.ScriptKind { return this._ts.ScriptKind.TS; } getCurrentDirectory(): string { return ''; } getDefaultLibFileName(_options: ts.CompilerOptions): string { return 'defaultLib:lib.d.ts'; } isDefaultLibFileName(fileName: string): boolean { return fileName === this.getDefaultLibFileName(this._compilerOptions); } readFile(path: string, _encoding?: string): string | undefined { return this._files[path] || this._libs[path]; } fileExists(path: string): boolean { return path in this._files || path in this._libs; } } //#endregion //#region Tree Shaking const enum NodeColor { White = 0, Gray = 1, Black = 2 } function getColor(node: ts.Node): NodeColor { return (node).$$$color || NodeColor.White; } function setColor(node: ts.Node, color: NodeColor): void { (node).$$$color = color; } function markNeededSourceFile(node: ts.SourceFile): void { (node).$$$neededSourceFile = true; } function isNeededSourceFile(node: ts.SourceFile): boolean { return Boolean((node).$$$neededSourceFile); } function nodeOrParentIsBlack(node: ts.Node): boolean { while (node) { const color = getColor(node); if (color === NodeColor.Black) { return true; } node = node.parent; } return false; } function nodeOrChildIsBlack(node: ts.Node): boolean { if (getColor(node) === NodeColor.Black) { return true; } for (const child of node.getChildren()) { if (nodeOrChildIsBlack(child)) { return true; } } return false; } function isSymbolWithDeclarations(symbol: ts.Symbol | undefined | null): symbol is ts.Symbol & { declarations: ts.Declaration[] } { return !!(symbol && symbol.declarations); } function isVariableStatementWithSideEffects(ts: typeof import('typescript'), node: ts.Node): boolean { if (!ts.isVariableStatement(node)) { return false; } let hasSideEffects = false; const visitNode = (node: ts.Node) => { if (hasSideEffects) { // no need to go on return; } if (ts.isCallExpression(node) || ts.isNewExpression(node)) { // TODO: assuming `createDecorator` and `refineServiceDecorator` calls are side-effect free const isSideEffectFree = /(createDecorator|refineServiceDecorator)/.test(node.expression.getText()); if (!isSideEffectFree) { hasSideEffects = true; } } node.forEachChild(visitNode); }; node.forEachChild(visitNode); return hasSideEffects; } function isStaticMemberWithSideEffects(ts: typeof import('typescript'), node: ts.ClassElement | ts.TypeElement): boolean { if (!ts.isPropertyDeclaration(node)) { return false; } if (!node.modifiers) { return false; } if (!node.modifiers.some(mod => mod.kind === ts.SyntaxKind.StaticKeyword)) { return false; } let hasSideEffects = false; const visitNode = (node: ts.Node) => { if (hasSideEffects) { // no need to go on return; } if (ts.isCallExpression(node) || ts.isNewExpression(node)) { hasSideEffects = true; } node.forEachChild(visitNode); }; node.forEachChild(visitNode); return hasSideEffects; } function markNodes(ts: typeof import('typescript'), languageService: ts.LanguageService, options: ITreeShakingOptions) { const program = languageService.getProgram(); if (!program) { throw new Error('Could not get program from language service'); } if (options.shakeLevel === ShakeLevel.Files) { // Mark all source files Black program.getSourceFiles().forEach((sourceFile) => { setColor(sourceFile, NodeColor.Black); }); return; } const black_queue: ts.Node[] = []; const gray_queue: ts.Node[] = []; const export_import_queue: ts.Node[] = []; const sourceFilesLoaded: { [fileName: string]: boolean } = {}; function enqueueTopLevelModuleStatements(sourceFile: ts.SourceFile): void { sourceFile.forEachChild((node: ts.Node) => { if (ts.isImportDeclaration(node)) { if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) { setColor(node, NodeColor.Black); enqueueImport(node, node.moduleSpecifier.text); } return; } if (ts.isExportDeclaration(node)) { if (!node.exportClause && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { // export * from "foo"; setColor(node, NodeColor.Black); enqueueImport(node, node.moduleSpecifier.text); } if (node.exportClause && ts.isNamedExports(node.exportClause)) { for (const exportSpecifier of node.exportClause.elements) { export_import_queue.push(exportSpecifier); } } return; } if (isVariableStatementWithSideEffects(ts, node)) { enqueue_black(node); } if ( ts.isExpressionStatement(node) || ts.isIfStatement(node) || ts.isIterationStatement(node, true) || ts.isExportAssignment(node) ) { enqueue_black(node); } if (ts.isImportEqualsDeclaration(node)) { if (/export/.test(node.getFullText(sourceFile))) { // e.g. "export import Severity = BaseSeverity;" enqueue_black(node); } } }); } /** * Return the parent of `node` which is an ImportDeclaration */ function findParentImportDeclaration(node: ts.Declaration): ts.ImportDeclaration | null { let _node: ts.Node = node; do { if (ts.isImportDeclaration(_node)) { return _node; } _node = _node.parent; } while (_node); return null; } function enqueue_gray(node: ts.Node): void { if (nodeOrParentIsBlack(node) || getColor(node) === NodeColor.Gray) { return; } setColor(node, NodeColor.Gray); gray_queue.push(node); } function enqueue_black(node: ts.Node): void { const previousColor = getColor(node); if (previousColor === NodeColor.Black) { return; } if (previousColor === NodeColor.Gray) { // remove from gray queue gray_queue.splice(gray_queue.indexOf(node), 1); setColor(node, NodeColor.White); // add to black queue enqueue_black(node); // move from one queue to the other // black_queue.push(node); // setColor(node, NodeColor.Black); return; } if (nodeOrParentIsBlack(node)) { return; } const fileName = node.getSourceFile().fileName; if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) { setColor(node, NodeColor.Black); return; } const sourceFile = node.getSourceFile(); if (!sourceFilesLoaded[sourceFile.fileName]) { sourceFilesLoaded[sourceFile.fileName] = true; enqueueTopLevelModuleStatements(sourceFile); } if (ts.isSourceFile(node)) { return; } setColor(node, NodeColor.Black); black_queue.push(node); if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); if (references) { for (let i = 0, len = references.length; i < len; i++) { const reference = references[i]; const referenceSourceFile = program!.getSourceFile(reference.fileName); if (!referenceSourceFile) { continue; } const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); if ( ts.isMethodDeclaration(referenceNode.parent) || ts.isPropertyDeclaration(referenceNode.parent) || ts.isGetAccessor(referenceNode.parent) || ts.isSetAccessor(referenceNode.parent) ) { enqueue_gray(referenceNode.parent); } } } } } function enqueueFile(filename: string): void { const sourceFile = program!.getSourceFile(filename); if (!sourceFile) { console.warn(`Cannot find source file ${filename}`); return; } // This source file should survive even if it is empty markNeededSourceFile(sourceFile); enqueue_black(sourceFile); } function enqueueImport(node: ts.Node, importText: string): void { if (options.importIgnorePattern.test(importText)) { // this import should be ignored return; } const nodeSourceFile = node.getSourceFile(); let fullPath: string; if (/(^\.\/)|(^\.\.\/)/.test(importText)) { if (importText.endsWith('.js')) { // ESM: code imports require to be relative and to have a '.js' file extension importText = importText.substr(0, importText.length - 3); } fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts'; } else { fullPath = importText + '.ts'; } enqueueFile(fullPath); } options.entryPoints.forEach(moduleId => enqueueFile(moduleId + '.ts')); // Add fake usage files options.inlineEntryPoints.forEach((_, index) => enqueueFile(`inlineEntryPoint.${index}.ts`)); let step = 0; const checker = program.getTypeChecker(); while (black_queue.length > 0 || gray_queue.length > 0) { ++step; let node: ts.Node; if (step % 100 === 0) { console.log(`Treeshaking - ${Math.floor(100 * step / (step + black_queue.length + gray_queue.length))}% - ${step}/${step + black_queue.length + gray_queue.length} (${black_queue.length}, ${gray_queue.length})`); } if (black_queue.length === 0) { for (let i = 0; i < gray_queue.length; i++) { const node = gray_queue[i]; const nodeParent = node.parent; if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) { gray_queue.splice(i, 1); black_queue.push(node); setColor(node, NodeColor.Black); i--; } } } if (black_queue.length > 0) { node = black_queue.shift()!; } else { // only gray nodes remaining... break; } const nodeSourceFile = node.getSourceFile(); const loop = (node: ts.Node) => { const symbols = getRealNodeSymbol(ts, checker, node); for (const { symbol, symbolImportNode } of symbols) { if (symbolImportNode) { setColor(symbolImportNode, NodeColor.Black); const importDeclarationNode = findParentImportDeclaration(symbolImportNode); if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) { enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text); } } if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) { for (let i = 0, len = symbol.declarations.length; i < len; i++) { const declaration = symbol.declarations[i]; if (ts.isSourceFile(declaration)) { // Do not enqueue full source files // (they can be the declaration of a module import) continue; } if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { enqueue_black(declaration.name!); for (let j = 0; j < declaration.members.length; j++) { const member = declaration.members[j]; const memberName = member.name ? member.name.getText() : null; if ( ts.isConstructorDeclaration(member) || ts.isConstructSignatureDeclaration(member) || ts.isIndexSignatureDeclaration(member) || ts.isCallSignatureDeclaration(member) || memberName === '[Symbol.iterator]' || memberName === '[Symbol.toStringTag]' || memberName === 'toJSON' || memberName === 'toString' || memberName === 'dispose'// TODO: keeping all `dispose` methods || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... ) { enqueue_black(member); } if (isStaticMemberWithSideEffects(ts, member)) { enqueue_black(member); } } // queue the heritage clauses if (declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { enqueue_black(heritageClause); } } } else { enqueue_black(declaration); } } } } node.forEachChild(loop); }; node.forEachChild(loop); } while (export_import_queue.length > 0) { const node = export_import_queue.shift()!; if (nodeOrParentIsBlack(node)) { continue; } const symbol: ts.Symbol | undefined = (node).symbol; if (!symbol) { continue; } const aliased = checker.getAliasedSymbol(symbol); if (aliased.declarations && aliased.declarations.length > 0) { if (nodeOrParentIsBlack(aliased.declarations[0]) || nodeOrChildIsBlack(aliased.declarations[0])) { setColor(node, NodeColor.Black); } } } } function nodeIsInItsOwnDeclaration(nodeSourceFile: ts.SourceFile, node: ts.Node, symbol: ts.Symbol & { declarations: ts.Declaration[] }): boolean { for (let i = 0, len = symbol.declarations.length; i < len; i++) { const declaration = symbol.declarations[i]; const declarationSourceFile = declaration.getSourceFile(); if (nodeSourceFile === declarationSourceFile) { if (declaration.pos <= node.pos && node.end <= declaration.end) { return true; } } } return false; } function generateResult(ts: typeof import('typescript'), languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult { const program = languageService.getProgram(); if (!program) { throw new Error('Could not get program from language service'); } const result: ITreeShakingResult = {}; const writeFile = (filePath: string, contents: string): void => { result[filePath] = contents; }; program.getSourceFiles().forEach((sourceFile) => { const fileName = sourceFile.fileName; if (/^defaultLib:/.test(fileName)) { return; } const destination = fileName; if (/\.d\.ts$/.test(fileName)) { if (nodeOrChildIsBlack(sourceFile)) { writeFile(destination, sourceFile.text); } return; } const text = sourceFile.text; let result = ''; function keep(node: ts.Node): void { result += text.substring(node.pos, node.end); } function write(data: string): void { result += data; } function writeMarkedNodes(node: ts.Node): void { if (getColor(node) === NodeColor.Black) { return keep(node); } // Always keep certain top-level statements if (ts.isSourceFile(node.parent)) { if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && node.expression.text === 'use strict') { return keep(node); } if (ts.isVariableStatement(node) && nodeOrChildIsBlack(node)) { return keep(node); } } // Keep the entire import in import * as X cases if (ts.isImportDeclaration(node)) { if (node.importClause && node.importClause.namedBindings) { if (ts.isNamespaceImport(node.importClause.namedBindings)) { if (getColor(node.importClause.namedBindings) === NodeColor.Black) { return keep(node); } } else { const survivingImports: string[] = []; for (const importNode of node.importClause.namedBindings.elements) { if (getColor(importNode) === NodeColor.Black) { survivingImports.push(importNode.getFullText(sourceFile)); } } const leadingTriviaWidth = node.getLeadingTriviaWidth(); const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth); if (survivingImports.length > 0) { if (node.importClause && node.importClause.name && getColor(node.importClause) === NodeColor.Black) { return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } else { if (node.importClause && node.importClause.name && getColor(node.importClause) === NodeColor.Black) { return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`); } } } } else { if (node.importClause && getColor(node.importClause) === NodeColor.Black) { return keep(node); } } } if (ts.isExportDeclaration(node)) { if (node.exportClause && node.moduleSpecifier && ts.isNamedExports(node.exportClause)) { const survivingExports: string[] = []; for (const exportSpecifier of node.exportClause.elements) { if (getColor(exportSpecifier) === NodeColor.Black) { survivingExports.push(exportSpecifier.getFullText(sourceFile)); } } const leadingTriviaWidth = node.getLeadingTriviaWidth(); const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth); if (survivingExports.length > 0) { return write(`${leadingTrivia}export {${survivingExports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`); } } } if (shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { let toWrite = node.getFullText(); for (let i = node.members.length - 1; i >= 0; i--) { const member = node.members[i]; if (getColor(member) === NodeColor.Black || !member.name) { // keep method continue; } const pos = member.pos - node.pos; const end = member.end - node.pos; toWrite = toWrite.substring(0, pos) + toWrite.substring(end); } return write(toWrite); } if (ts.isFunctionDeclaration(node)) { // Do not go inside functions if they haven't been marked return; } node.forEachChild(writeMarkedNodes); } if (getColor(sourceFile) !== NodeColor.Black) { if (!nodeOrChildIsBlack(sourceFile)) { // none of the elements are reachable if (isNeededSourceFile(sourceFile)) { // this source file must be written, even if nothing is used from it // because there is an import somewhere for it. // However, TS complains with empty files with the error "x" is not a module, // so we will export a dummy variable result = 'export const __dummy = 0;'; } else { // don't write this file at all! return; } } else { sourceFile.forEachChild(writeMarkedNodes); result += sourceFile.endOfFileToken.getFullText(sourceFile); } } else { result = text; } writeFile(destination, result); }); return result; } //#endregion //#region Utils function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts: typeof import('typescript'), program: ts.Program, checker: ts.TypeChecker, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean { if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { for (const type of heritageClause.types) { const symbol = findSymbolFromHeritageType(ts, checker, type); if (symbol) { const decl = symbol.valueDeclaration || (symbol.declarations && symbol.declarations[0]); if (decl && program.isSourceFileDefaultLibrary(decl.getSourceFile())) { return true; } } } } } return false; } function findSymbolFromHeritageType(ts: typeof import('typescript'), checker: ts.TypeChecker, type: ts.ExpressionWithTypeArguments | ts.Expression | ts.PrivateIdentifier): ts.Symbol | null { if (ts.isExpressionWithTypeArguments(type)) { return findSymbolFromHeritageType(ts, checker, type.expression); } if (ts.isIdentifier(type)) { const tmp = getRealNodeSymbol(ts, checker, type); return (tmp.length > 0 ? tmp[0].symbol : null); } if (ts.isPropertyAccessExpression(type)) { return findSymbolFromHeritageType(ts, checker, type.name); } return null; } class SymbolImportTuple { constructor( public readonly symbol: ts.Symbol | null, public readonly symbolImportNode: ts.Declaration | null ) { } } /** * Returns the node's symbol and the `import` node (if the symbol resolved from a different module) */ function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChecker, node: ts.Node): SymbolImportTuple[] { // Use some TypeScript internals to avoid code duplication type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes }; const getPropertySymbolsFromContextualType: (node: ObjectLiteralElementWithName, checker: ts.TypeChecker, contextualType: ts.Type, unionSymbolOk: boolean) => ReadonlyArray = (ts).getPropertySymbolsFromContextualType; const getContainingObjectLiteralElement: (node: ts.Node) => ObjectLiteralElementWithName | undefined = (ts).getContainingObjectLiteralElement; const getNameFromPropertyName: (name: ts.PropertyName) => string | undefined = (ts).getNameFromPropertyName; // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). // (2) when the aliased symbol is originating from an import. // function shouldSkipAlias(node: ts.Node, declaration: ts.Node): boolean { if (!ts.isShorthandPropertyAssignment(node) && node.kind !== ts.SyntaxKind.Identifier) { return false; } if (node.parent === declaration) { return true; } switch (declaration.kind) { case ts.SyntaxKind.ImportClause: case ts.SyntaxKind.ImportEqualsDeclaration: return true; case ts.SyntaxKind.ImportSpecifier: return declaration.parent.kind === ts.SyntaxKind.NamedImports; default: return false; } } if (!ts.isShorthandPropertyAssignment(node)) { if (node.getChildCount() !== 0) { return []; } } const { parent } = node; let symbol = ( ts.isShorthandPropertyAssignment(node) ? checker.getShorthandAssignmentValueSymbol(node) : checker.getSymbolAtLocation(node) ); let importNode: ts.Declaration | null = null; // If this is an alias, and the request came at the declaration location // get the aliased symbol instead. This allows for goto def on an import e.g. // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol && symbol.flags & ts.SymbolFlags.Alias && symbol.declarations && shouldSkipAlias(node, symbol.declarations[0])) { const aliased = checker.getAliasedSymbol(symbol); if (aliased.declarations) { // We should mark the import as visited importNode = symbol.declarations[0]; symbol = aliased; } } if (symbol) { // Because name in short-hand property assignment has two different meanings: property name and property value, // using go-to-definition at such position should go to the variable declaration of the property value rather than // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { symbol = checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); } // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern // and return the property declaration for the referenced property. // For example: // import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo" // // function bar(onfulfilled: (value: T) => void) { //....} // interface Test { // pr/*destination*/op1: number // } // bar(({pr/*goto*/op1})=>{}); if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) && (node === (parent.propertyName || parent.name))) { const name = getNameFromPropertyName(node); const type = checker.getTypeAtLocation(parent.parent); if (name && type) { if (type.isUnion()) { return generateMultipleSymbols(type, name, importNode); } else { const prop = type.getProperty(name); if (prop) { symbol = prop; } } } } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example // interface Props{ // /*first*/prop1: number // prop2: boolean // } // function Foo(arg: Props) {} // Foo( { pr/*1*/op1: 10, prop2: false }) const element = getContainingObjectLiteralElement(node); if (element) { const contextualType = element && checker.getContextualType(element.parent); if (contextualType) { const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false); if (propertySymbols) { symbol = propertySymbols[0]; } } } } if (symbol && symbol.declarations) { return [new SymbolImportTuple(symbol, importNode)]; } return []; function generateMultipleSymbols(type: ts.UnionType, name: string, importNode: ts.Declaration | null): SymbolImportTuple[] { const result: SymbolImportTuple[] = []; for (const t of type.types) { const prop = t.getProperty(name); if (prop && prop.declarations) { result.push(new SymbolImportTuple(prop, importNode)); } } return result; } } /** Get the token whose text contains the position */ function getTokenAtPosition(ts: typeof import('typescript'), sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeEndPosition: boolean): ts.Node { let current: ts.Node = sourceFile; outer: while (true) { // find the child that contains 'position' for (const child of current.getChildren()) { const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true); if (start > position) { // If this child begins after position, then all subsequent children will as well. break; } const end = child.getEnd(); if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) { current = child; continue outer; } } return current; } } //#endregion ================================================ FILE: build/lib/tsb/builder.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CancellationToken = void 0; exports.createTypeScriptBuilder = createTypeScriptBuilder; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const crypto_1 = __importDefault(require("crypto")); const utils = __importStar(require("./utils")); const ansi_colors_1 = __importDefault(require("ansi-colors")); const typescript_1 = __importDefault(require("typescript")); const vinyl_1 = __importDefault(require("vinyl")); const source_map_1 = require("source-map"); var CancellationToken; (function (CancellationToken) { CancellationToken.None = { isCancellationRequested() { return false; } }; })(CancellationToken || (exports.CancellationToken = CancellationToken = {})); function normalize(path) { return path.replace(/\\/g, '/'); } function createTypeScriptBuilder(config, projectFile, cmd) { const _log = config.logFn; const host = new LanguageServiceHost(cmd, projectFile, _log); const outHost = new LanguageServiceHost({ ...cmd, options: { ...cmd.options, sourceRoot: cmd.options.outDir } }, cmd.options.outDir ?? '', _log); let lastCycleCheckVersion; const service = typescript_1.default.createLanguageService(host, typescript_1.default.createDocumentRegistry()); const lastBuildVersion = Object.create(null); const lastDtsHash = Object.create(null); const userWantsDeclarations = cmd.options.declaration; let oldErrors = Object.create(null); let headUsed = process.memoryUsage().heapUsed; let emitSourceMapsInStream = true; // always emit declaraction files host.getCompilationSettings().declaration = true; function file(file) { // support gulp-sourcemaps if (file.sourceMap) { emitSourceMapsInStream = false; } if (!file.contents) { host.removeScriptSnapshot(file.path); delete lastBuildVersion[normalize(file.path)]; } else { host.addScriptSnapshot(file.path, new VinylScriptSnapshot(file)); } } function baseFor(snapshot) { if (snapshot instanceof VinylScriptSnapshot) { return cmd.options.outDir || snapshot.getBase(); } else { return ''; } } function isExternalModule(sourceFile) { return sourceFile.externalModuleIndicator || /declare\s+module\s+('|")(.+)\1/.test(sourceFile.getText()); } function build(out, onError, token = CancellationToken.None) { function checkSyntaxSoon(fileName) { return new Promise(resolve => { process.nextTick(function () { if (!host.getScriptSnapshot(fileName, false)) { resolve([]); // no script, no problems } else { resolve(service.getSyntacticDiagnostics(fileName)); } }); }); } function checkSemanticsSoon(fileName) { return new Promise(resolve => { process.nextTick(function () { if (!host.getScriptSnapshot(fileName, false)) { resolve([]); // no script, no problems } else { resolve(service.getSemanticDiagnostics(fileName)); } }); }); } function emitSoon(fileName) { return new Promise(resolve => { process.nextTick(function () { if (/\.d\.ts$/.test(fileName)) { // if it's already a d.ts file just emit it signature const snapshot = host.getScriptSnapshot(fileName); const signature = crypto_1.default.createHash('sha256') .update(snapshot.getText(0, snapshot.getLength())) .digest('base64'); return resolve({ fileName, signature, files: [] }); } const output = service.getEmitOutput(fileName); const files = []; let signature; for (const file of output.outputFiles) { if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) { continue; } if (/\.d\.ts$/.test(file.name)) { signature = crypto_1.default.createHash('sha256') .update(file.text) .digest('base64'); if (!userWantsDeclarations) { // don't leak .d.ts files if users don't want them continue; } } const vinyl = new vinyl_1.default({ path: file.name, contents: Buffer.from(file.text), base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined }); if (!emitSourceMapsInStream && /\.js$/.test(file.name)) { const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; if (sourcemapFile) { const extname = path_1.default.extname(vinyl.relative); const basename = path_1.default.basename(vinyl.relative, extname); const dirname = path_1.default.dirname(vinyl.relative); const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; let sourceMap = JSON.parse(sourcemapFile.text); sourceMap.sources[0] = tsname.replace(/\\/g, '/'); // check for an "input source" map and combine them // in step 1 we extract all line edit from the input source map, and // in step 2 we apply the line edits to the typescript source map const snapshot = host.getScriptSnapshot(fileName); if (snapshot instanceof VinylScriptSnapshot && snapshot.sourceMap) { const inputSMC = new source_map_1.SourceMapConsumer(snapshot.sourceMap); const tsSMC = new source_map_1.SourceMapConsumer(sourceMap); let didChange = false; const smg = new source_map_1.SourceMapGenerator({ file: sourceMap.file, sourceRoot: sourceMap.sourceRoot }); // step 1 const lineEdits = new Map(); inputSMC.eachMapping(m => { if (m.originalLine === m.generatedLine) { // same line mapping let array = lineEdits.get(m.originalLine); if (!array) { array = []; lineEdits.set(m.originalLine, array); } array.push([m.originalColumn, m.generatedColumn]); } else { // NOT SUPPORTED } }); // step 2 tsSMC.eachMapping(m => { didChange = true; const edits = lineEdits.get(m.originalLine); let originalColumnDelta = 0; if (edits) { for (const [from, to] of edits) { if (to >= m.originalColumn) { break; } originalColumnDelta = from - to; } } smg.addMapping({ source: m.source, name: m.name, generated: { line: m.generatedLine, column: m.generatedColumn }, original: { line: m.originalLine, column: m.originalColumn + originalColumnDelta } }); }); if (didChange) { [tsSMC, inputSMC].forEach((consumer) => { consumer.sources.forEach((sourceFile) => { smg._sources.add(sourceFile); const sourceContent = consumer.sourceContentFor(sourceFile); if (sourceContent !== null) { smg.setSourceContent(sourceFile, sourceContent); } }); }); sourceMap = JSON.parse(smg.toString()); // const filename = '/Users/jrieken/Code/vscode/src2/' + vinyl.relative + '.map'; // fs.promises.mkdir(path.dirname(filename), { recursive: true }).then(async () => { // await fs.promises.writeFile(filename, smg.toString()); // await fs.promises.writeFile('/Users/jrieken/Code/vscode/src2/' + vinyl.relative, vinyl.contents); // }); } } vinyl.sourceMap = sourceMap; } } files.push(vinyl); } resolve({ fileName, signature, files }); }); }); } const newErrors = Object.create(null); const t1 = Date.now(); const toBeEmitted = []; const toBeCheckedSyntactically = []; const toBeCheckedSemantically = []; const filesWithChangedSignature = []; const dependentFiles = []; const newLastBuildVersion = new Map(); for (const fileName of host.getScriptFileNames()) { if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { toBeEmitted.push(fileName); toBeCheckedSyntactically.push(fileName); toBeCheckedSemantically.push(fileName); } } return new Promise(resolve => { const semanticCheckInfo = new Map(); const seenAsDependentFile = new Set(); function workOnNext() { let promise; // let fileName: string; // someone told us to stop this if (token.isCancellationRequested()) { _log('[CANCEL]', '>>This compile run was cancelled<<'); newLastBuildVersion.clear(); resolve(); return; } // (1st) emit code else if (toBeEmitted.length) { const fileName = toBeEmitted.pop(); promise = emitSoon(fileName).then(value => { for (const file of value.files) { _log('[emit code]', file.path); out(file); } // remember when this was build newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); // remeber the signature if (value.signature && lastDtsHash[fileName] !== value.signature) { lastDtsHash[fileName] = value.signature; filesWithChangedSignature.push(fileName); } // line up for cycle check const jsValue = value.files.find(candidate => candidate.basename.endsWith('.js')); if (jsValue) { outHost.addScriptSnapshot(jsValue.path, new ScriptSnapshot(String(jsValue.contents), new Date())); } }).catch(e => { // can't just skip this or make a result up.. host.error(`ERROR emitting ${fileName}`); host.error(e); }); } // (2nd) check syntax else if (toBeCheckedSyntactically.length) { const fileName = toBeCheckedSyntactically.pop(); _log('[check syntax]', fileName); promise = checkSyntaxSoon(fileName).then(diagnostics => { delete oldErrors[fileName]; if (diagnostics.length > 0) { diagnostics.forEach(d => onError(d)); newErrors[fileName] = diagnostics; // stop the world when there are syntax errors toBeCheckedSyntactically.length = 0; toBeCheckedSemantically.length = 0; filesWithChangedSignature.length = 0; } }); } // (3rd) check semantics else if (toBeCheckedSemantically.length) { let fileName = toBeCheckedSemantically.pop(); while (fileName && semanticCheckInfo.has(fileName)) { fileName = toBeCheckedSemantically.pop(); } if (fileName) { _log('[check semantics]', fileName); promise = checkSemanticsSoon(fileName).then(diagnostics => { delete oldErrors[fileName]; semanticCheckInfo.set(fileName, diagnostics.length); if (diagnostics.length > 0) { diagnostics.forEach(d => onError(d)); newErrors[fileName] = diagnostics; } }); } } // (4th) check dependents else if (filesWithChangedSignature.length) { while (filesWithChangedSignature.length) { const fileName = filesWithChangedSignature.pop(); if (!isExternalModule(service.getProgram().getSourceFile(fileName))) { _log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet'); toBeCheckedSemantically.push(...host.getScriptFileNames()); filesWithChangedSignature.length = 0; dependentFiles.length = 0; break; } host.collectDependents(fileName, dependentFiles); } } // (5th) dependents contd else if (dependentFiles.length) { let fileName = dependentFiles.pop(); while (fileName && seenAsDependentFile.has(fileName)) { fileName = dependentFiles.pop(); } if (fileName) { seenAsDependentFile.add(fileName); const value = semanticCheckInfo.get(fileName); if (value === 0) { // already validated successfully -> look at dependents next host.collectDependents(fileName, dependentFiles); } else if (typeof value === 'undefined') { // first validate -> look at dependents next dependentFiles.push(fileName); toBeCheckedSemantically.push(fileName); } } } // (last) done else { resolve(); return; } if (!promise) { promise = Promise.resolve(); } promise.then(function () { // change to change process.nextTick(workOnNext); }).catch(err => { console.error(err); }); } workOnNext(); }).then(() => { // check for cyclic dependencies const thisCycleCheckVersion = outHost.getProjectVersion(); if (thisCycleCheckVersion === lastCycleCheckVersion) { return; } const oneCycle = outHost.hasCyclicDependency(); lastCycleCheckVersion = thisCycleCheckVersion; delete oldErrors[projectFile]; if (oneCycle) { const cycleError = { category: typescript_1.default.DiagnosticCategory.Error, code: 1, file: undefined, start: undefined, length: undefined, messageText: `CYCLIC dependency between ${oneCycle}` }; onError(cycleError); newErrors[projectFile] = [cycleError]; } }).then(() => { // store the build versions to not rebuilt the next time newLastBuildVersion.forEach((value, key) => { lastBuildVersion[key] = value; }); // print old errors and keep them for (const [key, value] of Object.entries(oldErrors)) { value.forEach(diag => onError(diag)); newErrors[key] = value; } oldErrors = newErrors; // print stats const headNow = process.memoryUsage().heapUsed; const MB = 1024 * 1024; _log('[tsb]', `time: ${ansi_colors_1.default.yellow((Date.now() - t1) + 'ms')} + \nmem: ${ansi_colors_1.default.cyan(Math.ceil(headNow / MB) + 'MB')} ${ansi_colors_1.default.bgcyan('delta: ' + Math.ceil((headNow - headUsed) / MB))}`); headUsed = headNow; }); } return { file, build, languageService: service }; } class ScriptSnapshot { _text; _mtime; constructor(text, mtime) { this._text = text; this._mtime = mtime; } getVersion() { return this._mtime.toUTCString(); } getText(start, end) { return this._text.substring(start, end); } getLength() { return this._text.length; } getChangeRange(_oldSnapshot) { return undefined; } } class VinylScriptSnapshot extends ScriptSnapshot { _base; sourceMap; constructor(file) { super(file.contents.toString(), file.stat.mtime); this._base = file.base; this.sourceMap = file.sourceMap; } getBase() { return this._base; } } class LanguageServiceHost { _cmdLine; _projectPath; _log; _snapshots; _filesInProject; _filesAdded; _dependencies; _dependenciesRecomputeList; _fileNameToDeclaredModule; _projectVersion; constructor(_cmdLine, _projectPath, _log) { this._cmdLine = _cmdLine; this._projectPath = _projectPath; this._log = _log; this._snapshots = Object.create(null); this._filesInProject = new Set(_cmdLine.fileNames); this._filesAdded = new Set(); this._dependencies = new utils.graph.Graph(); this._dependenciesRecomputeList = []; this._fileNameToDeclaredModule = Object.create(null); this._projectVersion = 1; } log(_s) { // console.log(s); } trace(_s) { // console.log(s); } error(s) { console.error(s); } getCompilationSettings() { return this._cmdLine.options; } getProjectVersion() { return String(this._projectVersion); } getScriptFileNames() { const res = Object.keys(this._snapshots).filter(path => this._filesInProject.has(path) || this._filesAdded.has(path)); return res; } getScriptVersion(filename) { filename = normalize(filename); const result = this._snapshots[filename]; if (result) { return result.getVersion(); } return 'UNKNWON_FILE_' + Math.random().toString(16).slice(2); } getScriptSnapshot(filename, resolve = true) { filename = normalize(filename); let result = this._snapshots[filename]; if (!result && resolve) { try { result = new VinylScriptSnapshot(new vinyl_1.default({ path: filename, contents: fs_1.default.readFileSync(filename), base: this.getCompilationSettings().outDir, stat: fs_1.default.statSync(filename) })); this.addScriptSnapshot(filename, result); } catch (e) { // ignore } } return result; } static _declareModule = /declare\s+module\s+('|")(.+)\1/g; addScriptSnapshot(filename, snapshot) { this._projectVersion++; filename = normalize(filename); const old = this._snapshots[filename]; if (!old && !this._filesInProject.has(filename) && !filename.endsWith('.d.ts')) { // ^^^^^^^^^^^^^^^^^^^^^^^^^^ // not very proper! this._filesAdded.add(filename); } if (!old || old.getVersion() !== snapshot.getVersion()) { this._dependenciesRecomputeList.push(filename); // (cheap) check for declare module LanguageServiceHost._declareModule.lastIndex = 0; let match; while ((match = LanguageServiceHost._declareModule.exec(snapshot.getText(0, snapshot.getLength())))) { let declaredModules = this._fileNameToDeclaredModule[filename]; if (!declaredModules) { this._fileNameToDeclaredModule[filename] = declaredModules = []; } declaredModules.push(match[2]); } } this._snapshots[filename] = snapshot; return old; } removeScriptSnapshot(filename) { this._filesInProject.delete(filename); this._filesAdded.delete(filename); this._projectVersion++; filename = normalize(filename); delete this._fileNameToDeclaredModule[filename]; return delete this._snapshots[filename]; } getCurrentDirectory() { return path_1.default.dirname(this._projectPath); } getDefaultLibFileName(options) { return typescript_1.default.getDefaultLibFilePath(options); } directoryExists = typescript_1.default.sys.directoryExists; getDirectories = typescript_1.default.sys.getDirectories; fileExists = typescript_1.default.sys.fileExists; readFile = typescript_1.default.sys.readFile; readDirectory = typescript_1.default.sys.readDirectory; // ---- dependency management collectDependents(filename, target) { while (this._dependenciesRecomputeList.length) { this._processFile(this._dependenciesRecomputeList.pop()); } filename = normalize(filename); const node = this._dependencies.lookup(filename); if (node) { node.incoming.forEach(entry => target.push(entry.data)); } } hasCyclicDependency() { // Ensure dependencies are up to date while (this._dependenciesRecomputeList.length) { this._processFile(this._dependenciesRecomputeList.pop()); } const cycle = this._dependencies.findCycle(); return cycle ? cycle.join(' -> ') : undefined; } _processFile(filename) { if (filename.match(/.*\.d\.ts$/)) { return; } filename = normalize(filename); const snapshot = this.getScriptSnapshot(filename); if (!snapshot) { this._log('processFile', `Missing snapshot for: ${filename}`); return; } const info = typescript_1.default.preProcessFile(snapshot.getText(0, snapshot.getLength()), true); // (0) clear out old dependencies this._dependencies.resetNode(filename); // (1) ///-references info.referencedFiles.forEach(ref => { const resolvedPath = path_1.default.resolve(path_1.default.dirname(filename), ref.fileName); const normalizedPath = normalize(resolvedPath); this._dependencies.inertEdge(filename, normalizedPath); }); // (2) import-require statements info.importedFiles.forEach(ref => { if (!ref.fileName.startsWith('.')) { // node module? return; } const stopDirname = normalize(this.getCurrentDirectory()); let dirname = filename; let found = false; while (!found && dirname.indexOf(stopDirname) === 0) { dirname = path_1.default.dirname(dirname); let resolvedPath = path_1.default.resolve(dirname, ref.fileName); if (resolvedPath.endsWith('.js')) { resolvedPath = resolvedPath.slice(0, -3); } const normalizedPath = normalize(resolvedPath); if (this.getScriptSnapshot(normalizedPath + '.ts')) { this._dependencies.inertEdge(filename, normalizedPath + '.ts'); found = true; } else if (this.getScriptSnapshot(normalizedPath + '.d.ts')) { this._dependencies.inertEdge(filename, normalizedPath + '.d.ts'); found = true; } else if (this.getScriptSnapshot(normalizedPath + '.js')) { this._dependencies.inertEdge(filename, normalizedPath + '.js'); found = true; } } if (!found) { for (const key in this._fileNameToDeclaredModule) { if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) { this._dependencies.inertEdge(filename, key); } } } }); } } //# sourceMappingURL=builder.js.map ================================================ FILE: build/lib/tsb/builder.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; import * as utils from './utils'; import colors from 'ansi-colors'; import ts from 'typescript'; import Vinyl from 'vinyl'; import { RawSourceMap, SourceMapConsumer, SourceMapGenerator } from 'source-map'; export interface IConfiguration { logFn: (topic: string, message: string) => void; _emitWithoutBasePath?: boolean; } export interface CancellationToken { isCancellationRequested(): boolean; } export namespace CancellationToken { export const None: CancellationToken = { isCancellationRequested() { return false; } }; } export interface ITypeScriptBuilder { build(out: (file: Vinyl) => void, onError: (err: ts.Diagnostic) => void, token?: CancellationToken): Promise; file(file: Vinyl): void; languageService: ts.LanguageService; } function normalize(path: string): string { return path.replace(/\\/g, '/'); } export function createTypeScriptBuilder(config: IConfiguration, projectFile: string, cmd: ts.ParsedCommandLine): ITypeScriptBuilder { const _log = config.logFn; const host = new LanguageServiceHost(cmd, projectFile, _log); const outHost = new LanguageServiceHost({ ...cmd, options: { ...cmd.options, sourceRoot: cmd.options.outDir } }, cmd.options.outDir ?? '', _log); let lastCycleCheckVersion: string; const service = ts.createLanguageService(host, ts.createDocumentRegistry()); const lastBuildVersion: { [path: string]: string } = Object.create(null); const lastDtsHash: { [path: string]: string } = Object.create(null); const userWantsDeclarations = cmd.options.declaration; let oldErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); let headUsed = process.memoryUsage().heapUsed; let emitSourceMapsInStream = true; // always emit declaraction files host.getCompilationSettings().declaration = true; function file(file: Vinyl): void { // support gulp-sourcemaps if ((file).sourceMap) { emitSourceMapsInStream = false; } if (!file.contents) { host.removeScriptSnapshot(file.path); delete lastBuildVersion[normalize(file.path)]; } else { host.addScriptSnapshot(file.path, new VinylScriptSnapshot(file)); } } function baseFor(snapshot: ScriptSnapshot): string { if (snapshot instanceof VinylScriptSnapshot) { return cmd.options.outDir || snapshot.getBase(); } else { return ''; } } function isExternalModule(sourceFile: ts.SourceFile): boolean { return (sourceFile).externalModuleIndicator || /declare\s+module\s+('|")(.+)\1/.test(sourceFile.getText()); } function build(out: (file: Vinyl) => void, onError: (err: any) => void, token = CancellationToken.None): Promise { function checkSyntaxSoon(fileName: string): Promise { return new Promise(resolve => { process.nextTick(function () { if (!host.getScriptSnapshot(fileName, false)) { resolve([]); // no script, no problems } else { resolve(service.getSyntacticDiagnostics(fileName)); } }); }); } function checkSemanticsSoon(fileName: string): Promise { return new Promise(resolve => { process.nextTick(function () { if (!host.getScriptSnapshot(fileName, false)) { resolve([]); // no script, no problems } else { resolve(service.getSemanticDiagnostics(fileName)); } }); }); } function emitSoon(fileName: string): Promise<{ fileName: string; signature?: string; files: Vinyl[] }> { return new Promise(resolve => { process.nextTick(function () { if (/\.d\.ts$/.test(fileName)) { // if it's already a d.ts file just emit it signature const snapshot = host.getScriptSnapshot(fileName); const signature = crypto.createHash('sha256') .update(snapshot.getText(0, snapshot.getLength())) .digest('base64'); return resolve({ fileName, signature, files: [] }); } const output = service.getEmitOutput(fileName); const files: Vinyl[] = []; let signature: string | undefined; for (const file of output.outputFiles) { if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) { continue; } if (/\.d\.ts$/.test(file.name)) { signature = crypto.createHash('sha256') .update(file.text) .digest('base64'); if (!userWantsDeclarations) { // don't leak .d.ts files if users don't want them continue; } } const vinyl = new Vinyl({ path: file.name, contents: Buffer.from(file.text), base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined }); if (!emitSourceMapsInStream && /\.js$/.test(file.name)) { const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; if (sourcemapFile) { const extname = path.extname(vinyl.relative); const basename = path.basename(vinyl.relative, extname); const dirname = path.dirname(vinyl.relative); const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; let sourceMap = JSON.parse(sourcemapFile.text); sourceMap.sources[0] = tsname.replace(/\\/g, '/'); // check for an "input source" map and combine them // in step 1 we extract all line edit from the input source map, and // in step 2 we apply the line edits to the typescript source map const snapshot = host.getScriptSnapshot(fileName); if (snapshot instanceof VinylScriptSnapshot && snapshot.sourceMap) { const inputSMC = new SourceMapConsumer(snapshot.sourceMap); const tsSMC = new SourceMapConsumer(sourceMap); let didChange = false; const smg = new SourceMapGenerator({ file: sourceMap.file, sourceRoot: sourceMap.sourceRoot }); // step 1 const lineEdits = new Map(); inputSMC.eachMapping(m => { if (m.originalLine === m.generatedLine) { // same line mapping let array = lineEdits.get(m.originalLine); if (!array) { array = []; lineEdits.set(m.originalLine, array); } array.push([m.originalColumn, m.generatedColumn]); } else { // NOT SUPPORTED } }); // step 2 tsSMC.eachMapping(m => { didChange = true; const edits = lineEdits.get(m.originalLine); let originalColumnDelta = 0; if (edits) { for (const [from, to] of edits) { if (to >= m.originalColumn) { break; } originalColumnDelta = from - to; } } smg.addMapping({ source: m.source, name: m.name, generated: { line: m.generatedLine, column: m.generatedColumn }, original: { line: m.originalLine, column: m.originalColumn + originalColumnDelta } }); }); if (didChange) { [tsSMC, inputSMC].forEach((consumer) => { (consumer).sources.forEach((sourceFile: any) => { (smg)._sources.add(sourceFile); const sourceContent = consumer.sourceContentFor(sourceFile); if (sourceContent !== null) { smg.setSourceContent(sourceFile, sourceContent); } }); }); sourceMap = JSON.parse(smg.toString()); // const filename = '/Users/jrieken/Code/vscode/src2/' + vinyl.relative + '.map'; // fs.promises.mkdir(path.dirname(filename), { recursive: true }).then(async () => { // await fs.promises.writeFile(filename, smg.toString()); // await fs.promises.writeFile('/Users/jrieken/Code/vscode/src2/' + vinyl.relative, vinyl.contents); // }); } } (vinyl).sourceMap = sourceMap; } } files.push(vinyl); } resolve({ fileName, signature, files }); }); }); } const newErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); const t1 = Date.now(); const toBeEmitted: string[] = []; const toBeCheckedSyntactically: string[] = []; const toBeCheckedSemantically: string[] = []; const filesWithChangedSignature: string[] = []; const dependentFiles: string[] = []; const newLastBuildVersion = new Map(); for (const fileName of host.getScriptFileNames()) { if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { toBeEmitted.push(fileName); toBeCheckedSyntactically.push(fileName); toBeCheckedSemantically.push(fileName); } } return new Promise(resolve => { const semanticCheckInfo = new Map(); const seenAsDependentFile = new Set(); function workOnNext() { let promise: Promise | undefined; // let fileName: string; // someone told us to stop this if (token.isCancellationRequested()) { _log('[CANCEL]', '>>This compile run was cancelled<<'); newLastBuildVersion.clear(); resolve(); return; } // (1st) emit code else if (toBeEmitted.length) { const fileName = toBeEmitted.pop()!; promise = emitSoon(fileName).then(value => { for (const file of value.files) { _log('[emit code]', file.path); out(file); } // remember when this was build newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); // remeber the signature if (value.signature && lastDtsHash[fileName] !== value.signature) { lastDtsHash[fileName] = value.signature; filesWithChangedSignature.push(fileName); } // line up for cycle check const jsValue = value.files.find(candidate => candidate.basename.endsWith('.js')); if (jsValue) { outHost.addScriptSnapshot(jsValue.path, new ScriptSnapshot(String(jsValue.contents), new Date())); } }).catch(e => { // can't just skip this or make a result up.. host.error(`ERROR emitting ${fileName}`); host.error(e); }); } // (2nd) check syntax else if (toBeCheckedSyntactically.length) { const fileName = toBeCheckedSyntactically.pop()!; _log('[check syntax]', fileName); promise = checkSyntaxSoon(fileName).then(diagnostics => { delete oldErrors[fileName]; if (diagnostics.length > 0) { diagnostics.forEach(d => onError(d)); newErrors[fileName] = diagnostics; // stop the world when there are syntax errors toBeCheckedSyntactically.length = 0; toBeCheckedSemantically.length = 0; filesWithChangedSignature.length = 0; } }); } // (3rd) check semantics else if (toBeCheckedSemantically.length) { let fileName = toBeCheckedSemantically.pop(); while (fileName && semanticCheckInfo.has(fileName)) { fileName = toBeCheckedSemantically.pop()!; } if (fileName) { _log('[check semantics]', fileName); promise = checkSemanticsSoon(fileName).then(diagnostics => { delete oldErrors[fileName!]; semanticCheckInfo.set(fileName!, diagnostics.length); if (diagnostics.length > 0) { diagnostics.forEach(d => onError(d)); newErrors[fileName!] = diagnostics; } }); } } // (4th) check dependents else if (filesWithChangedSignature.length) { while (filesWithChangedSignature.length) { const fileName = filesWithChangedSignature.pop()!; if (!isExternalModule(service.getProgram()!.getSourceFile(fileName)!)) { _log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet'); toBeCheckedSemantically.push(...host.getScriptFileNames()); filesWithChangedSignature.length = 0; dependentFiles.length = 0; break; } host.collectDependents(fileName, dependentFiles); } } // (5th) dependents contd else if (dependentFiles.length) { let fileName = dependentFiles.pop(); while (fileName && seenAsDependentFile.has(fileName)) { fileName = dependentFiles.pop(); } if (fileName) { seenAsDependentFile.add(fileName); const value = semanticCheckInfo.get(fileName); if (value === 0) { // already validated successfully -> look at dependents next host.collectDependents(fileName, dependentFiles); } else if (typeof value === 'undefined') { // first validate -> look at dependents next dependentFiles.push(fileName); toBeCheckedSemantically.push(fileName); } } } // (last) done else { resolve(); return; } if (!promise) { promise = Promise.resolve(); } promise.then(function () { // change to change process.nextTick(workOnNext); }).catch(err => { console.error(err); }); } workOnNext(); }).then(() => { // check for cyclic dependencies const thisCycleCheckVersion = outHost.getProjectVersion(); if (thisCycleCheckVersion === lastCycleCheckVersion) { return; } const oneCycle = outHost.hasCyclicDependency(); lastCycleCheckVersion = thisCycleCheckVersion; delete oldErrors[projectFile]; if (oneCycle) { const cycleError: ts.Diagnostic = { category: ts.DiagnosticCategory.Error, code: 1, file: undefined, start: undefined, length: undefined, messageText: `CYCLIC dependency between ${oneCycle}` }; onError(cycleError); newErrors[projectFile] = [cycleError]; } }).then(() => { // store the build versions to not rebuilt the next time newLastBuildVersion.forEach((value, key) => { lastBuildVersion[key] = value; }); // print old errors and keep them for (const [key, value] of Object.entries(oldErrors)) { value.forEach(diag => onError(diag)); newErrors[key] = value; } oldErrors = newErrors; // print stats const headNow = process.memoryUsage().heapUsed; const MB = 1024 * 1024; _log( '[tsb]', `time: ${colors.yellow((Date.now() - t1) + 'ms')} + \nmem: ${colors.cyan(Math.ceil(headNow / MB) + 'MB')} ${colors.bgcyan('delta: ' + Math.ceil((headNow - headUsed) / MB))}` ); headUsed = headNow; }); } return { file, build, languageService: service }; } class ScriptSnapshot implements ts.IScriptSnapshot { private readonly _text: string; private readonly _mtime: Date; constructor(text: string, mtime: Date) { this._text = text; this._mtime = mtime; } getVersion(): string { return this._mtime.toUTCString(); } getText(start: number, end: number): string { return this._text.substring(start, end); } getLength(): number { return this._text.length; } getChangeRange(_oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange | undefined { return undefined; } } class VinylScriptSnapshot extends ScriptSnapshot { private readonly _base: string; readonly sourceMap?: RawSourceMap; constructor(file: Vinyl & { sourceMap?: RawSourceMap }) { super(file.contents!.toString(), file.stat!.mtime); this._base = file.base; this.sourceMap = file.sourceMap; } getBase(): string { return this._base; } } class LanguageServiceHost implements ts.LanguageServiceHost { private readonly _snapshots: { [path: string]: ScriptSnapshot }; private readonly _filesInProject: Set; private readonly _filesAdded: Set; private readonly _dependencies: utils.graph.Graph; private readonly _dependenciesRecomputeList: string[]; private readonly _fileNameToDeclaredModule: { [path: string]: string[] }; private _projectVersion: number; constructor( private readonly _cmdLine: ts.ParsedCommandLine, private readonly _projectPath: string, private readonly _log: (topic: string, message: string) => void ) { this._snapshots = Object.create(null); this._filesInProject = new Set(_cmdLine.fileNames); this._filesAdded = new Set(); this._dependencies = new utils.graph.Graph(); this._dependenciesRecomputeList = []; this._fileNameToDeclaredModule = Object.create(null); this._projectVersion = 1; } log(_s: string): void { // console.log(s); } trace(_s: string): void { // console.log(s); } error(s: string): void { console.error(s); } getCompilationSettings(): ts.CompilerOptions { return this._cmdLine.options; } getProjectVersion(): string { return String(this._projectVersion); } getScriptFileNames(): string[] { const res = Object.keys(this._snapshots).filter(path => this._filesInProject.has(path) || this._filesAdded.has(path)); return res; } getScriptVersion(filename: string): string { filename = normalize(filename); const result = this._snapshots[filename]; if (result) { return result.getVersion(); } return 'UNKNWON_FILE_' + Math.random().toString(16).slice(2); } getScriptSnapshot(filename: string, resolve: boolean = true): ScriptSnapshot { filename = normalize(filename); let result = this._snapshots[filename]; if (!result && resolve) { try { result = new VinylScriptSnapshot(new Vinyl({ path: filename, contents: fs.readFileSync(filename), base: this.getCompilationSettings().outDir, stat: fs.statSync(filename) })); this.addScriptSnapshot(filename, result); } catch (e) { // ignore } } return result; } private static _declareModule = /declare\s+module\s+('|")(.+)\1/g; addScriptSnapshot(filename: string, snapshot: ScriptSnapshot): ScriptSnapshot { this._projectVersion++; filename = normalize(filename); const old = this._snapshots[filename]; if (!old && !this._filesInProject.has(filename) && !filename.endsWith('.d.ts')) { // ^^^^^^^^^^^^^^^^^^^^^^^^^^ // not very proper! this._filesAdded.add(filename); } if (!old || old.getVersion() !== snapshot.getVersion()) { this._dependenciesRecomputeList.push(filename); // (cheap) check for declare module LanguageServiceHost._declareModule.lastIndex = 0; let match: RegExpExecArray | null | undefined; while ((match = LanguageServiceHost._declareModule.exec(snapshot.getText(0, snapshot.getLength())))) { let declaredModules = this._fileNameToDeclaredModule[filename]; if (!declaredModules) { this._fileNameToDeclaredModule[filename] = declaredModules = []; } declaredModules.push(match[2]); } } this._snapshots[filename] = snapshot; return old; } removeScriptSnapshot(filename: string): boolean { this._filesInProject.delete(filename); this._filesAdded.delete(filename); this._projectVersion++; filename = normalize(filename); delete this._fileNameToDeclaredModule[filename]; return delete this._snapshots[filename]; } getCurrentDirectory(): string { return path.dirname(this._projectPath); } getDefaultLibFileName(options: ts.CompilerOptions): string { return ts.getDefaultLibFilePath(options); } readonly directoryExists = ts.sys.directoryExists; readonly getDirectories = ts.sys.getDirectories; readonly fileExists = ts.sys.fileExists; readonly readFile = ts.sys.readFile; readonly readDirectory = ts.sys.readDirectory; // ---- dependency management collectDependents(filename: string, target: string[]): void { while (this._dependenciesRecomputeList.length) { this._processFile(this._dependenciesRecomputeList.pop()!); } filename = normalize(filename); const node = this._dependencies.lookup(filename); if (node) { node.incoming.forEach(entry => target.push(entry.data)); } } hasCyclicDependency(): string | undefined { // Ensure dependencies are up to date while (this._dependenciesRecomputeList.length) { this._processFile(this._dependenciesRecomputeList.pop()!); } const cycle = this._dependencies.findCycle(); return cycle ? cycle.join(' -> ') : undefined; } _processFile(filename: string): void { if (filename.match(/.*\.d\.ts$/)) { return; } filename = normalize(filename); const snapshot = this.getScriptSnapshot(filename); if (!snapshot) { this._log('processFile', `Missing snapshot for: ${filename}`); return; } const info = ts.preProcessFile(snapshot.getText(0, snapshot.getLength()), true); // (0) clear out old dependencies this._dependencies.resetNode(filename); // (1) ///-references info.referencedFiles.forEach(ref => { const resolvedPath = path.resolve(path.dirname(filename), ref.fileName); const normalizedPath = normalize(resolvedPath); this._dependencies.inertEdge(filename, normalizedPath); }); // (2) import-require statements info.importedFiles.forEach(ref => { if (!ref.fileName.startsWith('.')) { // node module? return; } const stopDirname = normalize(this.getCurrentDirectory()); let dirname = filename; let found = false; while (!found && dirname.indexOf(stopDirname) === 0) { dirname = path.dirname(dirname); let resolvedPath = path.resolve(dirname, ref.fileName); if (resolvedPath.endsWith('.js')) { resolvedPath = resolvedPath.slice(0, -3); } const normalizedPath = normalize(resolvedPath); if (this.getScriptSnapshot(normalizedPath + '.ts')) { this._dependencies.inertEdge(filename, normalizedPath + '.ts'); found = true; } else if (this.getScriptSnapshot(normalizedPath + '.d.ts')) { this._dependencies.inertEdge(filename, normalizedPath + '.d.ts'); found = true; } else if (this.getScriptSnapshot(normalizedPath + '.js')) { this._dependencies.inertEdge(filename, normalizedPath + '.js'); found = true; } } if (!found) { for (const key in this._fileNameToDeclaredModule) { if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) { this._dependencies.inertEdge(filename, key); } } } }); } } ================================================ FILE: build/lib/tsb/index.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; const vinyl_1 = __importDefault(require("vinyl")); const through_1 = __importDefault(require("through")); const builder = __importStar(require("./builder")); const typescript_1 = __importDefault(require("typescript")); const stream_1 = require("stream"); const path_1 = require("path"); const utils_1 = require("./utils"); const fs_1 = require("fs"); const fancy_log_1 = __importDefault(require("fancy-log")); const transpiler_1 = require("./transpiler"); const colors = require("ansi-colors"); class EmptyDuplex extends stream_1.Duplex { _write(_chunk, _encoding, callback) { callback(); } _read() { this.push(null); } } function createNullCompiler() { const result = function () { return new EmptyDuplex(); }; result.src = () => new EmptyDuplex(); return result; } const _defaultOnError = (err) => console.log(JSON.stringify(err, null, 4)); function create(projectPath, existingOptions, config, onError = _defaultOnError) { function printDiagnostic(diag) { if (diag instanceof Error) { onError(diag.message); } else if (!diag.file || !diag.start) { onError(typescript_1.default.flattenDiagnosticMessageText(diag.messageText, '\n')); } else { const lineAndCh = diag.file.getLineAndCharacterOfPosition(diag.start); onError(utils_1.strings.format('{0}({1},{2}): {3}', diag.file.fileName, lineAndCh.line + 1, lineAndCh.character + 1, typescript_1.default.flattenDiagnosticMessageText(diag.messageText, '\n'))); } } const parsed = typescript_1.default.readConfigFile(projectPath, typescript_1.default.sys.readFile); if (parsed.error) { printDiagnostic(parsed.error); return createNullCompiler(); } const cmdLine = typescript_1.default.parseJsonConfigFileContent(parsed.config, typescript_1.default.sys, (0, path_1.dirname)(projectPath), existingOptions); if (cmdLine.errors.length > 0) { cmdLine.errors.forEach(printDiagnostic); return createNullCompiler(); } function logFn(topic, message) { if (config.verbose) { (0, fancy_log_1.default)(colors.cyan(topic), message); } } // FULL COMPILE stream doing transpile, syntax and semantic diagnostics function createCompileStream(builder, token) { return (0, through_1.default)(function (file) { // give the file to the compiler if (file.isStream()) { this.emit('error', 'no support for streams'); return; } builder.file(file); }, function () { // start the compilation process builder.build(file => this.queue(file), printDiagnostic, token).catch(e => console.error(e)).then(() => this.queue(null)); }); } // TRANSPILE ONLY stream doing just TS to JS conversion function createTranspileStream(transpiler) { return (0, through_1.default)(function (file) { // give the file to the compiler if (file.isStream()) { this.emit('error', 'no support for streams'); return; } if (!file.contents) { return; } if (!config.transpileOnlyIncludesDts && file.path.endsWith('.d.ts')) { return; } if (!transpiler.onOutfile) { transpiler.onOutfile = file => this.queue(file); } transpiler.transpile(file); }, function () { transpiler.join().then(() => { this.queue(null); transpiler.onOutfile = undefined; }); }); } let result; if (config.transpileOnly) { const transpiler = !config.transpileWithSwc ? new transpiler_1.TscTranspiler(logFn, printDiagnostic, projectPath, cmdLine) : new transpiler_1.ESBuildTranspiler(logFn, printDiagnostic, projectPath, cmdLine); result = (() => createTranspileStream(transpiler)); } else { const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine); result = ((token) => createCompileStream(_builder, token)); } result.src = (opts) => { let _pos = 0; const _fileNames = cmdLine.fileNames.slice(0); return new class extends stream_1.Readable { constructor() { super({ objectMode: true }); } _read() { let more = true; let path; for (; more && _pos < _fileNames.length; _pos++) { path = _fileNames[_pos]; more = this.push(new vinyl_1.default({ path, contents: (0, fs_1.readFileSync)(path), stat: (0, fs_1.statSync)(path), cwd: opts && opts.cwd, base: opts && opts.base || (0, path_1.dirname)(projectPath) })); } if (_pos >= _fileNames.length) { this.push(null); } } }; }; return result; } //# sourceMappingURL=index.js.map ================================================ FILE: build/lib/tsb/index.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import Vinyl from 'vinyl'; import through from 'through'; import * as builder from './builder'; import ts from 'typescript'; import { Readable, Writable, Duplex } from 'stream'; import { dirname } from 'path'; import { strings } from './utils'; import { readFileSync, statSync } from 'fs'; import log from 'fancy-log'; import { ESBuildTranspiler, ITranspiler, TscTranspiler } from './transpiler'; import colors = require('ansi-colors'); export interface IncrementalCompiler { (token?: any): Readable & Writable; src(opts?: { cwd?: string; base?: string }): Readable; } class EmptyDuplex extends Duplex { _write(_chunk: any, _encoding: string, callback: (err?: Error) => void): void { callback(); } _read() { this.push(null); } } function createNullCompiler(): IncrementalCompiler { const result: IncrementalCompiler = function () { return new EmptyDuplex(); }; result.src = () => new EmptyDuplex(); return result; } const _defaultOnError = (err: string) => console.log(JSON.stringify(err, null, 4)); export function create( projectPath: string, existingOptions: Partial, config: { verbose?: boolean; transpileOnly?: boolean; transpileOnlyIncludesDts?: boolean; transpileWithSwc?: boolean }, onError: (message: string) => void = _defaultOnError ): IncrementalCompiler { function printDiagnostic(diag: ts.Diagnostic | Error): void { if (diag instanceof Error) { onError(diag.message); } else if (!diag.file || !diag.start) { onError(ts.flattenDiagnosticMessageText(diag.messageText, '\n')); } else { const lineAndCh = diag.file.getLineAndCharacterOfPosition(diag.start); onError(strings.format('{0}({1},{2}): {3}', diag.file.fileName, lineAndCh.line + 1, lineAndCh.character + 1, ts.flattenDiagnosticMessageText(diag.messageText, '\n')) ); } } const parsed = ts.readConfigFile(projectPath, ts.sys.readFile); if (parsed.error) { printDiagnostic(parsed.error); return createNullCompiler(); } const cmdLine = ts.parseJsonConfigFileContent(parsed.config, ts.sys, dirname(projectPath), existingOptions); if (cmdLine.errors.length > 0) { cmdLine.errors.forEach(printDiagnostic); return createNullCompiler(); } function logFn(topic: string, message: string): void { if (config.verbose) { log(colors.cyan(topic), message); } } // FULL COMPILE stream doing transpile, syntax and semantic diagnostics function createCompileStream(builder: builder.ITypeScriptBuilder, token?: builder.CancellationToken): Readable & Writable { return through(function (this: through.ThroughStream, file: Vinyl) { // give the file to the compiler if (file.isStream()) { this.emit('error', 'no support for streams'); return; } builder.file(file); }, function (this: { queue(a: any): void }) { // start the compilation process builder.build( file => this.queue(file), printDiagnostic, token ).catch(e => console.error(e)).then(() => this.queue(null)); }); } // TRANSPILE ONLY stream doing just TS to JS conversion function createTranspileStream(transpiler: ITranspiler): Readable & Writable { return through(function (this: through.ThroughStream & { queue(a: any): void }, file: Vinyl) { // give the file to the compiler if (file.isStream()) { this.emit('error', 'no support for streams'); return; } if (!file.contents) { return; } if (!config.transpileOnlyIncludesDts && file.path.endsWith('.d.ts')) { return; } if (!transpiler.onOutfile) { transpiler.onOutfile = file => this.queue(file); } transpiler.transpile(file); }, function (this: { queue(a: any): void }) { transpiler.join().then(() => { this.queue(null); transpiler.onOutfile = undefined; }); }); } let result: IncrementalCompiler; if (config.transpileOnly) { const transpiler = !config.transpileWithSwc ? new TscTranspiler(logFn, printDiagnostic, projectPath, cmdLine) : new ESBuildTranspiler(logFn, printDiagnostic, projectPath, cmdLine); result = (() => createTranspileStream(transpiler)); } else { const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine); result = ((token: builder.CancellationToken) => createCompileStream(_builder, token)); } result.src = (opts?: { cwd?: string; base?: string }) => { let _pos = 0; const _fileNames = cmdLine.fileNames.slice(0); return new class extends Readable { constructor() { super({ objectMode: true }); } _read() { let more: boolean = true; let path: string; for (; more && _pos < _fileNames.length; _pos++) { path = _fileNames[_pos]; more = this.push(new Vinyl({ path, contents: readFileSync(path), stat: statSync(path), cwd: opts && opts.cwd, base: opts && opts.base || dirname(projectPath) })); } if (_pos >= _fileNames.length) { this.push(null); } } }; }; return result; } ================================================ FILE: build/lib/tsb/transpiler.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ESBuildTranspiler = exports.TscTranspiler = void 0; const esbuild_1 = __importDefault(require("esbuild")); const typescript_1 = __importDefault(require("typescript")); const node_worker_threads_1 = __importDefault(require("node:worker_threads")); const vinyl_1 = __importDefault(require("vinyl")); const node_os_1 = require("node:os"); function transpile(tsSrc, options) { const isAmd = /\n(import|export)/m.test(tsSrc); if (!isAmd && options.compilerOptions?.module === typescript_1.default.ModuleKind.AMD) { // enforce NONE module-system for not-amd cases options = { ...options, ...{ compilerOptions: { ...options.compilerOptions, module: typescript_1.default.ModuleKind.None } } }; } const out = typescript_1.default.transpileModule(tsSrc, options); return { jsSrc: out.outputText, diag: out.diagnostics ?? [] }; } if (!node_worker_threads_1.default.isMainThread) { // WORKER node_worker_threads_1.default.parentPort?.addListener('message', (req) => { const res = { jsSrcs: [], diagnostics: [] }; for (const tsSrc of req.tsSrcs) { const out = transpile(tsSrc, req.options); res.jsSrcs.push(out.jsSrc); res.diagnostics.push(out.diag); } node_worker_threads_1.default.parentPort.postMessage(res); }); } class OutputFileNameOracle { getOutputFileName; constructor(cmdLine, configFilePath) { this.getOutputFileName = (file) => { try { // windows: path-sep normalizing file = typescript_1.default.normalizePath(file); if (!cmdLine.options.configFilePath) { // this is needed for the INTERNAL getOutputFileNames-call below... cmdLine.options.configFilePath = configFilePath; } const isDts = file.endsWith('.d.ts'); if (isDts) { file = file.slice(0, -5) + '.ts'; cmdLine.fileNames.push(file); } const outfile = typescript_1.default.getOutputFileNames(cmdLine, file, true)[0]; if (isDts) { cmdLine.fileNames.pop(); } return outfile; } catch (err) { console.error(file, cmdLine.fileNames); console.error(err); throw err; } }; } } class TranspileWorker { static pool = 1; id = TranspileWorker.pool++; _worker = new node_worker_threads_1.default.Worker(__filename); _pending; _durations = []; constructor(outFileFn) { this._worker.addListener('message', (res) => { if (!this._pending) { console.error('RECEIVING data WITHOUT request'); return; } const [resolve, reject, files, options, t1] = this._pending; const outFiles = []; const diag = []; for (let i = 0; i < res.jsSrcs.length; i++) { // inputs and outputs are aligned across the arrays const file = files[i]; const jsSrc = res.jsSrcs[i]; const diag = res.diagnostics[i]; if (diag.length > 0) { diag.push(...diag); continue; } let SuffixTypes; (function (SuffixTypes) { SuffixTypes[SuffixTypes["Dts"] = 5] = "Dts"; SuffixTypes[SuffixTypes["Ts"] = 3] = "Ts"; SuffixTypes[SuffixTypes["Unknown"] = 0] = "Unknown"; })(SuffixTypes || (SuffixTypes = {})); const suffixLen = file.path.endsWith('.d.ts') ? 5 /* SuffixTypes.Dts */ : file.path.endsWith('.ts') ? 3 /* SuffixTypes.Ts */ : 0 /* SuffixTypes.Unknown */; // check if output of a DTS-files isn't just "empty" and iff so // skip this file if (suffixLen === 5 /* SuffixTypes.Dts */ && _isDefaultEmpty(jsSrc)) { continue; } const outBase = options.compilerOptions?.outDir ?? file.base; const outPath = outFileFn(file.path); outFiles.push(new vinyl_1.default({ path: outPath, base: outBase, contents: Buffer.from(jsSrc), })); } this._pending = undefined; this._durations.push(Date.now() - t1); if (diag.length > 0) { reject(diag); } else { resolve(outFiles); } }); } terminate() { // console.log(`Worker#${this.id} ENDS after ${this._durations.length} jobs (total: ${this._durations.reduce((p, c) => p + c, 0)}, avg: ${this._durations.reduce((p, c) => p + c, 0) / this._durations.length})`); this._worker.terminate(); } get isBusy() { return this._pending !== undefined; } next(files, options) { if (this._pending !== undefined) { throw new Error('BUSY'); } return new Promise((resolve, reject) => { this._pending = [resolve, reject, files, options, Date.now()]; const req = { options, tsSrcs: files.map(file => String(file.contents)) }; this._worker.postMessage(req); }); } } class TscTranspiler { _onError; _cmdLine; static P = Math.floor((0, node_os_1.cpus)().length * .5); _outputFileNames; onOutfile; _workerPool = []; _queue = []; _allJobs = []; constructor(logFn, _onError, configFilePath, _cmdLine) { this._onError = _onError; this._cmdLine = _cmdLine; logFn('Transpile', `will use ${TscTranspiler.P} transpile worker`); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); } async join() { // wait for all penindg jobs this._consumeQueue(); await Promise.allSettled(this._allJobs); this._allJobs.length = 0; // terminate all worker this._workerPool.forEach(w => w.terminate()); this._workerPool.length = 0; } transpile(file) { if (this._cmdLine.options.noEmit) { // not doing ANYTHING here return; } const newLen = this._queue.push(file); if (newLen > TscTranspiler.P ** 2) { this._consumeQueue(); } } _consumeQueue() { if (this._queue.length === 0) { // no work... return; } // kinda LAZYily create workers if (this._workerPool.length === 0) { for (let i = 0; i < TscTranspiler.P; i++) { this._workerPool.push(new TranspileWorker(file => this._outputFileNames.getOutputFileName(file))); } } const freeWorker = this._workerPool.filter(w => !w.isBusy); if (freeWorker.length === 0) { // OK, they will pick up work themselves return; } for (const worker of freeWorker) { if (this._queue.length === 0) { break; } const job = new Promise(resolve => { const consume = () => { const files = this._queue.splice(0, TscTranspiler.P); if (files.length === 0) { // DONE resolve(undefined); return; } // work on the NEXT file // const [inFile, outFn] = req; worker.next(files, { compilerOptions: this._cmdLine.options }).then(outFiles => { if (this.onOutfile) { outFiles.map(this.onOutfile, this); } consume(); }).catch(err => { this._onError(err); }); }; consume(); }); this._allJobs.push(job); } } } exports.TscTranspiler = TscTranspiler; class ESBuildTranspiler { _logFn; _onError; _cmdLine; _outputFileNames; _jobs = []; onOutfile; _transformOpts; constructor(_logFn, _onError, configFilePath, _cmdLine) { this._logFn = _logFn; this._onError = _onError; this._cmdLine = _cmdLine; _logFn('Transpile', `will use ESBuild to transpile source files`); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); const isExtension = configFilePath.includes('extensions'); this._transformOpts = { target: ['es2022'], format: isExtension ? 'cjs' : 'esm', platform: isExtension ? 'node' : undefined, loader: 'ts', sourcemap: 'inline', tsconfigRaw: JSON.stringify({ compilerOptions: { ...this._cmdLine.options, ...{ module: isExtension ? typescript_1.default.ModuleKind.CommonJS : undefined } } }), supported: { 'class-static-blocks': false, // SEE https://github.com/evanw/esbuild/issues/3823, 'dynamic-import': !isExtension, // see https://github.com/evanw/esbuild/issues/1281 'class-field': !isExtension } }; } async join() { const jobs = this._jobs.slice(); this._jobs.length = 0; await Promise.allSettled(jobs); } transpile(file) { if (!(file.contents instanceof Buffer)) { throw Error('file.contents must be a Buffer'); } const t1 = Date.now(); this._jobs.push(esbuild_1.default.transform(file.contents, { ...this._transformOpts, sourcefile: file.path, }).then(result => { // check if output of a DTS-files isn't just "empty" and iff so // skip this file if (file.path.endsWith('.d.ts') && _isDefaultEmpty(result.code)) { return; } const outBase = this._cmdLine.options.outDir ?? file.base; const outPath = this._outputFileNames.getOutputFileName(file.path); this.onOutfile(new vinyl_1.default({ path: outPath, base: outBase, contents: Buffer.from(result.code), })); this._logFn('Transpile', `esbuild took ${Date.now() - t1}ms for ${file.path}`); }).catch(err => { this._onError(err); })); } } exports.ESBuildTranspiler = ESBuildTranspiler; function _isDefaultEmpty(src) { return src .replace('"use strict";', '') .replace(/\/\/# sourceMappingURL.*^/, '') .replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1') .trim().length === 0; } //# sourceMappingURL=transpiler.js.map ================================================ FILE: build/lib/tsb/transpiler.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import esbuild from 'esbuild'; import ts from 'typescript'; import threads from 'node:worker_threads'; import Vinyl from 'vinyl'; import { cpus } from 'node:os'; interface TranspileReq { readonly tsSrcs: string[]; readonly options: ts.TranspileOptions; } interface TranspileRes { readonly jsSrcs: string[]; readonly diagnostics: ts.Diagnostic[][]; } function transpile(tsSrc: string, options: ts.TranspileOptions): { jsSrc: string; diag: ts.Diagnostic[] } { const isAmd = /\n(import|export)/m.test(tsSrc); if (!isAmd && options.compilerOptions?.module === ts.ModuleKind.AMD) { // enforce NONE module-system for not-amd cases options = { ...options, ...{ compilerOptions: { ...options.compilerOptions, module: ts.ModuleKind.None } } }; } const out = ts.transpileModule(tsSrc, options); return { jsSrc: out.outputText, diag: out.diagnostics ?? [] }; } if (!threads.isMainThread) { // WORKER threads.parentPort?.addListener('message', (req: TranspileReq) => { const res: TranspileRes = { jsSrcs: [], diagnostics: [] }; for (const tsSrc of req.tsSrcs) { const out = transpile(tsSrc, req.options); res.jsSrcs.push(out.jsSrc); res.diagnostics.push(out.diag); } threads.parentPort!.postMessage(res); }); } class OutputFileNameOracle { readonly getOutputFileName: (name: string) => string; constructor(cmdLine: ts.ParsedCommandLine, configFilePath: string) { // very complicated logic to re-use TS internal functions to know the output path // given a TS input path and its config type InternalTsApi = typeof ts & { normalizePath(path: string): string; getOutputFileNames(commandLine: ts.ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; }; this.getOutputFileName = (file) => { try { // windows: path-sep normalizing file = (ts).normalizePath(file); if (!cmdLine.options.configFilePath) { // this is needed for the INTERNAL getOutputFileNames-call below... cmdLine.options.configFilePath = configFilePath; } const isDts = file.endsWith('.d.ts'); if (isDts) { file = file.slice(0, -5) + '.ts'; cmdLine.fileNames.push(file); } const outfile = (ts).getOutputFileNames(cmdLine, file, true)[0]; if (isDts) { cmdLine.fileNames.pop(); } return outfile; } catch (err) { console.error(file, cmdLine.fileNames); console.error(err); throw err; } }; } } class TranspileWorker { private static pool = 1; readonly id = TranspileWorker.pool++; private _worker = new threads.Worker(__filename); private _pending?: [resolve: Function, reject: Function, file: Vinyl[], options: ts.TranspileOptions, t1: number]; private _durations: number[] = []; constructor(outFileFn: (fileName: string) => string) { this._worker.addListener('message', (res: TranspileRes) => { if (!this._pending) { console.error('RECEIVING data WITHOUT request'); return; } const [resolve, reject, files, options, t1] = this._pending; const outFiles: Vinyl[] = []; const diag: ts.Diagnostic[] = []; for (let i = 0; i < res.jsSrcs.length; i++) { // inputs and outputs are aligned across the arrays const file = files[i]; const jsSrc = res.jsSrcs[i]; const diag = res.diagnostics[i]; if (diag.length > 0) { diag.push(...diag); continue; } const enum SuffixTypes { Dts = 5, Ts = 3, Unknown = 0 } const suffixLen = file.path.endsWith('.d.ts') ? SuffixTypes.Dts : file.path.endsWith('.ts') ? SuffixTypes.Ts : SuffixTypes.Unknown; // check if output of a DTS-files isn't just "empty" and iff so // skip this file if (suffixLen === SuffixTypes.Dts && _isDefaultEmpty(jsSrc)) { continue; } const outBase = options.compilerOptions?.outDir ?? file.base; const outPath = outFileFn(file.path); outFiles.push(new Vinyl({ path: outPath, base: outBase, contents: Buffer.from(jsSrc), })); } this._pending = undefined; this._durations.push(Date.now() - t1); if (diag.length > 0) { reject(diag); } else { resolve(outFiles); } }); } terminate() { // console.log(`Worker#${this.id} ENDS after ${this._durations.length} jobs (total: ${this._durations.reduce((p, c) => p + c, 0)}, avg: ${this._durations.reduce((p, c) => p + c, 0) / this._durations.length})`); this._worker.terminate(); } get isBusy() { return this._pending !== undefined; } next(files: Vinyl[], options: ts.TranspileOptions) { if (this._pending !== undefined) { throw new Error('BUSY'); } return new Promise((resolve, reject) => { this._pending = [resolve, reject, files, options, Date.now()]; const req: TranspileReq = { options, tsSrcs: files.map(file => String(file.contents)) }; this._worker.postMessage(req); }); } } export interface ITranspiler { onOutfile?: (file: Vinyl) => void; join(): Promise; transpile(file: Vinyl): void; } export class TscTranspiler implements ITranspiler { static P = Math.floor(cpus().length * .5); private readonly _outputFileNames: OutputFileNameOracle; public onOutfile?: (file: Vinyl) => void; private _workerPool: TranspileWorker[] = []; private _queue: Vinyl[] = []; private _allJobs: Promise[] = []; constructor( logFn: (topic: string, message: string) => void, private readonly _onError: (err: any) => void, configFilePath: string, private readonly _cmdLine: ts.ParsedCommandLine ) { logFn('Transpile', `will use ${TscTranspiler.P} transpile worker`); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); } async join() { // wait for all penindg jobs this._consumeQueue(); await Promise.allSettled(this._allJobs); this._allJobs.length = 0; // terminate all worker this._workerPool.forEach(w => w.terminate()); this._workerPool.length = 0; } transpile(file: Vinyl) { if (this._cmdLine.options.noEmit) { // not doing ANYTHING here return; } const newLen = this._queue.push(file); if (newLen > TscTranspiler.P ** 2) { this._consumeQueue(); } } private _consumeQueue(): void { if (this._queue.length === 0) { // no work... return; } // kinda LAZYily create workers if (this._workerPool.length === 0) { for (let i = 0; i < TscTranspiler.P; i++) { this._workerPool.push(new TranspileWorker(file => this._outputFileNames.getOutputFileName(file))); } } const freeWorker = this._workerPool.filter(w => !w.isBusy); if (freeWorker.length === 0) { // OK, they will pick up work themselves return; } for (const worker of freeWorker) { if (this._queue.length === 0) { break; } const job = new Promise(resolve => { const consume = () => { const files = this._queue.splice(0, TscTranspiler.P); if (files.length === 0) { // DONE resolve(undefined); return; } // work on the NEXT file // const [inFile, outFn] = req; worker.next(files, { compilerOptions: this._cmdLine.options }).then(outFiles => { if (this.onOutfile) { outFiles.map(this.onOutfile, this); } consume(); }).catch(err => { this._onError(err); }); }; consume(); }); this._allJobs.push(job); } } } export class ESBuildTranspiler implements ITranspiler { private readonly _outputFileNames: OutputFileNameOracle; private _jobs: Promise[] = []; onOutfile?: ((file: Vinyl) => void) | undefined; private readonly _transformOpts: esbuild.TransformOptions; constructor( private readonly _logFn: (topic: string, message: string) => void, private readonly _onError: (err: any) => void, configFilePath: string, private readonly _cmdLine: ts.ParsedCommandLine ) { _logFn('Transpile', `will use ESBuild to transpile source files`); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); const isExtension = configFilePath.includes('extensions'); this._transformOpts = { target: ['es2022'], format: isExtension ? 'cjs' : 'esm', platform: isExtension ? 'node' : undefined, loader: 'ts', sourcemap: 'inline', tsconfigRaw: JSON.stringify({ compilerOptions: { ...this._cmdLine.options, ...{ module: isExtension ? ts.ModuleKind.CommonJS : undefined } satisfies ts.CompilerOptions } }), supported: { 'class-static-blocks': false, // SEE https://github.com/evanw/esbuild/issues/3823, 'dynamic-import': !isExtension, // see https://github.com/evanw/esbuild/issues/1281 'class-field': !isExtension } }; } async join(): Promise { const jobs = this._jobs.slice(); this._jobs.length = 0; await Promise.allSettled(jobs); } transpile(file: Vinyl): void { if (!(file.contents instanceof Buffer)) { throw Error('file.contents must be a Buffer'); } const t1 = Date.now(); this._jobs.push(esbuild.transform(file.contents, { ...this._transformOpts, sourcefile: file.path, }).then(result => { // check if output of a DTS-files isn't just "empty" and iff so // skip this file if (file.path.endsWith('.d.ts') && _isDefaultEmpty(result.code)) { return; } const outBase = this._cmdLine.options.outDir ?? file.base; const outPath = this._outputFileNames.getOutputFileName(file.path); this.onOutfile!(new Vinyl({ path: outPath, base: outBase, contents: Buffer.from(result.code), })); this._logFn('Transpile', `esbuild took ${Date.now() - t1}ms for ${file.path}`); }).catch(err => { this._onError(err); })); } } function _isDefaultEmpty(src: string): boolean { return src .replace('"use strict";', '') .replace(/\/\/# sourceMappingURL.*^/, '') .replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1') .trim().length === 0; } ================================================ FILE: build/lib/tsb/utils.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.graph = exports.strings = void 0; var strings; (function (strings) { function format(value, ...rest) { return value.replace(/({\d+})/g, function (match) { const index = Number(match.substring(1, match.length - 1)); return String(rest[index]) || match; }); } strings.format = format; })(strings || (exports.strings = strings = {})); var graph; (function (graph) { class Node { data; incoming = new Map(); outgoing = new Map(); constructor(data) { this.data = data; } } graph.Node = Node; class Graph { _nodes = new Map(); inertEdge(from, to) { const fromNode = this.lookupOrInsertNode(from); const toNode = this.lookupOrInsertNode(to); fromNode.outgoing.set(toNode.data, toNode); toNode.incoming.set(fromNode.data, fromNode); } resetNode(data) { const node = this._nodes.get(data); if (!node) { return; } for (const outDep of node.outgoing.values()) { outDep.incoming.delete(node.data); } node.outgoing.clear(); } lookupOrInsertNode(data) { let node = this._nodes.get(data); if (!node) { node = new Node(data); this._nodes.set(data, node); } return node; } lookup(data) { return this._nodes.get(data) ?? null; } findCycle() { let result; let foundStartNodes = false; const checked = new Set(); for (const [_start, value] of this._nodes) { if (Object.values(value.incoming).length > 0) { continue; } foundStartNodes = true; const dfs = (node, visited) => { if (checked.has(node)) { return; } if (visited.has(node)) { result = [...visited, node].map(n => n.data); const idx = result.indexOf(node.data); result = result.slice(idx); return; } visited.add(node); for (const child of Object.values(node.outgoing)) { dfs(child, visited); if (result) { break; } } visited.delete(node); checked.add(node); }; dfs(value, new Set()); if (result) { break; } } if (!foundStartNodes) { // everything is a cycle return Array.from(this._nodes.keys()); } return result; } } graph.Graph = Graph; })(graph || (exports.graph = graph = {})); //# sourceMappingURL=utils.js.map ================================================ FILE: build/lib/tsb/utils.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export namespace strings { export function format(value: string, ...rest: any[]): string { return value.replace(/({\d+})/g, function (match) { const index = Number(match.substring(1, match.length - 1)); return String(rest[index]) || match; }); } } export namespace graph { export class Node { readonly incoming = new Map>(); readonly outgoing = new Map>(); constructor(readonly data: T) { } } export class Graph { private _nodes = new Map>(); inertEdge(from: T, to: T): void { const fromNode = this.lookupOrInsertNode(from); const toNode = this.lookupOrInsertNode(to); fromNode.outgoing.set(toNode.data, toNode); toNode.incoming.set(fromNode.data, fromNode); } resetNode(data: T): void { const node = this._nodes.get(data); if (!node) { return; } for (const outDep of node.outgoing.values()) { outDep.incoming.delete(node.data); } node.outgoing.clear(); } lookupOrInsertNode(data: T): Node { let node = this._nodes.get(data); if (!node) { node = new Node(data); this._nodes.set(data, node); } return node; } lookup(data: T): Node | null { return this._nodes.get(data) ?? null; } findCycle(): T[] | undefined { let result: T[] | undefined; let foundStartNodes = false; const checked = new Set>(); for (const [_start, value] of this._nodes) { if (Object.values(value.incoming).length > 0) { continue; } foundStartNodes = true; const dfs = (node: Node, visited: Set>) => { if (checked.has(node)) { return; } if (visited.has(node)) { result = [...visited, node].map(n => n.data); const idx = result.indexOf(node.data); result = result.slice(idx); return; } visited.add(node); for (const child of Object.values(node.outgoing)) { dfs(child, visited); if (result) { break; } } visited.delete(node); checked.add(node); }; dfs(value, new Set()); if (result) { break; } } if (!foundStartNodes) { // everything is a cycle return Array.from(this._nodes.keys()); } return result; } } } ================================================ FILE: build/lib/typings/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "definitelytyped", "repositoryUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", "commitHash": "69e3ac6bec3008271f76bbfa7cf69aa9198c4ff0" } }, "license": "MIT" } ], "version": 1 } ================================================ FILE: build/lib/typings/event-stream.d.ts ================================================ declare module "event-stream" { import { Stream } from 'stream'; import { ThroughStream as _ThroughStream } from 'through'; import File from 'vinyl'; export interface ThroughStream extends _ThroughStream { queue(data: File | null): any; push(data: File | null): any; paused: boolean; } function merge(streams: Stream[]): ThroughStream; function merge(...streams: Stream[]): ThroughStream; function concat(...stream: Stream[]): ThroughStream; function duplex(istream: Stream, ostream: Stream): ThroughStream; function through(write?: (this: ThroughStream, data: any) => void, end?: (this: ThroughStream) => void, opts?: { autoDestroy: boolean; }): ThroughStream; function readArray(array: T[]): ThroughStream; function writeArray(cb: (err: Error, array: T[]) => void): ThroughStream; function mapSync(cb: (data: I) => O): ThroughStream; function map(cb: (data: I, cb: (err?: Error, data?: O) => void) => O): ThroughStream; function readable(asyncFunction: (this: ThroughStream, ...args: any[]) => any): any; } ================================================ FILE: build/lib/typings/github-releases.d.ts ================================================ declare module 'github-releases' { } ================================================ FILE: build/lib/typings/gulp-bom.d.ts ================================================ declare module "gulp-bom" { function f(): NodeJS.ReadWriteStream; /** * This is required as per: * https://github.com/microsoft/TypeScript/issues/5073 */ namespace f {} export = f; } ================================================ FILE: build/lib/typings/gulp-buffer.d.ts ================================================ declare module "gulp-buffer" { function f(): NodeJS.ReadWriteStream; /** * This is required as per: * https://github.com/microsoft/TypeScript/issues/5073 */ namespace f {} export = f; } ================================================ FILE: build/lib/typings/gulp-flatmap.d.ts ================================================ declare module 'gulp-flatmap' { import File = require('vinyl'); function f(fn:(stream:NodeJS.ReadWriteStream, file:File)=>NodeJS.ReadWriteStream): NodeJS.ReadWriteStream; /** * This is required as per: * https://github.com/microsoft/TypeScript/issues/5073 */ namespace f {} export = f; } ================================================ FILE: build/lib/typings/lazy.js.d.ts ================================================ // Type definitions for Lazy.js 0.3.2 // Project: https://github.com/dtao/lazy.js/ // Definitions by: Bart van der Schoor // Definitions: https://github.com/borisyankov/DefinitelyTyped declare function Lazy(value: string): Lazy.StringLikeSequence; declare function Lazy(value: T[]): Lazy.ArrayLikeSequence; declare function Lazy(value: any[]): Lazy.ArrayLikeSequence; declare function Lazy(value: Object): Lazy.ObjectLikeSequence; declare function Lazy(value: Object): Lazy.ObjectLikeSequence; declare module Lazy { function strict(): StrictLazy; function generate(generatorFn: GeneratorCallback, length?: number): GeneratedSequence; function range(to: number): GeneratedSequence; function range(from: number, to: number, step?: number): GeneratedSequence; function repeat(value: T, count?: number): GeneratedSequence; function on(eventType: string): Sequence; function readFile(path: string): StringLikeSequence; function makeHttpRequest(path: string): StringLikeSequence; interface StrictLazy { (value: string): StringLikeSequence; (value: T[]): ArrayLikeSequence; (value: any[]): ArrayLikeSequence; (value: Object): ObjectLikeSequence; (value: Object): ObjectLikeSequence; strict(): StrictLazy; generate(generatorFn: GeneratorCallback, length?: number): GeneratedSequence; range(to: number): GeneratedSequence; range(from: number, to: number, step?: number): GeneratedSequence; repeat(value: T, count?: number): GeneratedSequence; on(eventType: string): Sequence; readFile(path: string): StringLikeSequence; makeHttpRequest(path: string): StringLikeSequence; } interface ArrayLike { length: number; [index: number]: T; } interface Callback { (): void; } interface ErrorCallback { (error: any): void; } interface ValueCallback { (value: T): void; } interface GetKeyCallback { (value: T): string; } interface TestCallback { (value: T): boolean; } interface MapCallback { (value: T): U; } interface MapStringCallback { (value: string): string; } interface NumberCallback { (value: T): number; } interface MemoCallback { (memo: U, value: T): U; } interface GeneratorCallback { (index: number): T; } interface CompareCallback { (x: any, y: any): number; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - interface Iterator { new(sequence: Sequence): Iterator; current(): T; moveNext(): boolean; } interface GeneratedSequence extends Sequence { new(generatorFn: GeneratorCallback, length: number): GeneratedSequence; length(): number; } interface AsyncSequence extends SequenceBase { each(callback: ValueCallback): AsyncHandle; } interface AsyncHandle { cancel(): void; onComplete(callback: Callback): void; onError(callback: ErrorCallback): void; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module Sequence { function define(methodName: string[], overrides: Object): Function; } interface Sequence extends SequenceBase { each(eachFn: ValueCallback): Sequence; } interface ArraySequence extends SequenceBase { flatten(): Sequence; } interface SequenceBase extends SequenceBaser { first(): any; first(count: number): Sequence; indexOf(value: any, startIndex?: number): Sequence; last(): any; last(count: number): Sequence; lastIndexOf(value: any): Sequence; reverse(): Sequence; } interface SequenceBaser { // TODO improve define() (needs ugly overload) async(interval: number): AsyncSequence; chunk(size: number): Sequence; compact(): Sequence; concat(var_args: T[]): Sequence; concat(sequence: Sequence): Sequence; consecutive(length: number): Sequence; contains(value: T): boolean; countBy(keyFn: GetKeyCallback): ObjectLikeSequence; countBy(propertyName: string): ObjectLikeSequence; dropWhile(predicateFn: TestCallback): Sequence; every(predicateFn: TestCallback): boolean; filter(predicateFn: TestCallback): Sequence; find(predicateFn: TestCallback): Sequence; findWhere(properties: Object): Sequence; groupBy(keyFn: GetKeyCallback): ObjectLikeSequence; initial(count?: number): Sequence; intersection(var_args: T[]): Sequence; invoke(methodName: string): Sequence; isEmpty(): boolean; join(delimiter?: string): string; map(mapFn: MapCallback): ArraySequence; map(mapFn: MapCallback): Sequence; // TODO: vscode addition to workaround strict null errors flatten(): Sequence; max(valueFn?: NumberCallback): T; min(valueFn?: NumberCallback): T; none(valueFn?: TestCallback): boolean; pluck(propertyName: string): Sequence; reduce(aggregatorFn: MemoCallback, memo?: U): U; reduceRight(aggregatorFn: MemoCallback, memo: U): U; reject(predicateFn: TestCallback): Sequence; rest(count?: number): Sequence; shuffle(): Sequence; some(predicateFn?: TestCallback): boolean; sort(sortFn?: CompareCallback, descending?: boolean): Sequence; sortBy(sortFn: string, descending?: boolean): Sequence; sortBy(sortFn: NumberCallback, descending?: boolean): Sequence; sortedIndex(value: T): Sequence; size(): number; sum(valueFn?: NumberCallback): Sequence; takeWhile(predicateFn: TestCallback): Sequence; union(var_args: T[]): Sequence; uniq(): Sequence; where(properties: Object): Sequence; without(...var_args: T[]): Sequence; without(var_args: T[]): Sequence; zip(var_args: T[]): ArraySequence; toArray(): T[]; toObject(): Object; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module ArrayLikeSequence { function define(methodName: string[], overrides: Object): Function; } interface ArrayLikeSequence extends Sequence { // define()X; concat(var_args: T[]): ArrayLikeSequence; concat(sequence: Sequence): Sequence; first(count?: number): ArrayLikeSequence; get(index: number): T; length(): number; map(mapFn: MapCallback): ArraySequence; map(mapFn: MapCallback): ArrayLikeSequence; pop(): ArrayLikeSequence; rest(count?: number): ArrayLikeSequence; reverse(): ArrayLikeSequence; shift(): ArrayLikeSequence; slice(begin: number, end?: number): ArrayLikeSequence; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module ObjectLikeSequence { function define(methodName: string[], overrides: Object): Function; } interface ObjectLikeSequence extends Sequence { assign(other: Object): ObjectLikeSequence; // throws error //async(): X; defaults(defaults: Object): ObjectLikeSequence; functions(): Sequence; get(property: string): ObjectLikeSequence; invert(): ObjectLikeSequence; keys(): Sequence; omit(properties: string[]): ObjectLikeSequence; pairs(): Sequence; pick(properties: string[]): ObjectLikeSequence; toArray(): T[]; toObject(): Object; values(): Sequence; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module StringLikeSequence { function define(methodName: string[], overrides: Object): Function; } interface StringLikeSequence extends SequenceBaser { charAt(index: number): string; charCodeAt(index: number): number; contains(value: string): boolean; endsWith(suffix: string): boolean; first(): string; first(count: number): StringLikeSequence; indexOf(substring: string, startIndex?: number): number; last(): string; last(count: number): StringLikeSequence; lastIndexOf(substring: string, startIndex?: number): number; mapString(mapFn: MapStringCallback): StringLikeSequence; match(pattern: RegExp): StringLikeSequence; reverse(): StringLikeSequence; split(delimiter: string): StringLikeSequence; split(delimiter: RegExp): StringLikeSequence; startsWith(prefix: string): boolean; substring(start: number, stop?: number): StringLikeSequence; toLowerCase(): StringLikeSequence; toUpperCase(): StringLikeSequence; } } declare module 'lazy.js' { export = Lazy; } ================================================ FILE: build/lib/typings/stream.d.ts ================================================ declare namespace NodeJS { type ComposeFnParam = (source: any) => void; interface ReadWriteStream { compose( stream: T | ComposeFnParam | Iterable | AsyncIterable, options?: { signal: AbortSignal }, ): T; } } ================================================ FILE: build/lib/typings/ternary-stream.d.ts ================================================ declare module 'ternary-stream' { import File = require('vinyl'); function f(check: (f: File) => boolean, onTrue: NodeJS.ReadWriteStream, opnFalse?: NodeJS.ReadWriteStream): NodeJS.ReadWriteStream; /** * This is required as per: * https://github.com/microsoft/TypeScript/issues/5073 */ namespace f {} export = f; } ================================================ FILE: build/lib/typings/vinyl.d.ts ================================================ // Type definitions for vinyl 0.4.3 // Project: https://github.com/wearefractal/vinyl // Definitions by: vvakame , jedmao // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare module "vinyl" { import fs = require("fs"); /** * A virtual file format. */ class File { constructor(options?: { /** * Default: process.cwd() */ cwd?: string; /** * Used for relative pathing. Typically where a glob starts. */ base?: string; /** * Full path to the file. */ path?: string; /** * Path history. Has no effect if options.path is passed. */ history?: string[]; /** * The result of an fs.stat call. See fs.Stats for more information. */ stat?: fs.Stats; /** * File contents. * Type: Buffer, Stream, or null */ contents?: Buffer | NodeJS.ReadWriteStream; }); /** * Default: process.cwd() */ public cwd: string; /** * Used for relative pathing. Typically where a glob starts. */ public base: string; /** * Gets and sets the basename of `file.path`. * * Throws when `file.path` is not set. * * Example: * * ```js * var file = new File({ * cwd: '/', * base: '/test/', * path: '/test/file.js' * }); * * console.log(file.basename); // file.js * * file.basename = 'file.txt'; * * console.log(file.basename); // file.txt * console.log(file.path); // /test/file.txt * ``` */ basename: string; /** * Full path to the file. */ public path: string; public stat: fs.Stats; /** * Type: Buffer|Stream|null (Default: null) */ public contents: Buffer | NodeJS.ReadableStream; /** * Returns path.relative for the file base and file path. * Example: * var file = new File({ * cwd: "/", * base: "/test/", * path: "/test/file.js" * }); * console.log(file.relative); // file.js */ public relative: string; public isBuffer(): boolean; public isStream(): boolean; public isNull(): boolean; public isDirectory(): boolean; /** * Returns a new File object with all attributes cloned. Custom attributes are deep-cloned. */ public clone(opts?: { contents?: boolean }): File; /** * If file.contents is a Buffer, it will write it to the stream. * If file.contents is a Stream, it will pipe it to the stream. * If file.contents is null, it will do nothing. */ public pipe( stream: T, opts?: { /** * If false, the destination stream will not be ended (same as node core). */ end?: boolean; }): T; /** * Returns a pretty String interpretation of the File. Useful for console.log. */ public inspect(): string; } /** * This is required as per: * https://github.com/microsoft/TypeScript/issues/5073 */ namespace File { } export = File; } ================================================ FILE: build/lib/util.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.incremental = incremental; exports.debounce = debounce; exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions; exports.setExecutableBit = setExecutableBit; exports.toFileUri = toFileUri; exports.skipDirectories = skipDirectories; exports.cleanNodeModules = cleanNodeModules; exports.loadSourcemaps = loadSourcemaps; exports.stripSourceMappingURL = stripSourceMappingURL; exports.$if = $if; exports.appendOwnPathSourceURL = appendOwnPathSourceURL; exports.rewriteSourceMappingURL = rewriteSourceMappingURL; exports.rimraf = rimraf; exports.rreddir = rreddir; exports.ensureDir = ensureDir; exports.rebase = rebase; exports.filter = filter; exports.streamToPromise = streamToPromise; exports.getElectronVersion = getElectronVersion; const event_stream_1 = __importDefault(require("event-stream")); const debounce_1 = __importDefault(require("debounce")); const gulp_filter_1 = __importDefault(require("gulp-filter")); const gulp_rename_1 = __importDefault(require("gulp-rename")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const rimraf_1 = __importDefault(require("rimraf")); const url_1 = require("url"); const ternary_stream_1 = __importDefault(require("ternary-stream")); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const NoCancellationToken = { isCancellationRequested: () => false }; function incremental(streamProvider, initial, supportsCancellation) { const input = event_stream_1.default.through(); const output = event_stream_1.default.through(); let state = 'idle'; let buffer = Object.create(null); const token = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 }; const run = (input, isCancellable) => { state = 'running'; const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken); input .pipe(stream) .pipe(event_stream_1.default.through(undefined, () => { state = 'idle'; eventuallyRun(); })) .pipe(output); }; if (initial) { run(initial, false); } const eventuallyRun = (0, debounce_1.default)(() => { const paths = Object.keys(buffer); if (paths.length === 0) { return; } const data = paths.map(path => buffer[path]); buffer = Object.create(null); run(event_stream_1.default.readArray(data), true); }, 500); input.on('data', (f) => { buffer[f.path] = f; if (state === 'idle') { eventuallyRun(); } }); return event_stream_1.default.duplex(input, output); } function debounce(task, duration = 500) { const input = event_stream_1.default.through(); const output = event_stream_1.default.through(); let state = 'idle'; const run = () => { state = 'running'; task() .pipe(event_stream_1.default.through(undefined, () => { const shouldRunAgain = state === 'stale'; state = 'idle'; if (shouldRunAgain) { eventuallyRun(); } })) .pipe(output); }; run(); const eventuallyRun = (0, debounce_1.default)(() => run(), duration); input.on('data', () => { if (state === 'idle') { eventuallyRun(); } else { state = 'stale'; } }); return event_stream_1.default.duplex(input, output); } function fixWin32DirectoryPermissions() { if (!/win32/.test(process.platform)) { return event_stream_1.default.through(); } return event_stream_1.default.mapSync(f => { if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) { f.stat.mode = 16877; } return f; }); } function setExecutableBit(pattern) { const setBit = event_stream_1.default.mapSync(f => { if (!f.stat) { f.stat = { isFile() { return true; } }; } f.stat.mode = /* 100755 */ 33261; return f; }); if (!pattern) { return setBit; } const input = event_stream_1.default.through(); const filter = (0, gulp_filter_1.default)(pattern, { restore: true }); const output = input .pipe(filter) .pipe(setBit) .pipe(filter.restore); return event_stream_1.default.duplex(input, output); } function toFileUri(filePath) { const match = filePath.match(/^([a-z])\:(.*)$/i); if (match) { filePath = '/' + match[1].toUpperCase() + ':' + match[2]; } return 'file://' + filePath.replace(/\\/g, '/'); } function skipDirectories() { return event_stream_1.default.mapSync(f => { if (!f.isDirectory()) { return f; } }); } function cleanNodeModules(rulePath) { const rules = fs_1.default.readFileSync(rulePath, 'utf8') .split(/\r?\n/g) .map(line => line.trim()) .filter(line => line && !/^#/.test(line)); const excludes = rules.filter(line => !/^!/.test(line)).map(line => `!**/node_modules/${line}`); const includes = rules.filter(line => /^!/.test(line)).map(line => `**/node_modules/${line.substr(1)}`); const input = event_stream_1.default.through(); const output = event_stream_1.default.merge(input.pipe((0, gulp_filter_1.default)(['**', ...excludes])), input.pipe((0, gulp_filter_1.default)(includes))); return event_stream_1.default.duplex(input, output); } function loadSourcemaps() { const input = event_stream_1.default.through(); const output = input .pipe(event_stream_1.default.map((f, cb) => { if (f.sourceMap) { cb(undefined, f); return; } if (!f.contents) { cb(undefined, f); return; } const contents = f.contents.toString('utf8'); const reg = /\/\/# sourceMappingURL=(.*)$/g; let lastMatch = null; let match = null; while (match = reg.exec(contents)) { lastMatch = match; } if (!lastMatch) { f.sourceMap = { version: '3', names: [], mappings: '', sources: [f.relative.replace(/\\/g, '/')], sourcesContent: [contents] }; cb(undefined, f); return; } f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8'); fs_1.default.readFile(path_1.default.join(path_1.default.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => { if (err) { return cb(err); } f.sourceMap = JSON.parse(contents); cb(undefined, f); }); })); return event_stream_1.default.duplex(input, output); } function stripSourceMappingURL() { const input = event_stream_1.default.through(); const output = input .pipe(event_stream_1.default.mapSync(f => { const contents = f.contents.toString('utf8'); f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8'); return f; })); return event_stream_1.default.duplex(input, output); } /** Splits items in the stream based on the predicate, sending them to onTrue if true, or onFalse otherwise */ function $if(test, onTrue, onFalse = event_stream_1.default.through()) { if (typeof test === 'boolean') { return test ? onTrue : onFalse; } return (0, ternary_stream_1.default)(test, onTrue, onFalse); } /** Operator that appends the js files' original path a sourceURL, so debug locations map */ function appendOwnPathSourceURL() { const input = event_stream_1.default.through(); const output = input .pipe(event_stream_1.default.mapSync(f => { if (!(f.contents instanceof Buffer)) { throw new Error(`contents of ${f.path} are not a buffer`); } f.contents = Buffer.concat([f.contents, Buffer.from(`\n//# sourceURL=${(0, url_1.pathToFileURL)(f.path)}`)]); return f; })); return event_stream_1.default.duplex(input, output); } function rewriteSourceMappingURL(sourceMappingURLBase) { const input = event_stream_1.default.through(); const output = input .pipe(event_stream_1.default.mapSync(f => { const contents = f.contents.toString('utf8'); const str = `//# sourceMappingURL=${sourceMappingURLBase}/${path_1.default.dirname(f.relative).replace(/\\/g, '/')}/$1`; f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, str)); return f; })); return event_stream_1.default.duplex(input, output); } function rimraf(dir) { const result = () => new Promise((c, e) => { let retries = 0; const retry = () => { (0, rimraf_1.default)(dir, { maxBusyTries: 1 }, (err) => { if (!err) { return c(); } if (err.code === 'ENOTEMPTY' && ++retries < 5) { return setTimeout(() => retry(), 10); } return e(err); }); }; retry(); }); result.taskName = `clean-${path_1.default.basename(dir).toLowerCase()}`; return result; } function _rreaddir(dirPath, prepend, result) { const entries = fs_1.default.readdirSync(dirPath, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory()) { _rreaddir(path_1.default.join(dirPath, entry.name), `${prepend}/${entry.name}`, result); } else { result.push(`${prepend}/${entry.name}`); } } } function rreddir(dirPath) { const result = []; _rreaddir(dirPath, '', result); return result; } function ensureDir(dirPath) { if (fs_1.default.existsSync(dirPath)) { return; } ensureDir(path_1.default.dirname(dirPath)); fs_1.default.mkdirSync(dirPath); } function rebase(count) { return (0, gulp_rename_1.default)(f => { const parts = f.dirname ? f.dirname.split(/[\/\\]/) : []; f.dirname = parts.slice(count).join(path_1.default.sep); }); } function filter(fn) { const result = event_stream_1.default.through(function (data) { if (fn(data)) { this.emit('data', data); } else { result.restore.push(data); } }); result.restore = event_stream_1.default.through(); return result; } function streamToPromise(stream) { return new Promise((c, e) => { stream.on('error', err => e(err)); stream.on('end', () => c()); }); } function getElectronVersion() { const npmrc = fs_1.default.readFileSync(path_1.default.join(root, '.npmrc'), 'utf8'); const electronVersion = /^target="(.*)"$/m.exec(npmrc)[1]; const msBuildId = /^ms_build_id="(.*)"$/m.exec(npmrc)[1]; return { electronVersion, msBuildId }; } //# sourceMappingURL=util.js.map ================================================ FILE: build/lib/util.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import es from 'event-stream'; import _debounce from 'debounce'; import _filter from 'gulp-filter'; import rename from 'gulp-rename'; import path from 'path'; import fs from 'fs'; import _rimraf from 'rimraf'; import VinylFile from 'vinyl'; import { ThroughStream } from 'through'; import sm from 'source-map'; import { pathToFileURL } from 'url'; import ternaryStream from 'ternary-stream'; const root = path.dirname(path.dirname(__dirname)); export interface ICancellationToken { isCancellationRequested(): boolean; } const NoCancellationToken: ICancellationToken = { isCancellationRequested: () => false }; export interface IStreamProvider { (cancellationToken?: ICancellationToken): NodeJS.ReadWriteStream; } export function incremental(streamProvider: IStreamProvider, initial: NodeJS.ReadWriteStream, supportsCancellation?: boolean): NodeJS.ReadWriteStream { const input = es.through(); const output = es.through(); let state = 'idle'; let buffer = Object.create(null); const token: ICancellationToken | undefined = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 }; const run = (input: NodeJS.ReadWriteStream, isCancellable: boolean) => { state = 'running'; const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken); input .pipe(stream) .pipe(es.through(undefined, () => { state = 'idle'; eventuallyRun(); })) .pipe(output); }; if (initial) { run(initial, false); } const eventuallyRun = _debounce(() => { const paths = Object.keys(buffer); if (paths.length === 0) { return; } const data = paths.map(path => buffer[path]); buffer = Object.create(null); run(es.readArray(data), true); }, 500); input.on('data', (f: any) => { buffer[f.path] = f; if (state === 'idle') { eventuallyRun(); } }); return es.duplex(input, output); } export function debounce(task: () => NodeJS.ReadWriteStream, duration = 500): NodeJS.ReadWriteStream { const input = es.through(); const output = es.through(); let state = 'idle'; const run = () => { state = 'running'; task() .pipe(es.through(undefined, () => { const shouldRunAgain = state === 'stale'; state = 'idle'; if (shouldRunAgain) { eventuallyRun(); } })) .pipe(output); }; run(); const eventuallyRun = _debounce(() => run(), duration); input.on('data', () => { if (state === 'idle') { eventuallyRun(); } else { state = 'stale'; } }); return es.duplex(input, output); } export function fixWin32DirectoryPermissions(): NodeJS.ReadWriteStream { if (!/win32/.test(process.platform)) { return es.through(); } return es.mapSync(f => { if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) { f.stat.mode = 16877; } return f; }); } export function setExecutableBit(pattern?: string | string[]): NodeJS.ReadWriteStream { const setBit = es.mapSync(f => { if (!f.stat) { f.stat = { isFile() { return true; } } as any; } f.stat.mode = /* 100755 */ 33261; return f; }); if (!pattern) { return setBit; } const input = es.through(); const filter = _filter(pattern, { restore: true }); const output = input .pipe(filter) .pipe(setBit) .pipe(filter.restore); return es.duplex(input, output); } export function toFileUri(filePath: string): string { const match = filePath.match(/^([a-z])\:(.*)$/i); if (match) { filePath = '/' + match[1].toUpperCase() + ':' + match[2]; } return 'file://' + filePath.replace(/\\/g, '/'); } export function skipDirectories(): NodeJS.ReadWriteStream { return es.mapSync(f => { if (!f.isDirectory()) { return f; } }); } export function cleanNodeModules(rulePath: string): NodeJS.ReadWriteStream { const rules = fs.readFileSync(rulePath, 'utf8') .split(/\r?\n/g) .map(line => line.trim()) .filter(line => line && !/^#/.test(line)); const excludes = rules.filter(line => !/^!/.test(line)).map(line => `!**/node_modules/${line}`); const includes = rules.filter(line => /^!/.test(line)).map(line => `**/node_modules/${line.substr(1)}`); const input = es.through(); const output = es.merge( input.pipe(_filter(['**', ...excludes])), input.pipe(_filter(includes)) ); return es.duplex(input, output); } declare class FileSourceMap extends VinylFile { public sourceMap: sm.RawSourceMap; } export function loadSourcemaps(): NodeJS.ReadWriteStream { const input = es.through(); const output = input .pipe(es.map((f, cb): FileSourceMap | undefined => { if (f.sourceMap) { cb(undefined, f); return; } if (!f.contents) { cb(undefined, f); return; } const contents = (f.contents).toString('utf8'); const reg = /\/\/# sourceMappingURL=(.*)$/g; let lastMatch: RegExpExecArray | null = null; let match: RegExpExecArray | null = null; while (match = reg.exec(contents)) { lastMatch = match; } if (!lastMatch) { f.sourceMap = { version: '3', names: [], mappings: '', sources: [f.relative.replace(/\\/g, '/')], sourcesContent: [contents] }; cb(undefined, f); return; } f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8'); fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => { if (err) { return cb(err); } f.sourceMap = JSON.parse(contents); cb(undefined, f); }); })); return es.duplex(input, output); } export function stripSourceMappingURL(): NodeJS.ReadWriteStream { const input = es.through(); const output = input .pipe(es.mapSync(f => { const contents = (f.contents).toString('utf8'); f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8'); return f; })); return es.duplex(input, output); } /** Splits items in the stream based on the predicate, sending them to onTrue if true, or onFalse otherwise */ export function $if(test: boolean | ((f: VinylFile) => boolean), onTrue: NodeJS.ReadWriteStream, onFalse: NodeJS.ReadWriteStream = es.through()) { if (typeof test === 'boolean') { return test ? onTrue : onFalse; } return ternaryStream(test, onTrue, onFalse); } /** Operator that appends the js files' original path a sourceURL, so debug locations map */ export function appendOwnPathSourceURL(): NodeJS.ReadWriteStream { const input = es.through(); const output = input .pipe(es.mapSync(f => { if (!(f.contents instanceof Buffer)) { throw new Error(`contents of ${f.path} are not a buffer`); } f.contents = Buffer.concat([f.contents, Buffer.from(`\n//# sourceURL=${pathToFileURL(f.path)}`)]); return f; })); return es.duplex(input, output); } export function rewriteSourceMappingURL(sourceMappingURLBase: string): NodeJS.ReadWriteStream { const input = es.through(); const output = input .pipe(es.mapSync(f => { const contents = (f.contents).toString('utf8'); const str = `//# sourceMappingURL=${sourceMappingURLBase}/${path.dirname(f.relative).replace(/\\/g, '/')}/$1`; f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, str)); return f; })); return es.duplex(input, output); } export function rimraf(dir: string): () => Promise { const result = () => new Promise((c, e) => { let retries = 0; const retry = () => { _rimraf(dir, { maxBusyTries: 1 }, (err: any) => { if (!err) { return c(); } if (err.code === 'ENOTEMPTY' && ++retries < 5) { return setTimeout(() => retry(), 10); } return e(err); }); }; retry(); }); result.taskName = `clean-${path.basename(dir).toLowerCase()}`; return result; } function _rreaddir(dirPath: string, prepend: string, result: string[]): void { const entries = fs.readdirSync(dirPath, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory()) { _rreaddir(path.join(dirPath, entry.name), `${prepend}/${entry.name}`, result); } else { result.push(`${prepend}/${entry.name}`); } } } export function rreddir(dirPath: string): string[] { const result: string[] = []; _rreaddir(dirPath, '', result); return result; } export function ensureDir(dirPath: string): void { if (fs.existsSync(dirPath)) { return; } ensureDir(path.dirname(dirPath)); fs.mkdirSync(dirPath); } export function rebase(count: number): NodeJS.ReadWriteStream { return rename(f => { const parts = f.dirname ? f.dirname.split(/[\/\\]/) : []; f.dirname = parts.slice(count).join(path.sep); }); } export interface FilterStream extends NodeJS.ReadWriteStream { restore: ThroughStream; } export function filter(fn: (data: any) => boolean): FilterStream { const result = es.through(function (data) { if (fn(data)) { this.emit('data', data); } else { result.restore.push(data); } }); result.restore = es.through(); return result; } export function streamToPromise(stream: NodeJS.ReadWriteStream): Promise { return new Promise((c, e) => { stream.on('error', err => e(err)); stream.on('end', () => c()); }); } export function getElectronVersion(): Record { const npmrc = fs.readFileSync(path.join(root, '.npmrc'), 'utf8'); const electronVersion = /^target="(.*)"$/m.exec(npmrc)![1]; const msBuildId = /^ms_build_id="(.*)"$/m.exec(npmrc)![1]; return { electronVersion, msBuildId }; } ================================================ FILE: build/lib/watch/index.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const watch = process.platform === 'win32' ? require('./watch-win32') : require('vscode-gulp-watch'); module.exports = function () { return watch.apply(null, arguments); }; //# sourceMappingURL=index.js.map ================================================ FILE: build/lib/watch/index.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const watch = process.platform === 'win32' ? require('./watch-win32') : require('vscode-gulp-watch'); module.exports = function () { return watch.apply(null, arguments); }; ================================================ FILE: build/lib/watch/watch-win32.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const child_process_1 = __importDefault(require("child_process")); const fs_1 = __importDefault(require("fs")); const vinyl_1 = __importDefault(require("vinyl")); const event_stream_1 = __importDefault(require("event-stream")); const gulp_filter_1 = __importDefault(require("gulp-filter")); const watcherPath = path_1.default.join(__dirname, 'watcher.exe'); function toChangeType(type) { switch (type) { case '0': return 'change'; case '1': return 'add'; default: return 'unlink'; } } function watch(root) { const result = event_stream_1.default.through(); let child = child_process_1.default.spawn(watcherPath, [root]); child.stdout.on('data', function (data) { const lines = data.toString('utf8').split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.length === 0) { continue; } const changeType = line[0]; const changePath = line.substr(2); // filter as early as possible if (/^\.git/.test(changePath) || /(^|\\)out($|\\)/.test(changePath)) { continue; } const changePathFull = path_1.default.join(root, changePath); const file = new vinyl_1.default({ path: changePathFull, base: root }); file.event = toChangeType(changeType); result.emit('data', file); } }); child.stderr.on('data', function (data) { result.emit('error', data); }); child.on('exit', function (code) { result.emit('error', 'Watcher died with code ' + code); child = null; }); process.once('SIGTERM', function () { process.exit(0); }); process.once('SIGTERM', function () { process.exit(0); }); process.once('exit', function () { if (child) { child.kill(); } }); return result; } const cache = Object.create(null); module.exports = function (pattern, options) { options = options || {}; const cwd = path_1.default.normalize(options.cwd || process.cwd()); let watcher = cache[cwd]; if (!watcher) { watcher = cache[cwd] = watch(cwd); } const rebase = !options.base ? event_stream_1.default.through() : event_stream_1.default.mapSync(function (f) { f.base = options.base; return f; }); return watcher .pipe((0, gulp_filter_1.default)(['**', '!.git{,/**}'], { dot: options.dot })) // ignore all things git .pipe((0, gulp_filter_1.default)(pattern, { dot: options.dot })) .pipe(event_stream_1.default.map(function (file, cb) { fs_1.default.stat(file.path, function (err, stat) { if (err && err.code === 'ENOENT') { return cb(undefined, file); } if (err) { return cb(); } if (!stat.isFile()) { return cb(); } fs_1.default.readFile(file.path, function (err, contents) { if (err && err.code === 'ENOENT') { return cb(undefined, file); } if (err) { return cb(); } file.contents = contents; file.stat = stat; cb(undefined, file); }); }); })) .pipe(rebase); }; //# sourceMappingURL=watch-win32.js.map ================================================ FILE: build/lib/watch/watch-win32.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path from 'path'; import cp from 'child_process'; import fs from 'fs'; import File from 'vinyl'; import es from 'event-stream'; import filter from 'gulp-filter'; import { Stream } from 'stream'; const watcherPath = path.join(__dirname, 'watcher.exe'); function toChangeType(type: '0' | '1' | '2'): 'change' | 'add' | 'unlink' { switch (type) { case '0': return 'change'; case '1': return 'add'; default: return 'unlink'; } } function watch(root: string): Stream { const result = es.through(); let child: cp.ChildProcess | null = cp.spawn(watcherPath, [root]); child.stdout!.on('data', function (data) { const lines: string[] = data.toString('utf8').split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.length === 0) { continue; } const changeType = <'0' | '1' | '2'>line[0]; const changePath = line.substr(2); // filter as early as possible if (/^\.git/.test(changePath) || /(^|\\)out($|\\)/.test(changePath)) { continue; } const changePathFull = path.join(root, changePath); const file = new File({ path: changePathFull, base: root }); (file).event = toChangeType(changeType); result.emit('data', file); } }); child.stderr!.on('data', function (data) { result.emit('error', data); }); child.on('exit', function (code) { result.emit('error', 'Watcher died with code ' + code); child = null; }); process.once('SIGTERM', function () { process.exit(0); }); process.once('SIGTERM', function () { process.exit(0); }); process.once('exit', function () { if (child) { child.kill(); } }); return result; } const cache: { [cwd: string]: Stream } = Object.create(null); module.exports = function (pattern: string | string[] | filter.FileFunction, options?: { cwd?: string; base?: string; dot?: boolean }) { options = options || {}; const cwd = path.normalize(options.cwd || process.cwd()); let watcher = cache[cwd]; if (!watcher) { watcher = cache[cwd] = watch(cwd); } const rebase = !options.base ? es.through() : es.mapSync(function (f: File) { f.base = options!.base!; return f; }); return watcher .pipe(filter(['**', '!.git{,/**}'], { dot: options.dot })) // ignore all things git .pipe(filter(pattern, { dot: options.dot })) .pipe(es.map(function (file: File, cb) { fs.stat(file.path, function (err, stat) { if (err && err.code === 'ENOENT') { return cb(undefined, file); } if (err) { return cb(); } if (!stat.isFile()) { return cb(); } fs.readFile(file.path, function (err, contents) { if (err && err.code === 'ENOENT') { return cb(undefined, file); } if (err) { return cb(); } file.contents = contents; file.stat = stat; cb(undefined, file); }); }); })) .pipe(rebase); }; ================================================ FILE: build/linux/debian/calculate-deps.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generatePackageDeps = generatePackageDeps; const child_process_1 = require("child_process"); const fs_1 = require("fs"); const os_1 = require("os"); const path_1 = __importDefault(require("path")); const cgmanifest_json_1 = __importDefault(require("../../../cgmanifest.json")); const dep_lists_1 = require("./dep-lists"); function generatePackageDeps(files, arch, chromiumSysroot, vscodeSysroot) { const dependencies = files.map(file => calculatePackageDeps(file, arch, chromiumSysroot, vscodeSysroot)); const additionalDepsSet = new Set(dep_lists_1.additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. function calculatePackageDeps(binaryPath, arch, chromiumSysroot, vscodeSysroot) { try { if (!((0, fs_1.statSync)(binaryPath).mode & fs_1.constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); } } catch (e) { // The package might not exist. Don't re-throw the error here. console.error('Tried to stat ' + binaryPath + ' but failed.'); } // Get the Chromium dpkg-shlibdeps file. const chromiumManifest = cgmanifest_json_1.default.registrations.filter(registration => { return registration.component.type === 'git' && registration.component.git.name === 'chromium'; }); const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`; const dpkgShlibdepsScriptLocation = `${(0, os_1.tmpdir)()}/dpkg-shlibdeps.pl`; const result = (0, child_process_1.spawnSync)('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); if (result.status !== 0) { throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr); } const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; switch (arch) { case 'amd64': cmd.push(`-l${chromiumSysroot}/usr/lib/x86_64-linux-gnu`, `-l${chromiumSysroot}/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/lib/x86_64-linux-gnu`); break; case 'armhf': cmd.push(`-l${chromiumSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${chromiumSysroot}/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/lib/arm-linux-gnueabihf`); break; case 'arm64': cmd.push(`-l${chromiumSysroot}/usr/lib/aarch64-linux-gnu`, `-l${chromiumSysroot}/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/lib/aarch64-linux-gnu`); break; } cmd.push(`-l${chromiumSysroot}/usr/lib`); cmd.push(`-L${vscodeSysroot}/debian/libxkbfile1/DEBIAN/shlibs`); cmd.push('-O', '-e', path_1.default.resolve(binaryPath)); const dpkgShlibdepsResult = (0, child_process_1.spawnSync)('perl', cmd, { cwd: chromiumSysroot }); if (dpkgShlibdepsResult.status !== 0) { throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); } const shlibsDependsPrefix = 'shlibs:Depends='; const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n'); let depsStr = ''; for (const line of requiresList) { if (line.startsWith(shlibsDependsPrefix)) { depsStr = line.substring(shlibsDependsPrefix.length); } } // Refs https://chromium-review.googlesource.com/c/chromium/src/+/3572926 // Chromium depends on libgcc_s, is from the package libgcc1. However, in // Bullseye, the package was renamed to libgcc-s1. To avoid adding a dep // on the newer package, this hack skips the dep. This is safe because // libgcc-s1 is a dependency of libc6. This hack can be removed once // support for Debian Buster and Ubuntu Bionic are dropped. // // Remove kerberos native module related dependencies as the versions // computed from sysroot will not satisfy the minimum supported distros // Refs https://github.com/microsoft/vscode/issues/188881. // TODO(deepak1556): remove this workaround in favor of computing the // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { return !dependency.startsWith('libgcc-s1'); }).sort(); const requires = new Set(filteredDeps); return requires; } //# sourceMappingURL=calculate-deps.js.map ================================================ FILE: build/linux/debian/calculate-deps.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawnSync } from 'child_process'; import { constants, statSync } from 'fs'; import { tmpdir } from 'os'; import path from 'path'; import manifests from '../../../cgmanifest.json'; import { additionalDeps } from './dep-lists'; import { DebianArchString } from './types'; export function generatePackageDeps(files: string[], arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: string): Set[] { const dependencies: Set[] = files.map(file => calculatePackageDeps(file, arch, chromiumSysroot, vscodeSysroot)); const additionalDepsSet = new Set(additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. function calculatePackageDeps(binaryPath: string, arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: string): Set { try { if (!(statSync(binaryPath).mode & constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); } } catch (e) { // The package might not exist. Don't re-throw the error here. console.error('Tried to stat ' + binaryPath + ' but failed.'); } // Get the Chromium dpkg-shlibdeps file. const chromiumManifest = manifests.registrations.filter(registration => { return registration.component.type === 'git' && registration.component.git!.name === 'chromium'; }); const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`; const dpkgShlibdepsScriptLocation = `${tmpdir()}/dpkg-shlibdeps.pl`; const result = spawnSync('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); if (result.status !== 0) { throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr); } const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; switch (arch) { case 'amd64': cmd.push(`-l${chromiumSysroot}/usr/lib/x86_64-linux-gnu`, `-l${chromiumSysroot}/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/lib/x86_64-linux-gnu`); break; case 'armhf': cmd.push(`-l${chromiumSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${chromiumSysroot}/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/lib/arm-linux-gnueabihf`); break; case 'arm64': cmd.push(`-l${chromiumSysroot}/usr/lib/aarch64-linux-gnu`, `-l${chromiumSysroot}/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/lib/aarch64-linux-gnu`); break; } cmd.push(`-l${chromiumSysroot}/usr/lib`); cmd.push(`-L${vscodeSysroot}/debian/libxkbfile1/DEBIAN/shlibs`); cmd.push('-O', '-e', path.resolve(binaryPath)); const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: chromiumSysroot }); if (dpkgShlibdepsResult.status !== 0) { throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); } const shlibsDependsPrefix = 'shlibs:Depends='; const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n'); let depsStr = ''; for (const line of requiresList) { if (line.startsWith(shlibsDependsPrefix)) { depsStr = line.substring(shlibsDependsPrefix.length); } } // Refs https://chromium-review.googlesource.com/c/chromium/src/+/3572926 // Chromium depends on libgcc_s, is from the package libgcc1. However, in // Bullseye, the package was renamed to libgcc-s1. To avoid adding a dep // on the newer package, this hack skips the dep. This is safe because // libgcc-s1 is a dependency of libc6. This hack can be removed once // support for Debian Buster and Ubuntu Bionic are dropped. // // Remove kerberos native module related dependencies as the versions // computed from sysroot will not satisfy the minimum supported distros // Refs https://github.com/microsoft/vscode/issues/188881. // TODO(deepak1556): remove this workaround in favor of computing the // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { return !dependency.startsWith('libgcc-s1'); }).sort(); const requires = new Set(filteredDeps); return requires; } ================================================ FILE: build/linux/debian/dep-lists.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.referenceGeneratedDepsByArch = exports.recommendedDeps = exports.additionalDeps = void 0; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps // Additional dependencies not in the dpkg-shlibdeps output. exports.additionalDeps = [ 'ca-certificates', // Make sure users have SSL certificates. 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. 'xdg-utils (>= 1.0.2)', // OS integration ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends // Dependencies that we can only recommend // for now since some of the older distros don't support them. exports.recommendedDeps = [ 'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped. ]; exports.referenceGeneratedDepsByArch = { 'amd64': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], 'armhf': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], 'arm64': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ] }; //# sourceMappingURL=dep-lists.js.map ================================================ FILE: build/linux/debian/dep-lists.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps // Additional dependencies not in the dpkg-shlibdeps output. export const additionalDeps = [ 'ca-certificates', // Make sure users have SSL certificates. 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. 'xdg-utils (>= 1.0.2)', // OS integration ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends // Dependencies that we can only recommend // for now since some of the older distros don't support them. export const recommendedDeps = [ 'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped. ]; export const referenceGeneratedDepsByArch = { 'amd64': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], 'armhf': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], 'arm64': [ 'ca-certificates', 'libasound2 (>= 1.0.17)', 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.11.90)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libc6 (>= 2.25)', 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libudev1 (>= 183)', 'libx11-6', 'libx11-6 (>= 2:1.4.99.1)', 'libxcb1 (>= 1.9.2)', 'libxcomposite1 (>= 1:0.4.4-1)', 'libxdamage1 (>= 1:1.1)', 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ] }; ================================================ FILE: build/linux/debian/install-sysroot.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVSCodeSysroot = getVSCodeSysroot; exports.getChromiumSysroot = getChromiumSysroot; const child_process_1 = require("child_process"); const os_1 = require("os"); const fs_1 = __importDefault(require("fs")); const https_1 = __importDefault(require("https")); const path_1 = __importDefault(require("path")); const crypto_1 = require("crypto"); const ansi_colors_1 = __importDefault(require("ansi-colors")); // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectronbuild.z5.web.core.windows.net'; const URL_PATH = 'sysroots/toolchain'; const REPO_ROOT = path_1.default.dirname(path_1.default.dirname(path_1.default.dirname(__dirname))); const ghApiHeaders = { Accept: 'application/vnd.github.v3+json', 'User-Agent': 'VSCode Build', }; if (process.env.GITHUB_TOKEN) { ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); } const ghDownloadHeaders = { ...ghApiHeaders, Accept: 'application/octet-stream', }; function getElectronVersion() { const npmrc = fs_1.default.readFileSync(path_1.default.join(REPO_ROOT, '.npmrc'), 'utf8'); const electronVersion = /^target="(.*)"$/m.exec(npmrc)[1]; const msBuildId = /^ms_build_id="(.*)"$/m.exec(npmrc)[1]; return { electronVersion, msBuildId }; } function getSha(filename) { const hash = (0, crypto_1.createHash)('sha256'); // Read file 1 MB at a time const fd = fs_1.default.openSync(filename, 'r'); const buffer = Buffer.alloc(1024 * 1024); let position = 0; let bytesRead = 0; while ((bytesRead = fs_1.default.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) { hash.update(buffer); position += bytesRead; } hash.update(buffer.slice(0, bytesRead)); return hash.digest('hex'); } function getVSCodeSysrootChecksum(expectedName) { const checksums = fs_1.default.readFileSync(path_1.default.join(REPO_ROOT, 'build', 'checksums', 'vscode-sysroot.txt'), 'utf8'); for (const line of checksums.split('\n')) { const [checksum, name] = line.split(/\s+/); if (name === expectedName) { return checksum; } } return undefined; } /* * Do not use the fetch implementation from build/lib/fetch as it relies on vinyl streams * and vinyl-fs breaks the symlinks in the compiler toolchain sysroot. We use the native * tar implementation for that reason. */ async function fetchUrl(options, retries = 10, retryDelay = 1000) { try { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 30 * 1000); const version = '20240129-253798'; try { const response = await fetch(`https://api.github.com/repos/Microsoft/vscode-linux-build-agent/releases/tags/v${version}`, { headers: ghApiHeaders, signal: controller.signal /* Typings issue with lib.dom.d.ts */ }); if (response.ok && (response.status >= 200 && response.status < 300)) { console.log(`Fetch completed: Status ${response.status}.`); const contents = Buffer.from(await response.arrayBuffer()); const asset = JSON.parse(contents.toString()).assets.find((a) => a.name === options.assetName); if (!asset) { throw new Error(`Could not find asset in release of Microsoft/vscode-linux-build-agent @ ${version}`); } console.log(`Found asset ${options.assetName} @ ${asset.url}.`); const assetResponse = await fetch(asset.url, { headers: ghDownloadHeaders }); if (assetResponse.ok && (assetResponse.status >= 200 && assetResponse.status < 300)) { const assetContents = Buffer.from(await assetResponse.arrayBuffer()); console.log(`Fetched response body buffer: ${ansi_colors_1.default.magenta(`${assetContents.byteLength} bytes`)}`); if (options.checksumSha256) { const actualSHA256Checksum = (0, crypto_1.createHash)('sha256').update(assetContents).digest('hex'); if (actualSHA256Checksum !== options.checksumSha256) { throw new Error(`Checksum mismatch for ${ansi_colors_1.default.cyan(asset.url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); } } console.log(`Verified SHA256 checksums match for ${ansi_colors_1.default.cyan(asset.url)}`); const tarCommand = `tar -xz -C ${options.dest}`; (0, child_process_1.execSync)(tarCommand, { input: assetContents }); console.log(`Fetch complete!`); return; } throw new Error(`Request ${ansi_colors_1.default.magenta(asset.url)} failed with status code: ${assetResponse.status}`); } throw new Error(`Request ${ansi_colors_1.default.magenta('https://api.github.com')} failed with status code: ${response.status}`); } finally { clearTimeout(timeout); } } catch (e) { if (retries > 0) { console.log(`Fetching failed: ${e}`); await new Promise(resolve => setTimeout(resolve, retryDelay)); return fetchUrl(options, retries - 1, retryDelay); } throw e; } } async function getVSCodeSysroot(arch) { let expectedName; let triple; const prefix = process.env['VSCODE_SYSROOT_PREFIX'] ?? '-glibc-2.28'; switch (arch) { case 'amd64': expectedName = `x86_64-linux-gnu${prefix}.tar.gz`; triple = 'x86_64-linux-gnu'; break; case 'arm64': expectedName = `aarch64-linux-gnu${prefix}.tar.gz`; triple = 'aarch64-linux-gnu'; break; case 'armhf': expectedName = `arm-rpi-linux-gnueabihf${prefix}.tar.gz`; triple = 'arm-rpi-linux-gnueabihf'; break; } console.log(`Fetching ${expectedName} for ${triple}`); const checksumSha256 = getVSCodeSysrootChecksum(expectedName); if (!checksumSha256) { throw new Error(`Could not find checksum for ${expectedName}`); } const sysroot = process.env['VSCODE_SYSROOT_DIR'] ?? path_1.default.join((0, os_1.tmpdir)(), `vscode-${arch}-sysroot`); const stamp = path_1.default.join(sysroot, '.stamp'); const result = `${sysroot}/${triple}/${triple}/sysroot`; if (fs_1.default.existsSync(stamp) && fs_1.default.readFileSync(stamp).toString() === expectedName) { return result; } console.log(`Installing ${arch} root image: ${sysroot}`); fs_1.default.rmSync(sysroot, { recursive: true, force: true }); fs_1.default.mkdirSync(sysroot); await fetchUrl({ checksumSha256, assetName: expectedName, dest: sysroot }); fs_1.default.writeFileSync(stamp, expectedName); return result; } async function getChromiumSysroot(arch) { const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${getElectronVersion().electronVersion}/script/sysroots.json`; const sysrootDictLocation = `${(0, os_1.tmpdir)()}/sysroots.json`; const result = (0, child_process_1.spawnSync)('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); if (result.status !== 0) { throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); } const sysrootInfo = require(sysrootDictLocation); const sysrootArch = `bullseye_${arch}`; const sysrootDict = sysrootInfo[sysrootArch]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha256Sum']; const sysroot = path_1.default.join((0, os_1.tmpdir)(), sysrootDict['SysrootDir']); const url = [URL_PREFIX, URL_PATH, tarballSha].join('/'); const stamp = path_1.default.join(sysroot, '.stamp'); if (fs_1.default.existsSync(stamp) && fs_1.default.readFileSync(stamp).toString() === url) { return sysroot; } console.log(`Installing Debian ${arch} root image: ${sysroot}`); fs_1.default.rmSync(sysroot, { recursive: true, force: true }); fs_1.default.mkdirSync(sysroot); const tarball = path_1.default.join(sysroot, tarballFilename); console.log(`Downloading ${url}`); let downloadSuccess = false; for (let i = 0; i < 3 && !downloadSuccess; i++) { fs_1.default.writeFileSync(tarball, ''); await new Promise((c) => { https_1.default.get(url, (res) => { res.on('data', (chunk) => { fs_1.default.appendFileSync(tarball, chunk); }); res.on('end', () => { downloadSuccess = true; c(); }); }).on('error', (err) => { console.error('Encountered an error during the download attempt: ' + err.message); c(); }); }); } if (!downloadSuccess) { fs_1.default.rmSync(tarball); throw new Error('Failed to download ' + url); } const sha = getSha(tarball); if (sha !== tarballSha) { throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`); } const proc = (0, child_process_1.spawnSync)('tar', ['xf', tarball, '-C', sysroot]); if (proc.status) { throw new Error('Tarball extraction failed with code ' + proc.status); } fs_1.default.rmSync(tarball); fs_1.default.writeFileSync(stamp, url); return sysroot; } //# sourceMappingURL=install-sysroot.js.map ================================================ FILE: build/linux/debian/install-sysroot.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawnSync, execSync } from 'child_process'; import { tmpdir } from 'os'; import fs from 'fs'; import https from 'https'; import path from 'path'; import { createHash } from 'crypto'; import { DebianArchString } from './types'; import ansiColors from 'ansi-colors'; // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectronbuild.z5.web.core.windows.net'; const URL_PATH = 'sysroots/toolchain'; const REPO_ROOT = path.dirname(path.dirname(path.dirname(__dirname))); const ghApiHeaders: Record = { Accept: 'application/vnd.github.v3+json', 'User-Agent': 'VSCode Build', }; if (process.env.GITHUB_TOKEN) { ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); } const ghDownloadHeaders = { ...ghApiHeaders, Accept: 'application/octet-stream', }; interface IFetchOptions { assetName: string; checksumSha256?: string; dest: string; } function getElectronVersion(): Record { const npmrc = fs.readFileSync(path.join(REPO_ROOT, '.npmrc'), 'utf8'); const electronVersion = /^target="(.*)"$/m.exec(npmrc)![1]; const msBuildId = /^ms_build_id="(.*)"$/m.exec(npmrc)![1]; return { electronVersion, msBuildId }; } function getSha(filename: fs.PathLike): string { const hash = createHash('sha256'); // Read file 1 MB at a time const fd = fs.openSync(filename, 'r'); const buffer = Buffer.alloc(1024 * 1024); let position = 0; let bytesRead = 0; while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) { hash.update(buffer); position += bytesRead; } hash.update(buffer.slice(0, bytesRead)); return hash.digest('hex'); } function getVSCodeSysrootChecksum(expectedName: string) { const checksums = fs.readFileSync(path.join(REPO_ROOT, 'build', 'checksums', 'vscode-sysroot.txt'), 'utf8'); for (const line of checksums.split('\n')) { const [checksum, name] = line.split(/\s+/); if (name === expectedName) { return checksum; } } return undefined; } /* * Do not use the fetch implementation from build/lib/fetch as it relies on vinyl streams * and vinyl-fs breaks the symlinks in the compiler toolchain sysroot. We use the native * tar implementation for that reason. */ async function fetchUrl(options: IFetchOptions, retries = 10, retryDelay = 1000): Promise { try { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 30 * 1000); const version = '20240129-253798'; try { const response = await fetch(`https://api.github.com/repos/Microsoft/vscode-linux-build-agent/releases/tags/v${version}`, { headers: ghApiHeaders, signal: controller.signal as any /* Typings issue with lib.dom.d.ts */ }); if (response.ok && (response.status >= 200 && response.status < 300)) { console.log(`Fetch completed: Status ${response.status}.`); const contents = Buffer.from(await response.arrayBuffer()); const asset = JSON.parse(contents.toString()).assets.find((a: { name: string }) => a.name === options.assetName); if (!asset) { throw new Error(`Could not find asset in release of Microsoft/vscode-linux-build-agent @ ${version}`); } console.log(`Found asset ${options.assetName} @ ${asset.url}.`); const assetResponse = await fetch(asset.url, { headers: ghDownloadHeaders }); if (assetResponse.ok && (assetResponse.status >= 200 && assetResponse.status < 300)) { const assetContents = Buffer.from(await assetResponse.arrayBuffer()); console.log(`Fetched response body buffer: ${ansiColors.magenta(`${(assetContents as Buffer).byteLength} bytes`)}`); if (options.checksumSha256) { const actualSHA256Checksum = createHash('sha256').update(assetContents).digest('hex'); if (actualSHA256Checksum !== options.checksumSha256) { throw new Error(`Checksum mismatch for ${ansiColors.cyan(asset.url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); } } console.log(`Verified SHA256 checksums match for ${ansiColors.cyan(asset.url)}`); const tarCommand = `tar -xz -C ${options.dest}`; execSync(tarCommand, { input: assetContents }); console.log(`Fetch complete!`); return; } throw new Error(`Request ${ansiColors.magenta(asset.url)} failed with status code: ${assetResponse.status}`); } throw new Error(`Request ${ansiColors.magenta('https://api.github.com')} failed with status code: ${response.status}`); } finally { clearTimeout(timeout); } } catch (e) { if (retries > 0) { console.log(`Fetching failed: ${e}`); await new Promise(resolve => setTimeout(resolve, retryDelay)); return fetchUrl(options, retries - 1, retryDelay); } throw e; } } type SysrootDictEntry = { Sha256Sum: string; SysrootDir: string; Tarball: string; }; export async function getVSCodeSysroot(arch: DebianArchString): Promise { let expectedName: string; let triple: string; const prefix = process.env['VSCODE_SYSROOT_PREFIX'] ?? '-glibc-2.28'; switch (arch) { case 'amd64': expectedName = `x86_64-linux-gnu${prefix}.tar.gz`; triple = 'x86_64-linux-gnu'; break; case 'arm64': expectedName = `aarch64-linux-gnu${prefix}.tar.gz`; triple = 'aarch64-linux-gnu'; break; case 'armhf': expectedName = `arm-rpi-linux-gnueabihf${prefix}.tar.gz`; triple = 'arm-rpi-linux-gnueabihf'; break; } console.log(`Fetching ${expectedName} for ${triple}`); const checksumSha256 = getVSCodeSysrootChecksum(expectedName); if (!checksumSha256) { throw new Error(`Could not find checksum for ${expectedName}`); } const sysroot = process.env['VSCODE_SYSROOT_DIR'] ?? path.join(tmpdir(), `vscode-${arch}-sysroot`); const stamp = path.join(sysroot, '.stamp'); const result = `${sysroot}/${triple}/${triple}/sysroot`; if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === expectedName) { return result; } console.log(`Installing ${arch} root image: ${sysroot}`); fs.rmSync(sysroot, { recursive: true, force: true }); fs.mkdirSync(sysroot); await fetchUrl({ checksumSha256, assetName: expectedName, dest: sysroot }); fs.writeFileSync(stamp, expectedName); return result; } export async function getChromiumSysroot(arch: DebianArchString): Promise { const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${getElectronVersion().electronVersion}/script/sysroots.json`; const sysrootDictLocation = `${tmpdir()}/sysroots.json`; const result = spawnSync('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); if (result.status !== 0) { throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); } const sysrootInfo = require(sysrootDictLocation); const sysrootArch = `bullseye_${arch}`; const sysrootDict: SysrootDictEntry = sysrootInfo[sysrootArch]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha256Sum']; const sysroot = path.join(tmpdir(), sysrootDict['SysrootDir']); const url = [URL_PREFIX, URL_PATH, tarballSha].join('/'); const stamp = path.join(sysroot, '.stamp'); if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === url) { return sysroot; } console.log(`Installing Debian ${arch} root image: ${sysroot}`); fs.rmSync(sysroot, { recursive: true, force: true }); fs.mkdirSync(sysroot); const tarball = path.join(sysroot, tarballFilename); console.log(`Downloading ${url}`); let downloadSuccess = false; for (let i = 0; i < 3 && !downloadSuccess; i++) { fs.writeFileSync(tarball, ''); await new Promise((c) => { https.get(url, (res) => { res.on('data', (chunk) => { fs.appendFileSync(tarball, chunk); }); res.on('end', () => { downloadSuccess = true; c(); }); }).on('error', (err) => { console.error('Encountered an error during the download attempt: ' + err.message); c(); }); }); } if (!downloadSuccess) { fs.rmSync(tarball); throw new Error('Failed to download ' + url); } const sha = getSha(tarball); if (sha !== tarballSha) { throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`); } const proc = spawnSync('tar', ['xf', tarball, '-C', sysroot]); if (proc.status) { throw new Error('Tarball extraction failed with code ' + proc.status); } fs.rmSync(tarball); fs.writeFileSync(stamp, url); return sysroot; } ================================================ FILE: build/linux/debian/types.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.isDebianArchString = isDebianArchString; function isDebianArchString(s) { return ['amd64', 'armhf', 'arm64'].includes(s); } //# sourceMappingURL=types.js.map ================================================ FILE: build/linux/debian/types.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export type DebianArchString = 'amd64' | 'armhf' | 'arm64'; export function isDebianArchString(s: string): s is DebianArchString { return ['amd64', 'armhf', 'arm64'].includes(s); } ================================================ FILE: build/linux/dependencies-generator.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDependencies = getDependencies; const child_process_1 = require("child_process"); const path_1 = __importDefault(require("path")); const install_sysroot_1 = require("./debian/install-sysroot"); const calculate_deps_1 = require("./debian/calculate-deps"); const calculate_deps_2 = require("./rpm/calculate-deps"); const dep_lists_1 = require("./debian/dep-lists"); const dep_lists_2 = require("./rpm/dep-lists"); const types_1 = require("./debian/types"); const types_2 = require("./rpm/types"); const product = require("../../product.json"); // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. // If false, we warn about new dependencies if they show up // while running the prepare package tasks for a release. // If true, we fail the build if there are new dependencies found during that task. // The reference dependencies, which one has to update when the new dependencies // are valid, are in dep-lists.ts const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true; // Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:chrome/installer/linux/BUILD.gn;l=64-80 // and the Linux Archive build // Shared library dependencies that we already bundle. const bundledDeps = [ 'libEGL.so', 'libGLESv2.so', 'libvulkan.so.1', 'libvk_swiftshader.so', 'libffmpeg.so' ]; async function getDependencies(packageType, buildDir, applicationName, arch) { if (packageType === 'deb') { if (!(0, types_1.isDebianArchString)(arch)) { throw new Error('Invalid Debian arch string ' + arch); } } if (packageType === 'rpm' && !(0, types_2.isRpmArchString)(arch)) { throw new Error('Invalid RPM arch string ' + arch); } // Get the files for which we want to find dependencies. const canAsar = false; // TODO@esm ASAR disabled in ESM const nativeModulesPath = path_1.default.join(buildDir, 'resources', 'app', canAsar ? 'node_modules.asar.unpacked' : 'node_modules'); const findResult = (0, child_process_1.spawnSync)('find', [nativeModulesPath, '-name', '*.node']); if (findResult.status) { console.error('Error finding files:'); console.error(findResult.stderr.toString()); return []; } const appPath = path_1.default.join(buildDir, applicationName); // Add the native modules const files = findResult.stdout.toString().trimEnd().split('\n'); // Add the tunnel binary. files.push(path_1.default.join(buildDir, 'bin', product.tunnelApplicationName)); // Add the main executable. files.push(appPath); // Add chrome sandbox and crashpad handler. files.push(path_1.default.join(buildDir, 'chrome-sandbox')); files.push(path_1.default.join(buildDir, 'chrome_crashpad_handler')); // Generate the dependencies. let dependencies; if (packageType === 'deb') { const chromiumSysroot = await (0, install_sysroot_1.getChromiumSysroot)(arch); const vscodeSysroot = await (0, install_sysroot_1.getVSCodeSysroot)(arch); dependencies = (0, calculate_deps_1.generatePackageDeps)(files, arch, chromiumSysroot, vscodeSysroot); } else { dependencies = (0, calculate_deps_2.generatePackageDeps)(files); } // Merge all the dependencies. const mergedDependencies = mergePackageDeps(dependencies); // Exclude bundled dependencies and sort const sortedDependencies = Array.from(mergedDependencies).filter(dependency => { return !bundledDeps.some(bundledDep => dependency.startsWith(bundledDep)); }).sort(); const referenceGeneratedDeps = packageType === 'deb' ? dep_lists_1.referenceGeneratedDepsByArch[arch] : dep_lists_2.referenceGeneratedDepsByArch[arch]; if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) { const failMessage = 'The dependencies list has changed.' + '\nOld:\n' + referenceGeneratedDeps.join('\n') + '\nNew:\n' + sortedDependencies.join('\n'); if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) { throw new Error(failMessage); } else { console.warn(failMessage); } } return sortedDependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. function mergePackageDeps(inputDeps) { const requires = new Set(); for (const depSet of inputDeps) { for (const dep of depSet) { const trimmedDependency = dep.trim(); if (trimmedDependency.length && !trimmedDependency.startsWith('#')) { requires.add(trimmedDependency); } } } return requires; } //# sourceMappingURL=dependencies-generator.js.map ================================================ FILE: build/linux/dependencies-generator.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import { spawnSync } from 'child_process'; import path from 'path'; import { getChromiumSysroot, getVSCodeSysroot } from './debian/install-sysroot'; import { generatePackageDeps as generatePackageDepsDebian } from './debian/calculate-deps'; import { generatePackageDeps as generatePackageDepsRpm } from './rpm/calculate-deps'; import { referenceGeneratedDepsByArch as debianGeneratedDeps } from './debian/dep-lists'; import { referenceGeneratedDepsByArch as rpmGeneratedDeps } from './rpm/dep-lists'; import { DebianArchString, isDebianArchString } from './debian/types'; import { isRpmArchString, RpmArchString } from './rpm/types'; import product = require('../../product.json'); // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. // If false, we warn about new dependencies if they show up // while running the prepare package tasks for a release. // If true, we fail the build if there are new dependencies found during that task. // The reference dependencies, which one has to update when the new dependencies // are valid, are in dep-lists.ts const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true; // Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/132.0.6834.210:chrome/installer/linux/BUILD.gn;l=64-80 // and the Linux Archive build // Shared library dependencies that we already bundle. const bundledDeps = [ 'libEGL.so', 'libGLESv2.so', 'libvulkan.so.1', 'libvk_swiftshader.so', 'libffmpeg.so' ]; export async function getDependencies(packageType: 'deb' | 'rpm', buildDir: string, applicationName: string, arch: string): Promise { if (packageType === 'deb') { if (!isDebianArchString(arch)) { throw new Error('Invalid Debian arch string ' + arch); } } if (packageType === 'rpm' && !isRpmArchString(arch)) { throw new Error('Invalid RPM arch string ' + arch); } // Get the files for which we want to find dependencies. const canAsar = false; // TODO@esm ASAR disabled in ESM const nativeModulesPath = path.join(buildDir, 'resources', 'app', canAsar ? 'node_modules.asar.unpacked' : 'node_modules'); const findResult = spawnSync('find', [nativeModulesPath, '-name', '*.node']); if (findResult.status) { console.error('Error finding files:'); console.error(findResult.stderr.toString()); return []; } const appPath = path.join(buildDir, applicationName); // Add the native modules const files = findResult.stdout.toString().trimEnd().split('\n'); // Add the tunnel binary. files.push(path.join(buildDir, 'bin', product.tunnelApplicationName)); // Add the main executable. files.push(appPath); // Add chrome sandbox and crashpad handler. files.push(path.join(buildDir, 'chrome-sandbox')); files.push(path.join(buildDir, 'chrome_crashpad_handler')); // Generate the dependencies. let dependencies: Set[]; if (packageType === 'deb') { const chromiumSysroot = await getChromiumSysroot(arch as DebianArchString); const vscodeSysroot = await getVSCodeSysroot(arch as DebianArchString); dependencies = generatePackageDepsDebian(files, arch as DebianArchString, chromiumSysroot, vscodeSysroot); } else { dependencies = generatePackageDepsRpm(files); } // Merge all the dependencies. const mergedDependencies = mergePackageDeps(dependencies); // Exclude bundled dependencies and sort const sortedDependencies: string[] = Array.from(mergedDependencies).filter(dependency => { return !bundledDeps.some(bundledDep => dependency.startsWith(bundledDep)); }).sort(); const referenceGeneratedDeps = packageType === 'deb' ? debianGeneratedDeps[arch as DebianArchString] : rpmGeneratedDeps[arch as RpmArchString]; if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) { const failMessage = 'The dependencies list has changed.' + '\nOld:\n' + referenceGeneratedDeps.join('\n') + '\nNew:\n' + sortedDependencies.join('\n'); if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) { throw new Error(failMessage); } else { console.warn(failMessage); } } return sortedDependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. function mergePackageDeps(inputDeps: Set[]): Set { const requires = new Set(); for (const depSet of inputDeps) { for (const dep of depSet) { const trimmedDependency = dep.trim(); if (trimmedDependency.length && !trimmedDependency.startsWith('#')) { requires.add(trimmedDependency); } } } return requires; } ================================================ FILE: build/linux/libcxx-fetcher.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.downloadLibcxxHeaders = downloadLibcxxHeaders; exports.downloadLibcxxObjects = downloadLibcxxObjects; // Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available. const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const debug_1 = __importDefault(require("debug")); const extract_zip_1 = __importDefault(require("extract-zip")); const get_1 = require("@electron/get"); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const d = (0, debug_1.default)('libcxx-fetcher'); async function downloadLibcxxHeaders(outDir, electronVersion, lib_name) { if (await fs_1.default.existsSync(path_1.default.resolve(outDir, 'include'))) { return; } if (!await fs_1.default.existsSync(outDir)) { await fs_1.default.mkdirSync(outDir, { recursive: true }); } d(`downloading ${lib_name}_headers`); const headers = await (0, get_1.downloadArtifact)({ version: electronVersion, isGeneric: true, artifactName: `${lib_name}_headers.zip`, }); d(`unpacking ${lib_name}_headers from ${headers}`); await (0, extract_zip_1.default)(headers, { dir: outDir }); } async function downloadLibcxxObjects(outDir, electronVersion, targetArch = 'x64') { if (await fs_1.default.existsSync(path_1.default.resolve(outDir, 'libc++.a'))) { return; } if (!await fs_1.default.existsSync(outDir)) { await fs_1.default.mkdirSync(outDir, { recursive: true }); } d(`downloading libcxx-objects-linux-${targetArch}`); const objects = await (0, get_1.downloadArtifact)({ version: electronVersion, platform: 'linux', artifactName: 'libcxx-objects', arch: targetArch, }); d(`unpacking libcxx-objects from ${objects}`); await (0, extract_zip_1.default)(objects, { dir: outDir }); } async function main() { const libcxxObjectsDirPath = process.env['VSCODE_LIBCXX_OBJECTS_DIR']; const libcxxHeadersDownloadDir = process.env['VSCODE_LIBCXX_HEADERS_DIR']; const libcxxabiHeadersDownloadDir = process.env['VSCODE_LIBCXXABI_HEADERS_DIR']; const arch = process.env['VSCODE_ARCH']; const packageJSON = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'package.json'), 'utf8')); const electronVersion = packageJSON.devDependencies.electron; if (!libcxxObjectsDirPath || !libcxxHeadersDownloadDir || !libcxxabiHeadersDownloadDir) { throw new Error('Required build env not set'); } await downloadLibcxxObjects(libcxxObjectsDirPath, electronVersion, arch); await downloadLibcxxHeaders(libcxxHeadersDownloadDir, electronVersion, 'libcxx'); await downloadLibcxxHeaders(libcxxabiHeadersDownloadDir, electronVersion, 'libcxxabi'); } if (require.main === module) { main().catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=libcxx-fetcher.js.map ================================================ FILE: build/linux/libcxx-fetcher.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available. import fs from 'fs'; import path from 'path'; import debug from 'debug'; import extract from 'extract-zip'; import { downloadArtifact } from '@electron/get'; const root = path.dirname(path.dirname(__dirname)); const d = debug('libcxx-fetcher'); export async function downloadLibcxxHeaders(outDir: string, electronVersion: string, lib_name: string): Promise { if (await fs.existsSync(path.resolve(outDir, 'include'))) { return; } if (!await fs.existsSync(outDir)) { await fs.mkdirSync(outDir, { recursive: true }); } d(`downloading ${lib_name}_headers`); const headers = await downloadArtifact({ version: electronVersion, isGeneric: true, artifactName: `${lib_name}_headers.zip`, }); d(`unpacking ${lib_name}_headers from ${headers}`); await extract(headers, { dir: outDir }); } export async function downloadLibcxxObjects(outDir: string, electronVersion: string, targetArch: string = 'x64'): Promise { if (await fs.existsSync(path.resolve(outDir, 'libc++.a'))) { return; } if (!await fs.existsSync(outDir)) { await fs.mkdirSync(outDir, { recursive: true }); } d(`downloading libcxx-objects-linux-${targetArch}`); const objects = await downloadArtifact({ version: electronVersion, platform: 'linux', artifactName: 'libcxx-objects', arch: targetArch, }); d(`unpacking libcxx-objects from ${objects}`); await extract(objects, { dir: outDir }); } async function main(): Promise { const libcxxObjectsDirPath = process.env['VSCODE_LIBCXX_OBJECTS_DIR']; const libcxxHeadersDownloadDir = process.env['VSCODE_LIBCXX_HEADERS_DIR']; const libcxxabiHeadersDownloadDir = process.env['VSCODE_LIBCXXABI_HEADERS_DIR']; const arch = process.env['VSCODE_ARCH']; const packageJSON = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')); const electronVersion = packageJSON.devDependencies.electron; if (!libcxxObjectsDirPath || !libcxxHeadersDownloadDir || !libcxxabiHeadersDownloadDir) { throw new Error('Required build env not set'); } await downloadLibcxxObjects(libcxxObjectsDirPath, electronVersion, arch); await downloadLibcxxHeaders(libcxxHeadersDownloadDir, electronVersion, 'libcxx'); await downloadLibcxxHeaders(libcxxabiHeadersDownloadDir, electronVersion, 'libcxxabi'); } if (require.main === module) { main().catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/linux/rpm/calculate-deps.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.generatePackageDeps = generatePackageDeps; const child_process_1 = require("child_process"); const fs_1 = require("fs"); const dep_lists_1 = require("./dep-lists"); function generatePackageDeps(files) { const dependencies = files.map(file => calculatePackageDeps(file)); const additionalDepsSet = new Set(dep_lists_1.additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/calculate_package_deps.py. function calculatePackageDeps(binaryPath) { try { if (!((0, fs_1.statSync)(binaryPath).mode & fs_1.constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); } } catch (e) { // The package might not exist. Don't re-throw the error here. console.error('Tried to stat ' + binaryPath + ' but failed.'); } const findRequiresResult = (0, child_process_1.spawnSync)('/usr/lib/rpm/find-requires', { input: binaryPath + '\n' }); if (findRequiresResult.status !== 0) { throw new Error(`find-requires failed with exit code ${findRequiresResult.status}.\nstderr: ${findRequiresResult.stderr}`); } const requires = new Set(findRequiresResult.stdout.toString('utf-8').trimEnd().split('\n')); return requires; } //# sourceMappingURL=calculate-deps.js.map ================================================ FILE: build/linux/rpm/calculate-deps.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawnSync } from 'child_process'; import { constants, statSync } from 'fs'; import { additionalDeps } from './dep-lists'; export function generatePackageDeps(files: string[]): Set[] { const dependencies: Set[] = files.map(file => calculatePackageDeps(file)); const additionalDepsSet = new Set(additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/calculate_package_deps.py. function calculatePackageDeps(binaryPath: string): Set { try { if (!(statSync(binaryPath).mode & constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); } } catch (e) { // The package might not exist. Don't re-throw the error here. console.error('Tried to stat ' + binaryPath + ' but failed.'); } const findRequiresResult = spawnSync('/usr/lib/rpm/find-requires', { input: binaryPath + '\n' }); if (findRequiresResult.status !== 0) { throw new Error(`find-requires failed with exit code ${findRequiresResult.status}.\nstderr: ${findRequiresResult.stderr}`); } const requires = new Set(findRequiresResult.stdout.toString('utf-8').trimEnd().split('\n')); return requires; } ================================================ FILE: build/linux/rpm/dep-lists.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.referenceGeneratedDepsByArch = exports.additionalDeps = void 0; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/additional_deps // Additional dependencies not in the rpm find-requires output. exports.additionalDeps = [ 'ca-certificates', // Make sure users have SSL certificates. 'libgtk-3.so.0()(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'libvulkan.so.1()(64bit)', 'libcurl.so.4()(64bit)', 'xdg-utils' // OS integration ]; exports.referenceGeneratedDepsByArch = { 'x86_64': [ 'ca-certificates', 'ld-linux-x86-64.so.2()(64bit)', 'ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)', 'ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)', 'libX11.so.6()(64bit)', 'libXcomposite.so.1()(64bit)', 'libXdamage.so.1()(64bit)', 'libXext.so.6()(64bit)', 'libXfixes.so.3()(64bit)', 'libXrandr.so.2()(64bit)', 'libasound.so.2()(64bit)', 'libasound.so.2(ALSA_0.9)(64bit)', 'libasound.so.2(ALSA_0.9.0rc4)(64bit)', 'libatk-1.0.so.0()(64bit)', 'libatk-bridge-2.0.so.0()(64bit)', 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.10)(64bit)', 'libc.so.6(GLIBC_2.11)(64bit)', 'libc.so.6(GLIBC_2.12)(64bit)', 'libc.so.6(GLIBC_2.14)(64bit)', 'libc.so.6(GLIBC_2.15)(64bit)', 'libc.so.6(GLIBC_2.16)(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.2.5)(64bit)', 'libc.so.6(GLIBC_2.25)(64bit)', 'libc.so.6(GLIBC_2.27)(64bit)', 'libc.so.6(GLIBC_2.28)(64bit)', 'libc.so.6(GLIBC_2.3)(64bit)', 'libc.so.6(GLIBC_2.3.2)(64bit)', 'libc.so.6(GLIBC_2.3.3)(64bit)', 'libc.so.6(GLIBC_2.3.4)(64bit)', 'libc.so.6(GLIBC_2.4)(64bit)', 'libc.so.6(GLIBC_2.6)(64bit)', 'libc.so.6(GLIBC_2.7)(64bit)', 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', 'libdl.so.2()(64bit)', 'libdl.so.2(GLIBC_2.2.5)(64bit)', 'libexpat.so.1()(64bit)', 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.2.5)(64bit)', 'libnspr4.so()(64bit)', 'libnss3.so()(64bit)', 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.6)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', 'libnssutil3.so()(64bit)', 'libnssutil3.so(NSSUTIL_3.12.3)(64bit)', 'libpango-1.0.so.0()(64bit)', 'libpthread.so.0()(64bit)', 'libpthread.so.0(GLIBC_2.12)(64bit)', 'libpthread.so.0(GLIBC_2.2.5)(64bit)', 'libpthread.so.0(GLIBC_2.3.2)(64bit)', 'libpthread.so.0(GLIBC_2.3.3)(64bit)', 'libpthread.so.0(GLIBC_2.3.4)(64bit)', 'librt.so.1()(64bit)', 'librt.so.1(GLIBC_2.2.5)(64bit)', 'libsmime3.so()(64bit)', 'libsmime3.so(NSS_3.10)(64bit)', 'libsmime3.so(NSS_3.2)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'libudev.so.1()(64bit)', 'libudev.so.1(LIBUDEV_183)(64bit)', 'libutil.so.1()(64bit)', 'libutil.so.1(GLIBC_2.2.5)(64bit)', 'libxcb.so.1()(64bit)', 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ], 'armv7hl': [ 'ca-certificates', 'ld-linux-armhf.so.3', 'ld-linux-armhf.so.3(GLIBC_2.4)', 'libX11.so.6', 'libXcomposite.so.1', 'libXdamage.so.1', 'libXext.so.6', 'libXfixes.so.3', 'libXrandr.so.2', 'libasound.so.2', 'libasound.so.2(ALSA_0.9)', 'libasound.so.2(ALSA_0.9.0rc4)', 'libatk-1.0.so.0', 'libatk-bridge-2.0.so.0', 'libatspi.so.0', 'libc.so.6', 'libc.so.6(GLIBC_2.10)', 'libc.so.6(GLIBC_2.11)', 'libc.so.6(GLIBC_2.12)', 'libc.so.6(GLIBC_2.14)', 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', 'libc.so.6(GLIBC_2.18)', 'libc.so.6(GLIBC_2.25)', 'libc.so.6(GLIBC_2.27)', 'libc.so.6(GLIBC_2.28)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdbus-1.so.3(LIBDBUS_1_3)', 'libdl.so.2', 'libdl.so.2(GLIBC_2.4)', 'libexpat.so.1', 'libgbm.so.1', 'libgcc_s.so.1', 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.5)', 'libgcc_s.so.1(GCC_4.3.0)', 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', 'libm.so.6', 'libm.so.6(GLIBC_2.4)', 'libnspr4.so', 'libnss3.so', 'libnss3.so(NSS_3.11)', 'libnss3.so(NSS_3.12)', 'libnss3.so(NSS_3.12.1)', 'libnss3.so(NSS_3.2)', 'libnss3.so(NSS_3.22)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)', 'libnss3.so(NSS_3.30)', 'libnss3.so(NSS_3.4)', 'libnss3.so(NSS_3.5)', 'libnss3.so(NSS_3.6)', 'libnss3.so(NSS_3.9.2)', 'libnssutil3.so', 'libnssutil3.so(NSSUTIL_3.12.3)', 'libpango-1.0.so.0', 'libpthread.so.0', 'libpthread.so.0(GLIBC_2.12)', 'libpthread.so.0(GLIBC_2.4)', 'librt.so.1', 'librt.so.1(GLIBC_2.4)', 'libsmime3.so', 'libsmime3.so(NSS_3.10)', 'libsmime3.so(NSS_3.2)', 'libssl3.so(NSS_3.28)(64bit)', 'libstdc++.so.6', 'libstdc++.so.6(CXXABI_1.3)', 'libstdc++.so.6(CXXABI_1.3.5)', 'libstdc++.so.6(CXXABI_1.3.8)', 'libstdc++.so.6(CXXABI_1.3.9)', 'libstdc++.so.6(CXXABI_ARM_1.3.3)', 'libstdc++.so.6(GLIBCXX_3.4)', 'libstdc++.so.6(GLIBCXX_3.4.11)', 'libstdc++.so.6(GLIBCXX_3.4.14)', 'libstdc++.so.6(GLIBCXX_3.4.15)', 'libstdc++.so.6(GLIBCXX_3.4.18)', 'libstdc++.so.6(GLIBCXX_3.4.19)', 'libstdc++.so.6(GLIBCXX_3.4.20)', 'libstdc++.so.6(GLIBCXX_3.4.21)', 'libstdc++.so.6(GLIBCXX_3.4.22)', 'libstdc++.so.6(GLIBCXX_3.4.5)', 'libstdc++.so.6(GLIBCXX_3.4.9)', 'libudev.so.1', 'libudev.so.1(LIBUDEV_183)', 'libutil.so.1', 'libutil.so.1(GLIBC_2.4)', 'libxcb.so.1', 'libxkbcommon.so.0', 'libxkbcommon.so.0(V_0.5.0)', 'libxkbfile.so.1', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ], 'aarch64': [ 'ca-certificates', 'ld-linux-aarch64.so.1()(64bit)', 'ld-linux-aarch64.so.1(GLIBC_2.17)(64bit)', 'libX11.so.6()(64bit)', 'libXcomposite.so.1()(64bit)', 'libXdamage.so.1()(64bit)', 'libXext.so.6()(64bit)', 'libXfixes.so.3()(64bit)', 'libXrandr.so.2()(64bit)', 'libasound.so.2()(64bit)', 'libasound.so.2(ALSA_0.9)(64bit)', 'libasound.so.2(ALSA_0.9.0rc4)(64bit)', 'libatk-1.0.so.0()(64bit)', 'libatk-bridge-2.0.so.0()(64bit)', 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.25)(64bit)', 'libc.so.6(GLIBC_2.27)(64bit)', 'libc.so.6(GLIBC_2.28)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', 'libdl.so.2()(64bit)', 'libdl.so.2(GLIBC_2.17)(64bit)', 'libexpat.so.1()(64bit)', 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.17)(64bit)', 'libnspr4.so()(64bit)', 'libnss3.so()(64bit)', 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.6)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', 'libnssutil3.so()(64bit)', 'libnssutil3.so(NSSUTIL_3.12.3)(64bit)', 'libpango-1.0.so.0()(64bit)', 'libpthread.so.0()(64bit)', 'libpthread.so.0(GLIBC_2.17)(64bit)', 'libsmime3.so()(64bit)', 'libsmime3.so(NSS_3.10)(64bit)', 'libsmime3.so(NSS_3.2)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'libstdc++.so.6()(64bit)', 'libstdc++.so.6(CXXABI_1.3)(64bit)', 'libstdc++.so.6(CXXABI_1.3.5)(64bit)', 'libstdc++.so.6(CXXABI_1.3.8)(64bit)', 'libstdc++.so.6(CXXABI_1.3.9)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.11)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.14)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.15)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.18)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.19)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.20)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.21)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.22)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.5)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.9)(64bit)', 'libudev.so.1()(64bit)', 'libudev.so.1(LIBUDEV_183)(64bit)', 'libutil.so.1()(64bit)', 'libutil.so.1(GLIBC_2.17)(64bit)', 'libxcb.so.1()(64bit)', 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ] }; //# sourceMappingURL=dep-lists.js.map ================================================ FILE: build/linux/rpm/dep-lists.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/additional_deps // Additional dependencies not in the rpm find-requires output. export const additionalDeps = [ 'ca-certificates', // Make sure users have SSL certificates. 'libgtk-3.so.0()(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'libvulkan.so.1()(64bit)', 'libcurl.so.4()(64bit)', 'xdg-utils' // OS integration ]; export const referenceGeneratedDepsByArch = { 'x86_64': [ 'ca-certificates', 'ld-linux-x86-64.so.2()(64bit)', 'ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)', 'ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)', 'libX11.so.6()(64bit)', 'libXcomposite.so.1()(64bit)', 'libXdamage.so.1()(64bit)', 'libXext.so.6()(64bit)', 'libXfixes.so.3()(64bit)', 'libXrandr.so.2()(64bit)', 'libasound.so.2()(64bit)', 'libasound.so.2(ALSA_0.9)(64bit)', 'libasound.so.2(ALSA_0.9.0rc4)(64bit)', 'libatk-1.0.so.0()(64bit)', 'libatk-bridge-2.0.so.0()(64bit)', 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.10)(64bit)', 'libc.so.6(GLIBC_2.11)(64bit)', 'libc.so.6(GLIBC_2.12)(64bit)', 'libc.so.6(GLIBC_2.14)(64bit)', 'libc.so.6(GLIBC_2.15)(64bit)', 'libc.so.6(GLIBC_2.16)(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.2.5)(64bit)', 'libc.so.6(GLIBC_2.25)(64bit)', 'libc.so.6(GLIBC_2.27)(64bit)', 'libc.so.6(GLIBC_2.28)(64bit)', 'libc.so.6(GLIBC_2.3)(64bit)', 'libc.so.6(GLIBC_2.3.2)(64bit)', 'libc.so.6(GLIBC_2.3.3)(64bit)', 'libc.so.6(GLIBC_2.3.4)(64bit)', 'libc.so.6(GLIBC_2.4)(64bit)', 'libc.so.6(GLIBC_2.6)(64bit)', 'libc.so.6(GLIBC_2.7)(64bit)', 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', 'libdl.so.2()(64bit)', 'libdl.so.2(GLIBC_2.2.5)(64bit)', 'libexpat.so.1()(64bit)', 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.2.5)(64bit)', 'libnspr4.so()(64bit)', 'libnss3.so()(64bit)', 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.6)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', 'libnssutil3.so()(64bit)', 'libnssutil3.so(NSSUTIL_3.12.3)(64bit)', 'libpango-1.0.so.0()(64bit)', 'libpthread.so.0()(64bit)', 'libpthread.so.0(GLIBC_2.12)(64bit)', 'libpthread.so.0(GLIBC_2.2.5)(64bit)', 'libpthread.so.0(GLIBC_2.3.2)(64bit)', 'libpthread.so.0(GLIBC_2.3.3)(64bit)', 'libpthread.so.0(GLIBC_2.3.4)(64bit)', 'librt.so.1()(64bit)', 'librt.so.1(GLIBC_2.2.5)(64bit)', 'libsmime3.so()(64bit)', 'libsmime3.so(NSS_3.10)(64bit)', 'libsmime3.so(NSS_3.2)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'libudev.so.1()(64bit)', 'libudev.so.1(LIBUDEV_183)(64bit)', 'libutil.so.1()(64bit)', 'libutil.so.1(GLIBC_2.2.5)(64bit)', 'libxcb.so.1()(64bit)', 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ], 'armv7hl': [ 'ca-certificates', 'ld-linux-armhf.so.3', 'ld-linux-armhf.so.3(GLIBC_2.4)', 'libX11.so.6', 'libXcomposite.so.1', 'libXdamage.so.1', 'libXext.so.6', 'libXfixes.so.3', 'libXrandr.so.2', 'libasound.so.2', 'libasound.so.2(ALSA_0.9)', 'libasound.so.2(ALSA_0.9.0rc4)', 'libatk-1.0.so.0', 'libatk-bridge-2.0.so.0', 'libatspi.so.0', 'libc.so.6', 'libc.so.6(GLIBC_2.10)', 'libc.so.6(GLIBC_2.11)', 'libc.so.6(GLIBC_2.12)', 'libc.so.6(GLIBC_2.14)', 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', 'libc.so.6(GLIBC_2.18)', 'libc.so.6(GLIBC_2.25)', 'libc.so.6(GLIBC_2.27)', 'libc.so.6(GLIBC_2.28)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdbus-1.so.3(LIBDBUS_1_3)', 'libdl.so.2', 'libdl.so.2(GLIBC_2.4)', 'libexpat.so.1', 'libgbm.so.1', 'libgcc_s.so.1', 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.5)', 'libgcc_s.so.1(GCC_4.3.0)', 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', 'libm.so.6', 'libm.so.6(GLIBC_2.4)', 'libnspr4.so', 'libnss3.so', 'libnss3.so(NSS_3.11)', 'libnss3.so(NSS_3.12)', 'libnss3.so(NSS_3.12.1)', 'libnss3.so(NSS_3.2)', 'libnss3.so(NSS_3.22)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)', 'libnss3.so(NSS_3.30)', 'libnss3.so(NSS_3.4)', 'libnss3.so(NSS_3.5)', 'libnss3.so(NSS_3.6)', 'libnss3.so(NSS_3.9.2)', 'libnssutil3.so', 'libnssutil3.so(NSSUTIL_3.12.3)', 'libpango-1.0.so.0', 'libpthread.so.0', 'libpthread.so.0(GLIBC_2.12)', 'libpthread.so.0(GLIBC_2.4)', 'librt.so.1', 'librt.so.1(GLIBC_2.4)', 'libsmime3.so', 'libsmime3.so(NSS_3.10)', 'libsmime3.so(NSS_3.2)', 'libssl3.so(NSS_3.28)(64bit)', 'libstdc++.so.6', 'libstdc++.so.6(CXXABI_1.3)', 'libstdc++.so.6(CXXABI_1.3.5)', 'libstdc++.so.6(CXXABI_1.3.8)', 'libstdc++.so.6(CXXABI_1.3.9)', 'libstdc++.so.6(CXXABI_ARM_1.3.3)', 'libstdc++.so.6(GLIBCXX_3.4)', 'libstdc++.so.6(GLIBCXX_3.4.11)', 'libstdc++.so.6(GLIBCXX_3.4.14)', 'libstdc++.so.6(GLIBCXX_3.4.15)', 'libstdc++.so.6(GLIBCXX_3.4.18)', 'libstdc++.so.6(GLIBCXX_3.4.19)', 'libstdc++.so.6(GLIBCXX_3.4.20)', 'libstdc++.so.6(GLIBCXX_3.4.21)', 'libstdc++.so.6(GLIBCXX_3.4.22)', 'libstdc++.so.6(GLIBCXX_3.4.5)', 'libstdc++.so.6(GLIBCXX_3.4.9)', 'libudev.so.1', 'libudev.so.1(LIBUDEV_183)', 'libutil.so.1', 'libutil.so.1(GLIBC_2.4)', 'libxcb.so.1', 'libxkbcommon.so.0', 'libxkbcommon.so.0(V_0.5.0)', 'libxkbfile.so.1', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ], 'aarch64': [ 'ca-certificates', 'ld-linux-aarch64.so.1()(64bit)', 'ld-linux-aarch64.so.1(GLIBC_2.17)(64bit)', 'libX11.so.6()(64bit)', 'libXcomposite.so.1()(64bit)', 'libXdamage.so.1()(64bit)', 'libXext.so.6()(64bit)', 'libXfixes.so.3()(64bit)', 'libXrandr.so.2()(64bit)', 'libasound.so.2()(64bit)', 'libasound.so.2(ALSA_0.9)(64bit)', 'libasound.so.2(ALSA_0.9.0rc4)(64bit)', 'libatk-1.0.so.0()(64bit)', 'libatk-bridge-2.0.so.0()(64bit)', 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.25)(64bit)', 'libc.so.6(GLIBC_2.27)(64bit)', 'libc.so.6(GLIBC_2.28)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', 'libdl.so.2()(64bit)', 'libdl.so.2(GLIBC_2.17)(64bit)', 'libexpat.so.1()(64bit)', 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', 'libm.so.6(GLIBC_2.17)(64bit)', 'libnspr4.so()(64bit)', 'libnss3.so()(64bit)', 'libnss3.so(NSS_3.11)(64bit)', 'libnss3.so(NSS_3.12)(64bit)', 'libnss3.so(NSS_3.12.1)(64bit)', 'libnss3.so(NSS_3.2)(64bit)', 'libnss3.so(NSS_3.22)(64bit)', 'libnss3.so(NSS_3.3)(64bit)', 'libnss3.so(NSS_3.30)(64bit)', 'libnss3.so(NSS_3.4)(64bit)', 'libnss3.so(NSS_3.5)(64bit)', 'libnss3.so(NSS_3.6)(64bit)', 'libnss3.so(NSS_3.9.2)(64bit)', 'libnssutil3.so()(64bit)', 'libnssutil3.so(NSSUTIL_3.12.3)(64bit)', 'libpango-1.0.so.0()(64bit)', 'libpthread.so.0()(64bit)', 'libpthread.so.0(GLIBC_2.17)(64bit)', 'libsmime3.so()(64bit)', 'libsmime3.so(NSS_3.10)(64bit)', 'libsmime3.so(NSS_3.2)(64bit)', 'libssl3.so(NSS_3.28)(64bit)', 'libstdc++.so.6()(64bit)', 'libstdc++.so.6(CXXABI_1.3)(64bit)', 'libstdc++.so.6(CXXABI_1.3.5)(64bit)', 'libstdc++.so.6(CXXABI_1.3.8)(64bit)', 'libstdc++.so.6(CXXABI_1.3.9)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.11)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.14)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.15)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.18)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.19)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.20)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.21)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.22)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.5)(64bit)', 'libstdc++.so.6(GLIBCXX_3.4.9)(64bit)', 'libudev.so.1()(64bit)', 'libudev.so.1(LIBUDEV_183)(64bit)', 'libutil.so.1()(64bit)', 'libutil.so.1(GLIBC_2.17)(64bit)', 'libxcb.so.1()(64bit)', 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' ] }; ================================================ FILE: build/linux/rpm/types.js ================================================ "use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.isRpmArchString = isRpmArchString; function isRpmArchString(s) { return ['x86_64', 'armv7hl', 'aarch64'].includes(s); } //# sourceMappingURL=types.js.map ================================================ FILE: build/linux/rpm/types.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export type RpmArchString = 'x86_64' | 'armv7hl' | 'aarch64'; export function isRpmArchString(s: string): s is RpmArchString { return ['x86_64', 'armv7hl', 'aarch64'].includes(s); } ================================================ FILE: build/loader.min ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ "use strict";const _amdLoaderGlobal=this,_commonjsGlobal=typeof global=="object"?global:{};var AMDLoader;(function(d){d.global=_amdLoaderGlobal;class _{get isWindows(){return this._detect(),this._isWindows}get isNode(){return this._detect(),this._isNode}get isElectronRenderer(){return this._detect(),this._isElectronRenderer}get isWebWorker(){return this._detect(),this._isWebWorker}get isElectronNodeIntegrationWebWorker(){return this._detect(),this._isElectronNodeIntegrationWebWorker}constructor(){this._detected=!1,this._isWindows=!1,this._isNode=!1,this._isElectronRenderer=!1,this._isWebWorker=!1,this._isElectronNodeIntegrationWebWorker=!1}_detect(){this._detected||(this._detected=!0,this._isWindows=_._isWindows(),this._isNode=typeof module<"u"&&!!module.exports,this._isElectronRenderer=typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="renderer",this._isWebWorker=typeof d.global.importScripts=="function",this._isElectronNodeIntegrationWebWorker=this._isWebWorker&&typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="worker")}static _isWindows(){return typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.indexOf("Windows")>=0?!0:typeof process<"u"?process.platform==="win32":!1}}d.Environment=_})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(d){class _{constructor(n,c,a){this.type=n,this.detail=c,this.timestamp=a}}d.LoaderEvent=_;class v{constructor(n){this._events=[new _(1,"",n)]}record(n,c){this._events.push(new _(n,c,d.Utilities.getHighPerformanceTimestamp()))}getEvents(){return this._events}}d.LoaderEventRecorder=v;class f{record(n,c){}getEvents(){return[]}}f.INSTANCE=new f,d.NullLoaderEventRecorder=f})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(d){class _{static fileUriToFilePath(f,h){if(h=decodeURI(h).replace(/%23/g,"#"),f){if(/^file:\/\/\//.test(h))return h.substr(8);if(/^file:\/\//.test(h))return h.substr(5)}else if(/^file:\/\//.test(h))return h.substr(7);return h}static startsWith(f,h){return f.length>=h.length&&f.substr(0,h.length)===h}static endsWith(f,h){return f.length>=h.length&&f.substr(f.length-h.length)===h}static containsQueryString(f){return/^[^\#]*\?/gi.test(f)}static isAbsolutePath(f){return/^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(f)}static forEachProperty(f,h){if(f){let n;for(n in f)f.hasOwnProperty(n)&&h(n,f[n])}}static isEmpty(f){let h=!0;return _.forEachProperty(f,()=>{h=!1}),h}static recursiveClone(f){if(!f||typeof f!="object"||f instanceof RegExp||!Array.isArray(f)&&Object.getPrototypeOf(f)!==Object.prototype)return f;let h=Array.isArray(f)?[]:{};return _.forEachProperty(f,(n,c)=>{c&&typeof c=="object"?h[n]=_.recursiveClone(c):h[n]=c}),h}static generateAnonymousModule(){return"===anonymous"+_.NEXT_ANONYMOUS_ID+++"==="}static isAnonymousModule(f){return _.startsWith(f,"===anonymous")}static getHighPerformanceTimestamp(){return this.PERFORMANCE_NOW_PROBED||(this.PERFORMANCE_NOW_PROBED=!0,this.HAS_PERFORMANCE_NOW=d.global.performance&&typeof d.global.performance.now=="function"),this.HAS_PERFORMANCE_NOW?d.global.performance.now():Date.now()}}_.NEXT_ANONYMOUS_ID=1,_.PERFORMANCE_NOW_PROBED=!1,_.HAS_PERFORMANCE_NOW=!1,d.Utilities=_})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(d){function _(h){if(h instanceof Error)return h;const n=new Error(h.message||String(h)||"Unknown Error");return h.stack&&(n.stack=h.stack),n}d.ensureError=_;class v{static validateConfigurationOptions(n){function c(a){if(a.phase==="loading"){console.error('Loading "'+a.moduleId+'" failed'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}if(a.phase==="factory"){console.error('The factory function of "'+a.moduleId+'" has thrown an exception'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}}if(n=n||{},typeof n.baseUrl!="string"&&(n.baseUrl=""),typeof n.isBuild!="boolean"&&(n.isBuild=!1),typeof n.paths!="object"&&(n.paths={}),typeof n.config!="object"&&(n.config={}),typeof n.catchError>"u"&&(n.catchError=!1),typeof n.recordStats>"u"&&(n.recordStats=!1),typeof n.urlArgs!="string"&&(n.urlArgs=""),typeof n.onError!="function"&&(n.onError=c),Array.isArray(n.ignoreDuplicateModules)||(n.ignoreDuplicateModules=[]),n.baseUrl.length>0&&(d.Utilities.endsWith(n.baseUrl,"/")||(n.baseUrl+="/")),typeof n.cspNonce!="string"&&(n.cspNonce=""),typeof n.preferScriptTags>"u"&&(n.preferScriptTags=!1),n.nodeCachedData&&typeof n.nodeCachedData=="object"&&(typeof n.nodeCachedData.seed!="string"&&(n.nodeCachedData.seed="seed"),(typeof n.nodeCachedData.writeDelay!="number"||n.nodeCachedData.writeDelay<0)&&(n.nodeCachedData.writeDelay=1e3*7),!n.nodeCachedData.path||typeof n.nodeCachedData.path!="string")){const a=_(new Error("INVALID cached data configuration, 'path' MUST be set"));a.phase="configuration",n.onError(a),n.nodeCachedData=void 0}return n}static mergeConfigurationOptions(n=null,c=null){let a=d.Utilities.recursiveClone(c||{});return d.Utilities.forEachProperty(n,(t,e)=>{t==="ignoreDuplicateModules"&&typeof a.ignoreDuplicateModules<"u"?a.ignoreDuplicateModules=a.ignoreDuplicateModules.concat(e):t==="paths"&&typeof a.paths<"u"?d.Utilities.forEachProperty(e,(i,s)=>a.paths[i]=s):t==="config"&&typeof a.config<"u"?d.Utilities.forEachProperty(e,(i,s)=>a.config[i]=s):a[t]=d.Utilities.recursiveClone(e)}),v.validateConfigurationOptions(a)}}d.ConfigurationOptionsUtil=v;class f{constructor(n,c){if(this._env=n,this.options=v.mergeConfigurationOptions(c),this._createIgnoreDuplicateModulesMap(),this._createSortedPathsRules(),this.options.baseUrl===""&&this.options.nodeRequire&&this.options.nodeRequire.main&&this.options.nodeRequire.main.filename&&this._env.isNode){let a=this.options.nodeRequire.main.filename,t=Math.max(a.lastIndexOf("/"),a.lastIndexOf("\\"));this.options.baseUrl=a.substring(0,t+1)}}_createIgnoreDuplicateModulesMap(){this.ignoreDuplicateModulesMap={};for(let n=0;n{Array.isArray(c)?this.sortedPathsRules.push({from:n,to:c}):this.sortedPathsRules.push({from:n,to:[c]})}),this.sortedPathsRules.sort((n,c)=>c.from.length-n.from.length)}cloneAndMerge(n){return new f(this._env,v.mergeConfigurationOptions(n,this.options))}getOptionsLiteral(){return this.options}_applyPaths(n){let c;for(let a=0,t=this.sortedPathsRules.length;athis.triggerCallback(i),u=>this.triggerErrorback(i,u))}triggerCallback(e){let i=this._callbackMap[e];delete this._callbackMap[e];for(let s=0;s{e.removeEventListener("load",o),e.removeEventListener("error",u)},o=l=>{r(),i()},u=l=>{r(),s(l)};e.addEventListener("load",o),e.addEventListener("error",u)}load(e,i,s,r){if(/^node\|/.test(i)){let o=e.getConfig().getOptionsLiteral(),u=c(e.getRecorder(),o.nodeRequire||d.global.nodeRequire),l=i.split("|"),g=null;try{g=u(l[1])}catch(p){r(p);return}e.enqueueDefineAnonymousModule([],()=>g),s()}else{let o=document.createElement("script");o.setAttribute("async","async"),o.setAttribute("type","text/javascript"),this.attachListeners(o,s,r);const{trustedTypesPolicy:u}=e.getConfig().getOptionsLiteral();u&&(i=u.createScriptURL(i)),o.setAttribute("src",i);const{cspNonce:l}=e.getConfig().getOptionsLiteral();l&&o.setAttribute("nonce",l),document.getElementsByTagName("head")[0].appendChild(o)}}}function f(t){const{trustedTypesPolicy:e}=t.getConfig().getOptionsLiteral();try{return(e?self.eval(e.createScript("","true")):new Function("true")).call(self),!0}catch{return!1}}class h{constructor(){this._cachedCanUseEval=null}_canUseEval(e){return this._cachedCanUseEval===null&&(this._cachedCanUseEval=f(e)),this._cachedCanUseEval}load(e,i,s,r){if(/^node\|/.test(i)){const o=e.getConfig().getOptionsLiteral(),u=c(e.getRecorder(),o.nodeRequire||d.global.nodeRequire),l=i.split("|");let g=null;try{g=u(l[1])}catch(p){r(p);return}e.enqueueDefineAnonymousModule([],function(){return g}),s()}else{const{trustedTypesPolicy:o}=e.getConfig().getOptionsLiteral();if(!(/^((http:)|(https:)|(file:))/.test(i)&&i.substring(0,self.origin.length)!==self.origin)&&this._canUseEval(e)){fetch(i).then(l=>{if(l.status!==200)throw new Error(l.statusText);return l.text()}).then(l=>{l=`${l} //# sourceURL=${i}`,(o?self.eval(o.createScript("",l)):new Function(l)).call(self),s()}).then(void 0,r);return}try{o&&(i=o.createScriptURL(i)),importScripts(i),s()}catch(l){r(l)}}}}class n{constructor(e){this._env=e,this._didInitialize=!1,this._didPatchNodeRequire=!1}_init(e){this._didInitialize||(this._didInitialize=!0,this._fs=e("fs"),this._vm=e("vm"),this._path=e("path"),this._crypto=e("crypto"))}_initNodeRequire(e,i){const{nodeCachedData:s}=i.getConfig().getOptionsLiteral();if(!s||this._didPatchNodeRequire)return;this._didPatchNodeRequire=!0;const r=this,o=e("module");function u(l){const g=l.constructor;let p=function(y){try{return l.require(y)}finally{}};return p.resolve=function(y,E){return g._resolveFilename(y,l,!1,E)},p.resolve.paths=function(y){return g._resolveLookupPaths(y,l)},p.main=process.mainModule,p.extensions=g._extensions,p.cache=g._cache,p}o.prototype._compile=function(l,g){const p=o.wrap(l.replace(/^#!.*/,"")),m=i.getRecorder(),y=r._getCachedDataPath(s,g),E={filename:g};let R;try{const x=r._fs.readFileSync(y);R=x.slice(0,16),E.cachedData=x.slice(16),m.record(60,y)}catch{m.record(61,y)}const C=new r._vm.Script(p,E),I=C.runInThisContext(E),w=r._path.dirname(g),b=u(this),U=[this.exports,b,this,g,w,process,_commonjsGlobal,Buffer],P=I.apply(this.exports,U);return r._handleCachedData(C,p,y,!E.cachedData,i),r._verifyCachedData(C,p,y,R,i),P}}load(e,i,s,r){const o=e.getConfig().getOptionsLiteral(),u=c(e.getRecorder(),o.nodeRequire||d.global.nodeRequire),l=o.nodeInstrumenter||function(p){return p};this._init(u),this._initNodeRequire(u,e);let g=e.getRecorder();if(/^node\|/.test(i)){let p=i.split("|"),m=null;try{m=u(p[1])}catch(y){r(y);return}e.enqueueDefineAnonymousModule([],()=>m),s()}else{i=d.Utilities.fileUriToFilePath(this._env.isWindows,i);const p=this._path.normalize(i),m=this._getElectronRendererScriptPathOrUri(p),y=!!o.nodeCachedData,E=y?this._getCachedDataPath(o.nodeCachedData,i):void 0;this._readSourceAndCachedData(p,E,g,(R,C,I,w)=>{if(R){r(R);return}let b;C.charCodeAt(0)===n._BOM?b=n._PREFIX+C.substring(1)+n._SUFFIX:b=n._PREFIX+C+n._SUFFIX,b=l(b,p);const U={filename:m,cachedData:I},P=this._createAndEvalScript(e,b,U,s,r);this._handleCachedData(P,b,E,y&&!I,e),this._verifyCachedData(P,b,E,w,e)})}}_createAndEvalScript(e,i,s,r,o){const u=e.getRecorder();u.record(31,s.filename);const l=new this._vm.Script(i,s),g=l.runInThisContext(s),p=e.getGlobalAMDDefineFunc();let m=!1;const y=function(){return m=!0,p.apply(null,arguments)};return y.amd=p.amd,g.call(d.global,e.getGlobalAMDRequireFunc(),y,s.filename,this._path.dirname(s.filename)),u.record(32,s.filename),m?r():o(new Error(`Didn't receive define call in ${s.filename}!`)),l}_getElectronRendererScriptPathOrUri(e){if(!this._env.isElectronRenderer)return e;let i=e.match(/^([a-z])\:(.*)/i);return i?`file:///${(i[1].toUpperCase()+":"+i[2]).replace(/\\/g,"/")}`:`file://${e}`}_getCachedDataPath(e,i){const s=this._crypto.createHash("md5").update(i,"utf8").update(e.seed,"utf8").update(process.arch,"").digest("hex"),r=this._path.basename(i).replace(/\.js$/,"");return this._path.join(e.path,`${r}-${s}.code`)}_handleCachedData(e,i,s,r,o){e.cachedDataRejected?this._fs.unlink(s,u=>{o.getRecorder().record(62,s),this._createAndWriteCachedData(e,i,s,o),u&&o.getConfig().onError(u)}):r&&this._createAndWriteCachedData(e,i,s,o)}_createAndWriteCachedData(e,i,s,r){let o=Math.ceil(r.getConfig().getOptionsLiteral().nodeCachedData.writeDelay*(1+Math.random())),u=-1,l=0,g;const p=()=>{setTimeout(()=>{g||(g=this._crypto.createHash("md5").update(i,"utf8").digest());const m=e.createCachedData();if(!(m.length===0||m.length===u||l>=5)){if(m.length{y&&r.getConfig().onError(y),r.getRecorder().record(63,s),p()})}},o*Math.pow(4,l++))};p()}_readSourceAndCachedData(e,i,s,r){if(!i)this._fs.readFile(e,{encoding:"utf8"},r);else{let o,u,l,g=2;const p=m=>{m?r(m):--g===0&&r(void 0,o,u,l)};this._fs.readFile(e,{encoding:"utf8"},(m,y)=>{o=y,p(m)}),this._fs.readFile(i,(m,y)=>{!m&&y&&y.length>0?(l=y.slice(0,16),u=y.slice(16),s.record(60,i)):s.record(61,i),p()})}}_verifyCachedData(e,i,s,r,o){r&&(e.cachedDataRejected||setTimeout(()=>{const u=this._crypto.createHash("md5").update(i,"utf8").digest();r.equals(u)||(o.getConfig().onError(new Error(`FAILED TO VERIFY CACHED DATA, deleting stale '${s}' now, but a RESTART IS REQUIRED`)),this._fs.unlink(s,l=>{l&&o.getConfig().onError(l)}))},Math.ceil(5e3*(1+Math.random()))))}}n._BOM=65279,n._PREFIX="(function (require, define, __filename, __dirname) { ",n._SUFFIX=` });`;function c(t,e){if(e.__$__isRecorded)return e;const i=function(r){t.record(33,r);try{return e(r)}finally{t.record(34,r)}};return i.__$__isRecorded=!0,i}d.ensureRecordedNodeRequire=c;function a(t){return new _(t)}d.createScriptLoader=a})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(d){class _{constructor(t){let e=t.lastIndexOf("/");e!==-1?this.fromModulePath=t.substr(0,e+1):this.fromModulePath=""}static _normalizeModuleId(t){let e=t,i;for(i=/\/\.\//;i.test(e);)e=e.replace(i,"/");for(e=e.replace(/^\.\//g,""),i=/\/(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//;i.test(e);)e=e.replace(i,"/");return e=e.replace(/^(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//,""),e}resolveModule(t){let e=t;return d.Utilities.isAbsolutePath(e)||(d.Utilities.startsWith(e,"./")||d.Utilities.startsWith(e,"../"))&&(e=_._normalizeModuleId(this.fromModulePath+e)),e}}_.ROOT=new _(""),d.ModuleIdResolver=_;class v{constructor(t,e,i,s,r,o){this.id=t,this.strId=e,this.dependencies=i,this._callback=s,this._errorback=r,this.moduleIdResolver=o,this.exports={},this.error=null,this.exportsPassedIn=!1,this.unresolvedDependenciesCount=this.dependencies.length,this._isComplete=!1}static _safeInvokeFunction(t,e){try{return{returnedValue:t.apply(d.global,e),producedError:null}}catch(i){return{returnedValue:null,producedError:i}}}static _invokeFactory(t,e,i,s){return t.shouldInvokeFactory(e)?t.shouldCatchError()?this._safeInvokeFunction(i,s):{returnedValue:i.apply(d.global,s),producedError:null}:{returnedValue:null,producedError:null}}complete(t,e,i,s){this._isComplete=!0;let r=null;if(this._callback)if(typeof this._callback=="function"){t.record(21,this.strId);let o=v._invokeFactory(e,this.strId,this._callback,i);r=o.producedError,t.record(22,this.strId),!r&&typeof o.returnedValue<"u"&&(!this.exportsPassedIn||d.Utilities.isEmpty(this.exports))&&(this.exports=o.returnedValue)}else this.exports=this._callback;if(r){let o=d.ensureError(r);o.phase="factory",o.moduleId=this.strId,o.neededBy=s(this.id),this.error=o,e.onError(o)}this.dependencies=null,this._callback=null,this._errorback=null,this.moduleIdResolver=null}onDependencyError(t){return this._isComplete=!0,this.error=t,this._errorback?(this._errorback(t),!0):!1}isComplete(){return this._isComplete}}d.Module=v;class f{constructor(){this._nextId=0,this._strModuleIdToIntModuleId=new Map,this._intModuleIdToStrModuleId=[],this.getModuleId("exports"),this.getModuleId("module"),this.getModuleId("require")}getMaxModuleId(){return this._nextId}getModuleId(t){let e=this._strModuleIdToIntModuleId.get(t);return typeof e>"u"&&(e=this._nextId++,this._strModuleIdToIntModuleId.set(t,e),this._intModuleIdToStrModuleId[e]=t),e}getStrModuleId(t){return this._intModuleIdToStrModuleId[t]}}class h{constructor(t){this.id=t}}h.EXPORTS=new h(0),h.MODULE=new h(1),h.REQUIRE=new h(2),d.RegularDependency=h;class n{constructor(t,e,i){this.id=t,this.pluginId=e,this.pluginParam=i}}d.PluginDependency=n;class c{constructor(t,e,i,s,r=0){this._env=t,this._scriptLoader=e,this._loaderAvailableTimestamp=r,this._defineFunc=i,this._requireFunc=s,this._moduleIdProvider=new f,this._config=new d.Configuration(this._env),this._hasDependencyCycle=!1,this._modules2=[],this._knownModules2=[],this._inverseDependencies2=[],this._inversePluginDependencies2=new Map,this._currentAnonymousDefineCall=null,this._recorder=null,this._buildInfoPath=[],this._buildInfoDefineStack=[],this._buildInfoDependencies=[],this._requireFunc.moduleManager=this}reset(){return new c(this._env,this._scriptLoader,this._defineFunc,this._requireFunc,this._loaderAvailableTimestamp)}getGlobalAMDDefineFunc(){return this._defineFunc}getGlobalAMDRequireFunc(){return this._requireFunc}static _findRelevantLocationInStack(t,e){let i=o=>o.replace(/\\/g,"/"),s=i(t),r=e.split(/\n/);for(let o=0;othis._moduleIdProvider.getStrModuleId(g.id))),this._resolve(l)}_normalizeDependency(t,e){if(t==="exports")return h.EXPORTS;if(t==="module")return h.MODULE;if(t==="require")return h.REQUIRE;let i=t.indexOf("!");if(i>=0){let s=e.resolveModule(t.substr(0,i)),r=e.resolveModule(t.substr(i+1)),o=this._moduleIdProvider.getModuleId(s+"!"+r),u=this._moduleIdProvider.getModuleId(s);return new n(o,u,r)}return new h(this._moduleIdProvider.getModuleId(e.resolveModule(t)))}_normalizeDependencies(t,e){let i=[],s=0;for(let r=0,o=t.length;rthis._moduleIdProvider.getStrModuleId(o));const r=d.ensureError(e);return r.phase="loading",r.moduleId=i,r.neededBy=s,r}_onLoadError(t,e){const i=this._createLoadError(t,e);this._modules2[t]||(this._modules2[t]=new v(t,this._moduleIdProvider.getStrModuleId(t),[],()=>{},null,null));let s=[];for(let u=0,l=this._moduleIdProvider.getMaxModuleId();u0;){let u=o.shift(),l=this._modules2[u];l&&(r=l.onDependencyError(i)||r);let g=this._inverseDependencies2[u];if(g)for(let p=0,m=g.length;p0;){let u=r.shift().dependencies;if(u)for(let l=0,g=u.length;lthis._relativeRequire(t,i,s,r);return e.toUrl=i=>this._config.requireToUrl(t.resolveModule(i)),e.getStats=()=>this.getLoaderEvents(),e.hasDependencyCycle=()=>this._hasDependencyCycle,e.config=(i,s=!1)=>{this.configure(i,s)},e.__$__nodeRequire=d.global.nodeRequire,e}_loadModule(t){if(this._modules2[t]||this._knownModules2[t])return;this._knownModules2[t]=!0;let e=this._moduleIdProvider.getStrModuleId(t),i=this._config.moduleIdToPaths(e),s=/^@[^\/]+\/[^\/]+$/;this._env.isNode&&(e.indexOf("/")===-1||s.test(e))&&i.push("node|"+e);let r=-1,o=u=>{if(r++,r>=i.length)this._onLoadError(t,u);else{let l=i[r],g=this.getRecorder();if(this._config.isBuild()&&l==="empty:"){this._buildInfoPath[t]=l,this.defineModule(this._moduleIdProvider.getStrModuleId(t),[],null,null,null),this._onLoad(t);return}g.record(10,l),this._scriptLoader.load(this,l,()=>{this._config.isBuild()&&(this._buildInfoPath[t]=l),g.record(11,l),this._onLoad(t)},p=>{g.record(12,l),o(p)})}};o(null)}_loadPluginDependency(t,e){if(this._modules2[e.id]||this._knownModules2[e.id])return;this._knownModules2[e.id]=!0;let i=s=>{this.defineModule(this._moduleIdProvider.getStrModuleId(e.id),[],s,null,null)};i.error=s=>{this._config.onError(this._createLoadError(e.id,s))},t.load(e.pluginParam,this._createRequire(_.ROOT),i,this._config.getOptionsLiteral())}_resolve(t){let e=t.dependencies;if(e)for(let i=0,s=e.length;ithis._moduleIdProvider.getStrModuleId(l)).join(` => `)),t.unresolvedDependenciesCount--;continue}if(this._inverseDependencies2[r.id]=this._inverseDependencies2[r.id]||[],this._inverseDependencies2[r.id].push(t.id),r instanceof n){let u=this._modules2[r.pluginId];if(u&&u.isComplete()){this._loadPluginDependency(u.exports,r);continue}let l=this._inversePluginDependencies2.get(r.pluginId);l||(l=[],this._inversePluginDependencies2.set(r.pluginId,l)),l.push(r),this._loadModule(r.pluginId);continue}this._loadModule(r.id)}t.unresolvedDependenciesCount===0&&this._onModuleComplete(t)}_onModuleComplete(t){let e=this.getRecorder();if(t.isComplete())return;let i=t.dependencies,s=[];if(i)for(let l=0,g=i.length;lthis._config.getConfigForModule(t.strId)};continue}if(p===h.REQUIRE){s[l]=this._createRequire(t.moduleIdResolver);continue}let m=this._modules2[p.id];if(m){s[l]=m.exports;continue}s[l]=null}const r=l=>(this._inverseDependencies2[l]||[]).map(g=>this._moduleIdProvider.getStrModuleId(g));t.complete(e,this._config,s,r);let o=this._inverseDependencies2[t.id];if(this._inverseDependencies2[t.id]=null,o)for(let l=0,g=o.length;l"u"&&c())})(AMDLoader||(AMDLoader={})),define("vs/css",["require","exports"],function(d,_){"use strict";Object.defineProperty(_,"__esModule",{value:!0}),_.load=v;function v(a,t,e,i){if(i=i||{},(i["vs/css"]||{}).disabled){e({});return}const r=t.toUrl(a+".css");f(a,r,()=>{e({})},o=>{typeof e.error=="function"&&e.error("Could not find "+r+".")})}function f(a,t,e,i){if(h(a,t)){e();return}n(a,t,e,i)}function h(a,t){const e=window.document.getElementsByTagName("link");for(let i=0,s=e.length;i{t.removeEventListener("load",r),t.removeEventListener("error",o)},r=u=>{s(),e()},o=u=>{s(),i(u)};t.addEventListener("load",r),t.addEventListener("error",o)}}),function(){const d=require.getConfig().baseUrl||"https://main.vscode-cdn.net/insider/336db9ece67f682159078ea1b54212de7636d88a/out";require.config({baseUrl:d,recordStats:!0,paths:{"@microsoft/1ds-core-js":"../node_modules/@microsoft/1ds-core-js/dist/ms.core.min.js","@microsoft/1ds-post-js":"../node_modules/@microsoft/1ds-post-js/dist/ms.post.min.js","@vscode/iconv-lite-umd":"../node_modules/@vscode/iconv-lite-umd/lib/iconv-lite-umd.js","@vscode/tree-sitter-wasm":"../node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.js","@vscode/vscode-languagedetection":"../node_modules/@vscode/vscode-languagedetection/dist/lib/index.js","@xterm/addon-clipboard":"../node_modules/@xterm/addon-clipboard/lib/addon-clipboard.js","@xterm/addon-image":"../node_modules/@xterm/addon-image/lib/addon-image.js","@xterm/addon-search":"../node_modules/@xterm/addon-search/lib/addon-search.js","@xterm/addon-serialize":"../node_modules/@xterm/addon-serialize/lib/addon-serialize.js","@xterm/addon-unicode11":"../node_modules/@xterm/addon-unicode11/lib/addon-unicode11.js","@xterm/addon-webgl":"../node_modules/@xterm/addon-webgl/lib/addon-webgl.js","@xterm/xterm":"../node_modules/@xterm/xterm/lib/xterm.js",jschardet:"../node_modules/jschardet/dist/jschardet.min.js","tas-client-umd":"../node_modules/tas-client-umd/lib/tas-client-umd.js","vscode-oniguruma":"../node_modules/vscode-oniguruma/release/main.js","vscode-textmate":"../node_modules/vscode-textmate/release/main.js","vscode-regexp-languagedetection":"../node_modules/vscode-regexp-languagedetection/dist/index.js",vsda:"../node_modules/vsda/rust/web/vsda.js","@microsoft/dynamicproto-js":"../node_modules/@microsoft/dynamicproto-js/lib/dist/umd/dynamicproto-js.min.js","@microsoft/applicationinsights-shims":"../node_modules/@microsoft/applicationinsights-shims/dist/umd/applicationinsights-shims.min.js","@microsoft/applicationinsights-core-js":"../node_modules/@microsoft/applicationinsights-core-js/browser/applicationinsights-core-js.min.js"}})}(); //# sourceMappingURL=https://main.vscode-cdn.net/sourcemaps/336db9ece67f682159078ea1b54212de7636d88a/core/vs/loader.js.map ================================================ FILE: build/monaco/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016 - present Microsoft Corporation 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. ================================================ FILE: build/monaco/README-npm.md ================================================ # monaco-editor-core > This npm module is a building block for the [monaco-editor](https://www.npmjs.com/package/monaco-editor) npm module and unless you are doing something special (e.g. authoring a monaco editor language that can be shipped and consumed independently), it is best to consume the [monaco-editor](https://www.npmjs.com/package/monaco-editor) module that contains this module and adds languages supports. The Monaco Editor is the code editor that powers [VS Code](https://github.com/microsoft/vscode). Here is a good page describing some [editor features](https://code.visualstudio.com/docs/editor/editingevolved). This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/microsoft/vscode). ## License [MIT](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) ================================================ FILE: build/monaco/README.md ================================================ # Steps to publish a new version of monaco-editor-core ## Generate monaco.d.ts * The `monaco.d.ts` is now automatically generated when running `gulp watch` ## Bump version * increase version in `build/monaco/package.json` ## Generate npm contents for monaco-editor-core * Be sure to have all changes committed **and pushed to the remote** * (the generated files contain the HEAD sha and that should be available on the remote) * run gulp editor-distro ## Publish * `cd out-monaco-editor-core` * `npm publish` ================================================ FILE: build/monaco/ThirdPartyNotices.txt ================================================ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION Do Not Translate or Localize This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. %% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158) ========================================= Copyright Joyent, Inc. and other Node contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF nodejs path library NOTICES AND INFORMATION %% markedjs NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/) Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF markedjs NOTICES AND INFORMATION ================================================ FILE: build/monaco/monaco.d.ts.recipe ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ declare let MonacoEnvironment: monaco.Environment | undefined; interface Window { MonacoEnvironment?: monaco.Environment | undefined; } declare namespace monaco { export type Thenable = PromiseLike; export interface Environment { /** * Define a global `monaco` symbol. * This is true by default in AMD and false by default in ESM. */ globalAPI?: boolean; /** * The base url where the editor sources are found (which contains the vs folder) */ baseUrl?: string; /** * A web worker factory. * NOTE: If `getWorker` is defined, `getWorkerUrl` is not invoked. */ getWorker?(workerId: string, label: string): Promise | Worker; /** * Return the location for web worker scripts. * NOTE: If `getWorker` is defined, `getWorkerUrl` is not invoked. */ getWorkerUrl?(workerId: string, label: string): string; /** * Create a trusted types policy (same API as window.trustedTypes.createPolicy) */ createTrustedTypesPolicy?( policyName: string, policyOptions?: ITrustedTypePolicyOptions, ): undefined | ITrustedTypePolicy; } export interface ITrustedTypePolicyOptions { createHTML?: (input: string, ...arguments: any[]) => string; createScript?: (input: string, ...arguments: any[]) => string; createScriptURL?: (input: string, ...arguments: any[]) => string; } export interface ITrustedTypePolicy { readonly name: string; createHTML?(input: string): any; createScript?(input: string): any; createScriptURL?(input: string): any; } export interface IDisposable { dispose(): void; } export interface IEvent { (listener: (e: T) => any, thisArg?: any): IDisposable; } /** * A helper that allows to emit and listen to typed events */ export class Emitter { constructor(); readonly event: Event; fire(event: T): void; dispose(): void; } #include(vs/platform/markers/common/markers): MarkerTag, MarkerSeverity #include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken #include(vs/base/common/uri): URI, UriComponents #include(vs/base/common/keyCodes): KeyCode #include(vs/editor/common/services/editorBaseApi): KeyMod #include(vs/base/common/htmlContent): IMarkdownString, MarkdownStringTrustedOptions #include(vs/base/browser/keyboardEvent): IKeyboardEvent #include(vs/base/browser/mouseEvent): IMouseEvent #include(vs/editor/common/editorCommon): IScrollEvent #include(vs/editor/common/core/position): IPosition, Position #include(vs/editor/common/core/range): IRange, Range #include(vs/editor/common/core/selection): ISelection, Selection, SelectionDirection #include(vs/editor/common/languages): Token } declare namespace monaco.editor { #includeAll(vs/editor/standalone/browser/standaloneEditor;languages.Token=>Token): #include(vs/editor/standalone/common/standaloneTheme): BuiltinTheme, IStandaloneThemeData, IColors #include(vs/editor/common/languages/supports/tokenization): ITokenThemeRule #include(vs/editor/standalone/browser/standaloneWebWorker): MonacoWebWorker, IInternalWebWorkerOptions #include(vs/editor/standalone/browser/standaloneCodeEditor): IActionDescriptor, IGlobalEditorOptions, IStandaloneEditorConstructionOptions, IStandaloneDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor export interface ICommandHandler { (...args: any[]): void; } export interface ILocalizedString { original: string; value: string; } export interface ICommandMetadata { readonly description: ILocalizedString | string; } #include(vs/platform/contextkey/common/contextkey): IContextKey, ContextKeyValue #include(vs/editor/standalone/browser/standaloneServices): IEditorOverrideServices #include(vs/platform/markers/common/markers): IMarker, IMarkerData, IRelatedInformation #include(vs/editor/standalone/browser/colorizer): IColorizerOptions, IColorizerElementOptions #include(vs/base/common/scrollable): ScrollbarVisibility #include(vs/base/common/themables): ThemeColor, ThemeIcon #include(vs/editor/common/core/editOperation): ISingleEditOperation #include(vs/editor/common/core/wordHelper): IWordAtPosition #includeAll(vs/editor/common/model): IScrollEvent #include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/core/dimension): IDimension #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): #includeAll(vs/editor/common/cursorEvents): #include(vs/platform/accessibility/common/accessibility): AccessibilitySupport #includeAll(vs/editor/common/config/editorOptions): #include(vs/editor/browser/config/editorConfiguration): IEditorConstructionOptions #includeAll(vs/editor/browser/editorBrowser;editorCommon.=>): #include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo #include(vs/editor/common/config/editorZoom): EditorZoom, IEditorZoom //compatibility: export type IReadOnlyModel = ITextModel; export type IModel = ITextModel; } declare namespace monaco.languages { #include(vs/base/common/glob): IRelativePattern #include(vs/editor/common/languageSelector): LanguageSelector, LanguageFilter #includeAll(vs/editor/standalone/browser/standaloneLanguages;languages.=>;editorCommon.=>editor.;model.=>editor.;IMarkerData=>editor.IMarkerData): #includeAll(vs/editor/common/languages/languageConfiguration): #includeAll(vs/editor/common/languages;IMarkerData=>editor.IMarkerData;ISingleEditOperation=>editor.ISingleEditOperation;model.=>editor.;ThemeIcon=>editor.ThemeIcon): Token #include(vs/editor/common/languages/language): ILanguageExtensionPoint #includeAll(vs/editor/standalone/common/monarch/monarchTypes): } declare namespace monaco.worker { #include(vs/editor/common/model/mirrorTextModel): IMirrorTextModel #includeAll(vs/editor/common/services/editorWebWorker;): } //dtsv=3 ================================================ FILE: build/monaco/monaco.usage.recipe ================================================ // This file is adding references to various symbols which should not be removed via tree shaking import { IObservable } from './vs/base/common/observable'; import { ServiceIdentifier } from './vs/platform/instantiation/common/instantiation'; import { start } from './vs/editor/editor.worker.start'; import { SyncDescriptor0 } from './vs/platform/instantiation/common/descriptors'; import * as editorAPI from './vs/editor/editor.api'; (function () { var a: any; var b: any; a = (>b).type; a = start; // injection madness a = (>b).ctor; // exported API a = editorAPI.CancellationTokenSource; a = editorAPI.Emitter; a = editorAPI.KeyCode; a = editorAPI.KeyMod; a = editorAPI.Position; a = editorAPI.Range; a = editorAPI.Selection; a = editorAPI.SelectionDirection; a = editorAPI.MarkerSeverity; a = editorAPI.MarkerTag; a = editorAPI.Uri; a = editorAPI.Token; a = editorAPI.editor; a = editorAPI.languages; const o: IObservable = null!; o.TChange; })(); ================================================ FILE: build/monaco/package.json ================================================ { "name": "monaco-editor-core", "private": true, "version": "0.0.0", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", "typings": "./esm/vs/editor/editor.api.d.ts", "module": "./esm/vs/editor/editor.main.js", "repository": { "type": "git", "url": "https://github.com/microsoft/vscode" }, "bugs": { "url": "https://github.com/microsoft/vscode/issues" } } ================================================ FILE: build/monaco/version.txt ================================================ ================================================ FILE: build/npm/dirs.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const fs = require('fs'); // Complete list of directories where npm should be executed to install node modules const dirs = [ '', 'build', 'extensions', 'extensions/configuration-editing', 'extensions/css-language-features', 'extensions/css-language-features/server', 'extensions/debug-auto-launch', 'extensions/debug-server-ready', 'extensions/emmet', 'extensions/extension-editing', 'extensions/git', 'extensions/git-base', 'extensions/github', 'extensions/github-authentication', 'extensions/grunt', 'extensions/gulp', 'extensions/html-language-features', 'extensions/html-language-features/server', 'extensions/ipynb', 'extensions/jake', 'extensions/json-language-features', 'extensions/json-language-features/server', 'extensions/markdown-language-features', 'extensions/markdown-math', 'extensions/media-preview', 'extensions/merge-conflict', 'extensions/microsoft-authentication', 'extensions/notebook-renderers', 'extensions/npm', 'extensions/php-language-features', 'extensions/references-view', 'extensions/search-result', 'extensions/simple-browser', 'extensions/tunnel-forwarding', 'extensions/typescript-language-features', 'extensions/vscode-api-tests', 'extensions/vscode-colorize-tests', 'extensions/vscode-colorize-perf-tests', 'extensions/vscode-test-resolver', 'remote', 'remote/web', 'test/automation', 'test/integration/browser', 'test/monaco', 'test/smoke', '.vscode/extensions/vscode-selfhost-import-aid', '.vscode/extensions/vscode-selfhost-test-provider', 'extensions/open-remote-ssh', // Void added this 'extensions/open-remote-wsl', // Void added this ]; if (fs.existsSync(`${__dirname}/../../.build/distro/npm`)) { dirs.push('.build/distro/npm'); dirs.push('.build/distro/npm/remote'); dirs.push('.build/distro/npm/remote/web'); } exports.dirs = dirs; ================================================ FILE: build/npm/gyp/package.json ================================================ { "name": "code-oss-dev-build", "version": "1.0.0", "private": true, "license": "MIT", "devDependencies": { "node-gyp": "^10.1.0" }, "scripts": {} } ================================================ FILE: build/npm/jsconfig.json ================================================ { "compilerOptions": { "target": "es2020", "lib": [ "ES2020" ], "module": "node16", "checkJs": true, "noEmit": true } } ================================================ FILE: build/npm/postinstall.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const fs = require('fs'); const path = require('path'); const os = require('os'); const cp = require('child_process'); const { dirs } = require('./dirs'); const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'; const root = path.dirname(path.dirname(__dirname)); function log(dir, message) { if (process.stdout.isTTY) { console.log(`\x1b[34m[${dir}]\x1b[0m`, message); } else { console.log(`[${dir}]`, message); } } function run(command, args, opts) { log(opts.cwd || '.', '$ ' + command + ' ' + args.join(' ')); const result = cp.spawnSync(command, args, opts); if (result.error) { console.error(`ERR Failed to spawn process: ${result.error}`); process.exit(1); } else if (result.status !== 0) { console.error(`ERR Process exited with code: ${result.status}`); process.exit(result.status); } } /** * @param {string} dir * @param {*} [opts] */ function npmInstall(dir, opts) { opts = { env: { ...process.env }, ...(opts ?? {}), cwd: dir, stdio: 'inherit', shell: true }; const command = process.env['npm_command'] || 'install'; if (process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME'] && /^(.build\/distro\/npm\/)?remote$/.test(dir)) { const userinfo = os.userInfo(); log(dir, `Installing dependencies inside container ${process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME']}...`); opts.cwd = root; if (process.env['npm_config_arch'] === 'arm64') { run('sudo', ['docker', 'run', '--rm', '--privileged', 'multiarch/qemu-user-static', '--reset', '-p', 'yes'], opts); } run('sudo', ['docker', 'run', '-e', 'GITHUB_TOKEN', '-v', `${process.env['VSCODE_HOST_MOUNT']}:/root/vscode`, '-v', `${process.env['VSCODE_HOST_MOUNT']}/.build/.netrc:/root/.netrc`, '-w', path.resolve('/root/vscode', dir), process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME'], 'sh', '-c', `\"chown -R root:root ${path.resolve('/root/vscode', dir)} && npm i -g node-gyp-build && npm ci\"`], opts); run('sudo', ['chown', '-R', `${userinfo.uid}:${userinfo.gid}`, `${path.resolve(root, dir)}`], opts); } else { log(dir, 'Installing dependencies...'); run(npm, command.split(' '), opts); } removeParcelWatcherPrebuild(dir); } function setNpmrcConfig(dir, env) { const npmrcPath = path.join(root, dir, '.npmrc'); const lines = fs.readFileSync(npmrcPath, 'utf8').split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine && !trimmedLine.startsWith('#')) { const [key, value] = trimmedLine.split('='); env[`npm_config_${key}`] = value.replace(/^"(.*)"$/, '$1'); } } // Force node-gyp to use process.config on macOS // which defines clang variable as expected. Otherwise we // run into compilation errors due to incorrect compiler // configuration. // NOTE: This means the process.config should contain // the correct clang variable. So keep the version check // in preinstall sync with this logic. // Change was first introduced in https://github.com/nodejs/node/commit/6e0a2bb54c5bbeff0e9e33e1a0c683ed980a8a0f if ((dir === 'remote' || dir === 'build') && process.platform === 'darwin') { env['npm_config_force_process_config'] = 'true'; } else { delete env['npm_config_force_process_config']; } if (dir === 'build') { env['npm_config_target'] = process.versions.node; env['npm_config_arch'] = process.arch; } } function removeParcelWatcherPrebuild(dir) { const parcelModuleFolder = path.join(root, dir, 'node_modules', '@parcel'); if (!fs.existsSync(parcelModuleFolder)) { return; } const parcelModules = fs.readdirSync(parcelModuleFolder); for (const moduleName of parcelModules) { if (moduleName.startsWith('watcher-')) { const modulePath = path.join(parcelModuleFolder, moduleName); fs.rmSync(modulePath, { recursive: true, force: true }); log(dir, `Removed @parcel/watcher prebuilt module ${modulePath}`); } } } for (let dir of dirs) { if (dir === '') { removeParcelWatcherPrebuild(dir); continue; // already executed in root } let opts; if (dir === 'build') { opts = { env: { ...process.env }, } if (process.env['CC']) { opts.env['CC'] = 'gcc'; } if (process.env['CXX']) { opts.env['CXX'] = 'g++'; } if (process.env['CXXFLAGS']) { opts.env['CXXFLAGS'] = ''; } if (process.env['LDFLAGS']) { opts.env['LDFLAGS'] = ''; } setNpmrcConfig('build', opts.env); npmInstall('build', opts); continue; } if (/^(.build\/distro\/npm\/)?remote$/.test(dir)) { // node modules used by vscode server opts = { env: { ...process.env }, } if (process.env['VSCODE_REMOTE_CC']) { opts.env['CC'] = process.env['VSCODE_REMOTE_CC']; } else { delete opts.env['CC']; } if (process.env['VSCODE_REMOTE_CXX']) { opts.env['CXX'] = process.env['VSCODE_REMOTE_CXX']; } else { delete opts.env['CXX']; } if (process.env['CXXFLAGS']) { delete opts.env['CXXFLAGS']; } if (process.env['CFLAGS']) { delete opts.env['CFLAGS']; } if (process.env['LDFLAGS']) { delete opts.env['LDFLAGS']; } if (process.env['VSCODE_REMOTE_CXXFLAGS']) { opts.env['CXXFLAGS'] = process.env['VSCODE_REMOTE_CXXFLAGS']; } if (process.env['VSCODE_REMOTE_LDFLAGS']) { opts.env['LDFLAGS'] = process.env['VSCODE_REMOTE_LDFLAGS']; } if (process.env['VSCODE_REMOTE_NODE_GYP']) { opts.env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; } const globalGypPath = path.join(os.homedir(), '.gyp'); const globalInclude = path.join(globalGypPath, 'include.gypi'); const tempGlobalInclude = path.join(globalGypPath, 'include.gypi.bak'); if (process.platform === 'linux' && (process.env['CI'] || process.env['BUILD_ARTIFACTSTAGINGDIRECTORY'])) { // Following include file rename should be removed // when `Override gnu target for arm64 and arm` step // is removed from the product build pipeline. if (fs.existsSync(globalInclude)) { fs.renameSync(globalInclude, tempGlobalInclude); } } setNpmrcConfig('remote', opts.env); npmInstall(dir, opts); if (process.platform === 'linux' && (process.env['CI'] || process.env['BUILD_ARTIFACTSTAGINGDIRECTORY'])) { if (fs.existsSync(tempGlobalInclude)) { fs.renameSync(tempGlobalInclude, globalInclude); } } continue; } npmInstall(dir, opts); } cp.execSync('git config pull.rebase merges'); cp.execSync('git config blame.ignoreRevsFile .git-blame-ignore-revs'); ================================================ FILE: build/npm/preinstall.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const nodeVersion = /^(\d+)\.(\d+)\.(\d+)/.exec(process.versions.node); const majorNodeVersion = parseInt(nodeVersion[1]); const minorNodeVersion = parseInt(nodeVersion[2]); const patchNodeVersion = parseInt(nodeVersion[3]); if (!process.env['VSCODE_SKIP_NODE_VERSION_CHECK']) { if (majorNodeVersion < 20 || (majorNodeVersion === 20 && minorNodeVersion < 18) || (majorNodeVersion === 20 && minorNodeVersion === 18 && patchNodeVersion < 1)) { console.error('\x1b[1;31m*** Please use Node.js v20.18.1 or later for development.\x1b[0;0m'); throw new Error(); } } if (process.env['npm_execpath'].includes('yarn')) { console.error('\x1b[1;31m*** Seems like you are using `yarn` which is not supported in this repo any more, please use `npm i` instead. ***\x1b[0;0m'); throw new Error(); } const path = require('path'); const fs = require('fs'); const cp = require('child_process'); const os = require('os'); if (process.platform === 'win32') { if (!hasSupportedVisualStudioVersion()) { console.error('\x1b[1;31m*** Invalid C/C++ Compiler Toolchain. Please check https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites.\x1b[0;0m'); throw new Error(); } installHeaders(); } if (process.arch !== os.arch()) { console.error(`\x1b[1;31m*** ARCHITECTURE MISMATCH: The node.js process is ${process.arch}, but your OS architecture is ${os.arch()}. ***\x1b[0;0m`); console.error(`\x1b[1;31m*** This can greatly increase the build time of vs code. ***\x1b[0;0m`); } function hasSupportedVisualStudioVersion() { const fs = require('fs'); const path = require('path'); // Translated over from // https://source.chromium.org/chromium/chromium/src/+/master:build/vs_toolchain.py;l=140-175 const supportedVersions = ['2022', '2019', '2017']; const availableVersions = []; for (const version of supportedVersions) { let vsPath = process.env[`vs${version}_install`]; if (vsPath && fs.existsSync(vsPath)) { availableVersions.push(version); break; } const programFiles86Path = process.env['ProgramFiles(x86)']; const programFiles64Path = process.env['ProgramFiles']; const vsTypes = ['Enterprise', 'Professional', 'Community', 'Preview', 'BuildTools', 'IntPreview']; if (programFiles64Path) { vsPath = `${programFiles64Path}/Microsoft Visual Studio/${version}`; if (vsTypes.some(vsType => fs.existsSync(path.join(vsPath, vsType)))) { availableVersions.push(version); break; } } if (programFiles86Path) { vsPath = `${programFiles86Path}/Microsoft Visual Studio/${version}`; if (vsTypes.some(vsType => fs.existsSync(path.join(vsPath, vsType)))) { availableVersions.push(version); break; } } } return availableVersions.length; } function installHeaders() { cp.execSync(`npm.cmd ${process.env['npm_command'] || 'ci'}`, { env: process.env, cwd: path.join(__dirname, 'gyp'), stdio: 'inherit' }); // The node gyp package got installed using the above npm command using the gyp/package.json // file checked into our repository. So from that point it is save to construct the path // to that executable const node_gyp = path.join(__dirname, 'gyp', 'node_modules', '.bin', 'node-gyp.cmd'); const result = cp.execFileSync(node_gyp, ['list'], { encoding: 'utf8', shell: true }); const versions = new Set(result.split(/\n/g).filter(line => !line.startsWith('gyp info')).map(value => value)); const local = getHeaderInfo(path.join(__dirname, '..', '..', '.npmrc')); const remote = getHeaderInfo(path.join(__dirname, '..', '..', 'remote', '.npmrc')); if (local !== undefined && !versions.has(local.target)) { // Both disturl and target come from a file checked into our repository cp.execFileSync(node_gyp, ['install', '--dist-url', local.disturl, local.target], { shell: true }); } if (remote !== undefined && !versions.has(remote.target)) { // Both disturl and target come from a file checked into our repository cp.execFileSync(node_gyp, ['install', '--dist-url', remote.disturl, remote.target], { shell: true }); } } /** * @param {string} rcFile * @returns {{ disturl: string; target: string } | undefined} */ function getHeaderInfo(rcFile) { const lines = fs.readFileSync(rcFile, 'utf8').split(/\r\n?/g); let disturl, target; for (const line of lines) { let match = line.match(/\s*disturl=*\"(.*)\"\s*$/); if (match !== null && match.length >= 1) { disturl = match[1]; } match = line.match(/\s*target=*\"(.*)\"\s*$/); if (match !== null && match.length >= 1) { target = match[1]; } } return disturl !== undefined && target !== undefined ? { disturl, target } : undefined; } ================================================ FILE: build/npm/update-all-grammars.mjs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { spawn as _spawn } from 'child_process'; import { readdirSync, readFileSync } from 'fs'; import { join } from 'path'; import url from 'url'; async function spawn(cmd, args, opts) { return new Promise((c, e) => { const child = _spawn(cmd, args, { shell: true, stdio: 'inherit', env: process.env, ...opts }); child.on('close', code => code === 0 ? c() : e(`Returned ${code}`)); }); } async function main() { await spawn('npm', ['ci'], { cwd: 'extensions' }); for (const extension of readdirSync('extensions')) { try { const packageJSON = JSON.parse(readFileSync(join('extensions', extension, 'package.json')).toString()); if (!(packageJSON && packageJSON.scripts && packageJSON.scripts['update-grammar'])) { continue; } } catch { continue; } await spawn(`npm`, ['run', 'update-grammar'], { cwd: `extensions/${extension}` }); } // run integration tests if (process.platform === 'win32') { _spawn('.\\scripts\\test-integration.bat', [], { env: process.env, stdio: 'inherit' }); } else { _spawn('/bin/bash', ['./scripts/test-integration.sh'], { env: process.env, stdio: 'inherit' }); } } if (import.meta.url === url.pathToFileURL(process.argv[1]).href) { main().catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/npm/update-distro.mjs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { execSync } from 'child_process'; import { join, resolve } from 'path'; import { readFileSync, writeFileSync } from 'fs'; import { fileURLToPath } from 'url'; const rootPath = resolve(fileURLToPath(import.meta.url), '..', '..', '..', '..'); const vscodePath = join(rootPath, 'vscode'); const distroPath = join(rootPath, 'vscode-distro'); const commit = execSync('git rev-parse HEAD', { cwd: distroPath, encoding: 'utf8' }).trim(); const packageJsonPath = join(vscodePath, 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); packageJson.distro = commit; writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); ================================================ FILE: build/npm/update-localization-extension.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; let i18n = require("../lib/i18n"); let fs = require("fs"); let path = require("path"); let gulp = require('gulp'); let vfs = require("vinyl-fs"); let rimraf = require('rimraf'); let minimist = require('minimist'); function update(options) { let idOrPath = options._; if (!idOrPath) { throw new Error('Argument must be the location of the localization extension.'); } let location = options.location; if (location !== undefined && !fs.existsSync(location)) { throw new Error(`${location} doesn't exist.`); } let externalExtensionsLocation = options.externalExtensionsLocation; if (externalExtensionsLocation !== undefined && !fs.existsSync(externalExtensionsLocation)) { throw new Error(`${externalExtensionsLocation} doesn't exist.`); } let locExtFolder = idOrPath; if (/^\w{2,3}(-\w+)?$/.test(idOrPath)) { locExtFolder = path.join('..', 'vscode-loc', 'i18n', `vscode-language-pack-${idOrPath}`); } let locExtStat = fs.statSync(locExtFolder); if (!locExtStat || !locExtStat.isDirectory) { throw new Error('No directory found at ' + idOrPath); } let packageJSON = JSON.parse(fs.readFileSync(path.join(locExtFolder, 'package.json')).toString()); let contributes = packageJSON['contributes']; if (!contributes) { throw new Error('The extension must define a "localizations" contribution in the "package.json"'); } let localizations = contributes['localizations']; if (!localizations) { throw new Error('The extension must define a "localizations" contribution of type array in the "package.json"'); } localizations.forEach(function (localization) { if (!localization.languageId || !localization.languageName || !localization.localizedLanguageName) { throw new Error('Each localization contribution must define "languageId", "languageName" and "localizedLanguageName" properties.'); } let languageId = localization.languageId; let translationDataFolder = path.join(locExtFolder, 'translations'); switch (languageId) { case 'zh-cn': languageId = 'zh-Hans'; break; case 'zh-tw': languageId = 'zh-Hant'; break; case 'pt-br': languageId = 'pt-BR'; break; } if (fs.existsSync(translationDataFolder) && fs.existsSync(path.join(translationDataFolder, 'main.i18n.json'))) { console.log('Clearing \'' + translationDataFolder + '\'...'); rimraf.sync(translationDataFolder); } console.log(`Importing translations for ${languageId} form '${location}' to '${translationDataFolder}' ...`); let translationPaths = []; gulp.src([ path.join(location, '**', languageId, '*.xlf'), ...i18n.EXTERNAL_EXTENSIONS.map(extensionId => path.join(externalExtensionsLocation, extensionId, languageId, '*-new.xlf')) ], { silent: false }) .pipe(i18n.prepareI18nPackFiles(translationPaths)) .on('error', (error) => { console.log(`Error occurred while importing translations:`); translationPaths = undefined; if (Array.isArray(error)) { error.forEach(console.log); } else if (error) { console.log(error); } else { console.log('Unknown error'); } }) .pipe(vfs.dest(translationDataFolder)) .on('end', function () { if (translationPaths !== undefined) { localization.translations = []; for (let tp of translationPaths) { localization.translations.push({ id: tp.id, path: `./translations/${tp.resourceName}` }); } fs.writeFileSync(path.join(locExtFolder, 'package.json'), JSON.stringify(packageJSON, null, '\t') + '\n'); } }); }); } if (path.basename(process.argv[1]) === 'update-localization-extension.js') { var options = minimist(process.argv.slice(2), { string: ['location', 'externalExtensionsLocation'] }); update(options); } ================================================ FILE: build/package.json ================================================ { "name": "code-oss-dev-build", "version": "1.0.0", "license": "MIT", "devDependencies": { "@azure/core-auth": "^1.9.0", "@azure/cosmos": "^3", "@azure/identity": "^4.2.1", "@azure/msal-node": "^2.16.1", "@azure/storage-blob": "^12.25.0", "@electron/get": "^2.0.0", "@types/ansi-colors": "^3.2.0", "@types/byline": "^4.2.32", "@types/debounce": "^1.0.0", "@types/debug": "^4.1.5", "@types/fancy-log": "^1.3.0", "@types/fs-extra": "^9.0.12", "@types/glob": "^7.1.1", "@types/gulp": "^4.0.17", "@types/gulp-filter": "^3.0.32", "@types/gulp-gzip": "^0.0.31", "@types/gulp-json-editor": "^2.2.31", "@types/gulp-rename": "^0.0.33", "@types/gulp-sort": "^2.0.4", "@types/gulp-sourcemaps": "^0.0.32", "@types/jws": "^3.2.10", "@types/mime": "0.0.29", "@types/minimatch": "^3.0.3", "@types/minimist": "^1.2.1", "@types/mocha": "^9.1.1", "@types/node": "20.x", "@types/pump": "^1.0.1", "@types/rimraf": "^2.0.4", "@types/through": "^0.0.29", "@types/through2": "^2.0.36", "@types/workerpool": "^6.4.0", "@types/xml2js": "0.0.33", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/ripgrep": "^1.15.10", "@vscode/vsce": "2.20.1", "byline": "^5.0.0", "debug": "^4.3.2", "electron-osx-sign": "^0.4.16", "esbuild": "0.25.0", "extract-zip": "^2.0.1", "gulp-merge-json": "^2.1.1", "gulp-sort": "^2.0.0", "jsonc-parser": "^2.3.0", "jws": "^4.0.0", "mime": "^1.4.1", "source-map": "0.6.1", "ternary-stream": "^3.0.0", "through2": "^4.0.2", "tree-sitter": "^0.22.4", "vscode-universal-bundler": "^0.1.3", "workerpool": "^6.4.0", "yauzl": "^2.10.0" }, "type": "commonjs", "scripts": { "compile": "../node_modules/.bin/tsc -p tsconfig.build.json", "watch": "../node_modules/.bin/tsc -p tsconfig.build.json --watch", "npmCheckJs": "../node_modules/.bin/tsc --noEmit" }, "optionalDependencies": { "tree-sitter-typescript": "^0.23.2", "vscode-gulp-watch": "^5.0.3" } } ================================================ FILE: build/setup-npm-registry.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; const fs = require('fs').promises; const path = require('path'); async function* getPackageLockFiles(dir) { const files = await fs.readdir(dir); for (const file of files) { const fullPath = path.join(dir, file); const stat = await fs.stat(fullPath); if (stat.isDirectory()) { yield* getPackageLockFiles(fullPath); } else if (file === 'package-lock.json') { yield fullPath; } } } async function setup(url, file) { let contents = await fs.readFile(file, 'utf8'); contents = contents.replace(/https:\/\/registry\.[^.]+\.com\//g, url); await fs.writeFile(file, contents); } async function main(url, dir) { const root = dir ?? process.cwd(); for await (const file of getPackageLockFiles(root)) { console.log(`Enabling custom NPM registry: ${path.relative(root, file)}`); await setup(url, file); } } main(process.argv[2], process.argv[3]); ================================================ FILE: build/stylelint.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const es = require('event-stream'); const vfs = require('vinyl-fs'); const { stylelintFilter } = require('./filters'); const { getVariableNameValidator } = require('./lib/stylelint/validateVariableNames'); module.exports = gulpstylelint; /** use regex on lines */ function gulpstylelint(reporter) { const variableValidator = getVariableNameValidator(); let errorCount = 0; return es.through(function (file) { const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; lines.forEach((line, i) => { variableValidator(line, unknownVariable => { reporter(file.relative + '(' + (i + 1) + ',1): Unknown variable: ' + unknownVariable, true); errorCount++; }); }); this.emit('data', file); }, function () { if (errorCount > 0) { reporter('All valid variable names are in `build/lib/stylelint/vscode-known-variables.json`\nTo update that file, run `./scripts/test-documentation.sh|bat.`', false); } this.emit('end'); } ); } function stylelint() { return vfs .src(stylelintFilter, { base: '.', follow: true, allowEmpty: true }) .pipe(gulpstylelint((message, isError) => { if (isError) { console.error(message); } else { console.info(message); } })) .pipe(es.through(function () { /* noop, important for the stream to end */ })); } if (require.main === module) { stylelint().on('error', (err) => { console.error(); console.error(err); process.exit(1); }); } ================================================ FILE: build/tsconfig.build.json ================================================ { "extends": "./tsconfig.json", "compilerOptions": { "allowJs": false, "checkJs": false, "noEmit": false, "skipLibCheck": true }, "include": [ "**/*.ts" ], "exclude": [ "lib/eslint-plugin-vscode/**/*" ] } ================================================ FILE: build/tsconfig.json ================================================ { "compilerOptions": { "target": "es2022", "lib": [ "ES2020" ], "module": "nodenext", "alwaysStrict": true, "removeComments": false, "preserveConstEnums": true, "sourceMap": true, "resolveJsonModule": true, // enable JavaScript type checking for the language service // use the tsconfig.build.json for compiling which disable JavaScript // type checking so that JavaScript file are not transpiled "allowJs": true, "strict": true, "exactOptionalPropertyTypes": false, "useUnknownInCatchVariables": false, "noUnusedLocals": true, "noUnusedParameters": true, "newLine": "lf", "noEmit": true }, "include": [ "**/*.ts", "**/*.js" ], "exclude": [ "node_modules/**" ] } ================================================ FILE: build/win32/.gitignore ================================================ code-processed.iss ================================================ FILE: build/win32/Cargo.toml ================================================ [package] name = "inno_updater" version = "0.14.2" authors = ["Microsoft "] build = "build.rs" [dependencies] byteorder = "1.4.3" crc = "3.0.1" slog = "2.7.0" slog-async = "2.7.0" slog-term = "2.9.1" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.42" features = [ "Win32_Foundation", "Win32_System_Shutdown", "Win32_UI_WindowsAndMessaging", "Win32_System_Threading", "Win32_System_LibraryLoader", "Win32_System_Diagnostics_Debug", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_ProcessStatus", "Win32_System_Diagnostics_ToolHelp" ] [profile.release] lto = true panic = 'abort' ================================================ FILE: build/win32/code.iss ================================================ #define RootLicenseFileName FileExists(RepoDir + '\LICENSE.rtf') ? 'LICENSE.rtf' : 'LICENSE.txt' #define LocalizedLanguageFile(Language = "") \ DirExists(RepoDir + "\licenses") && Language != "" \ ? ('; LicenseFile: "' + RepoDir + '\licenses\LICENSE-' + Language + '.rtf"') \ : '; LicenseFile: "' + RepoDir + '\' + RootLicenseFileName + '"' [Setup] AppId={#AppId} AppName={#NameLong} AppVerName={#NameVersion} AppPublisher=Microsoft Corporation AppPublisherURL=https://code.visualstudio.com/ AppSupportURL=https://code.visualstudio.com/ AppUpdatesURL=https://code.visualstudio.com/ DefaultGroupName={#NameLong} AllowNoIcons=yes OutputDir={#OutputDir} OutputBaseFilename=VSCodeSetup Compression=lzma SolidCompression=yes AppMutex={code:GetAppMutex} SetupMutex={#AppMutex}setup ; this is a // Void icon comment. Old: WizardImageFile="{#RepoDir}\resources\win32\inno-big-100.bmp,{#RepoDir}\resources\win32\inno-big-125.bmp,{#RepoDir}\resources\win32\inno-big-150.bmp,{#RepoDir}\resources\win32\inno-big-175.bmp,{#RepoDir}\resources\win32\inno-big-200.bmp,{#RepoDir}\resources\win32\inno-big-225.bmp,{#RepoDir}\resources\win32\inno-big-250.bmp" ; this is a // Void icon comment. Old: WizardSmallImageFile="{#RepoDir}\resources\win32\inno-small-100.bmp,{#RepoDir}\resources\win32\inno-small-125.bmp,{#RepoDir}\resources\win32\inno-small-150.bmp,{#RepoDir}\resources\win32\inno-small-175.bmp,{#RepoDir}\resources\win32\inno-small-200.bmp,{#RepoDir}\resources\win32\inno-small-225.bmp,{#RepoDir}\resources\win32\inno-small-250.bmp" ; COMMENTED OUT WizardImageFile="" WizardSmallImageFile="{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp,{#RepoDir}\resources\win32\inno-void.bmp" SetupIconFile={#RepoDir}\resources\win32\code.ico UninstallDisplayIcon={app}\{#ExeBasename}.exe ChangesEnvironment=true ChangesAssociations=true MinVersion=10.0 SourceDir={#SourceDir} AppVersion={#Version} VersionInfoVersion={#RawVersion} ShowLanguageDialog=auto ArchitecturesAllowed={#ArchitecturesAllowed} ArchitecturesInstallIn64BitMode={#ArchitecturesInstallIn64BitMode} WizardStyle=modern // We've seen an uptick on broken installations from updates which were unable // to shutdown VS Code. We rely on the fact that the update signals // that VS Code is ready to be shutdown, so we're good to use `force` here. CloseApplications=force #ifdef Sign SignTool=esrp #endif #if "user" == InstallTarget DefaultDirName={userpf}\{#DirName} PrivilegesRequired=lowest #else DefaultDirName={pf}\{#DirName} #endif [Languages] Name: "english"; MessagesFile: "compiler:Default.isl,{#RepoDir}\build\win32\i18n\messages.en.isl" {#LocalizedLanguageFile} Name: "german"; MessagesFile: "compiler:Languages\German.isl,{#RepoDir}\build\win32\i18n\messages.de.isl" {#LocalizedLanguageFile("deu")} Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl,{#RepoDir}\build\win32\i18n\messages.es.isl" {#LocalizedLanguageFile("esp")} Name: "french"; MessagesFile: "compiler:Languages\French.isl,{#RepoDir}\build\win32\i18n\messages.fr.isl" {#LocalizedLanguageFile("fra")} Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl,{#RepoDir}\build\win32\i18n\messages.it.isl" {#LocalizedLanguageFile("ita")} Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl,{#RepoDir}\build\win32\i18n\messages.ja.isl" {#LocalizedLanguageFile("jpn")} Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl,{#RepoDir}\build\win32\i18n\messages.ru.isl" {#LocalizedLanguageFile("rus")} Name: "korean"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.ko.isl,{#RepoDir}\build\win32\i18n\messages.ko.isl" {#LocalizedLanguageFile("kor")} Name: "simplifiedChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-cn.isl,{#RepoDir}\build\win32\i18n\messages.zh-cn.isl" {#LocalizedLanguageFile("chs")} Name: "traditionalChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-tw.isl,{#RepoDir}\build\win32\i18n\messages.zh-tw.isl" {#LocalizedLanguageFile("cht")} Name: "brazilianPortuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl,{#RepoDir}\build\win32\i18n\messages.pt-br.isl" {#LocalizedLanguageFile("ptb")} Name: "hungarian"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.hu.isl,{#RepoDir}\build\win32\i18n\messages.hu.isl" {#LocalizedLanguageFile("hun")} Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl,{#RepoDir}\build\win32\i18n\messages.tr.isl" {#LocalizedLanguageFile("trk")} [InstallDelete] Type: filesandordirs; Name: "{app}\resources\app\out"; Check: IsNotBackgroundUpdate Type: filesandordirs; Name: "{app}\resources\app\plugins"; Check: IsNotBackgroundUpdate Type: filesandordirs; Name: "{app}\resources\app\extensions"; Check: IsNotBackgroundUpdate Type: filesandordirs; Name: "{app}\resources\app\node_modules"; Check: IsNotBackgroundUpdate Type: filesandordirs; Name: "{app}\resources\app\node_modules.asar.unpacked"; Check: IsNotBackgroundUpdate Type: files; Name: "{app}\resources\app\node_modules.asar"; Check: IsNotBackgroundUpdate Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNotBackgroundUpdate [UninstallDelete] Type: filesandordirs; Name: "{app}\_" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 Name: "addcontextmenufiles"; Description: "{cm:AddContextMenuFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked Name: "addcontextmenufolders"; Description: "{cm:AddContextMenuFolders,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked; Check: not (IsWindows11OrLater and QualityIsInsiders) Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameShort}}"; GroupDescription: "{cm:Other}" Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}" Name: "runcode"; Description: "{cm:RunAfter,{#NameShort}}"; GroupDescription: "{cm:Other}"; Check: WizardSilent [Dirs] Name: "{app}"; AfterInstall: DisableAppDirInheritance [Files] Source: "*"; Excludes: "\CodeSignSummary*.md,\tools,\tools\*,\appx,\appx\*,\resources\app\product.json"; DestDir: "{code:GetDestDir}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "tools\*"; DestDir: "{app}\tools"; Flags: ignoreversion Source: "{#ProductJsonPath}"; DestDir: "{code:GetDestDir}\resources\app"; Flags: ignoreversion #ifdef AppxPackageFullname Source: "appx\*"; DestDir: "{app}\appx"; BeforeInstall: RemoveAppxPackage; AfterInstall: AddAppxPackage; Flags: ignoreversion; Check: IsWindows11OrLater and QualityIsInsiders #endif [Icons] Name: "{group}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUserModelID: "{#AppUserId}" Name: "{autodesktop}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; Tasks: desktopicon; AppUserModelID: "{#AppUserId}" Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; Tasks: quicklaunchicon; AppUserModelID: "{#AppUserId}" [Run] Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: ShouldRunAfterUpdate Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Flags: nowait postinstall; Check: WizardNotSilent #ifdef AppxPackageFullname [UninstallRun] Filename: "powershell.exe"; Parameters: "Invoke-Command -ScriptBlock {{Remove-AppxPackage -Package ""{#AppxPackageFullname}""}"; Check: IsWindows11OrLater and QualityIsInsiders; Flags: shellexec waituntilterminated runhidden #endif [Registry] #if "user" == InstallTarget #define SoftwareClassesRootKey "HKCU" #else #define SoftwareClassesRootKey "HKLM" #endif Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ascx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ascx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ascx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ascx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,ASCX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ascx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ascx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\xml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ascx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ascx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.asp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.asp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.asp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.asp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,ASP}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.asp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.asp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.asp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.asp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.aspx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.aspx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.aspx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.aspx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,ASPX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.aspx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.aspx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.aspx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.aspx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bash"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bash}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_login\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_login\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bash_login"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_login"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bash Login}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_login"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_login\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_login\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_login\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_logout\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_logout\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bash_logout"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_logout"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bash Logout}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_logout"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_logout\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_logout\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_logout\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_profile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bash_profile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bash_profile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_profile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bash Profile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_profile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_profile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_profile\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bash_profile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bashrc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bashrc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bashrc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bashrc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bash RC}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bashrc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bashrc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bashrc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bashrc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bib\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bib\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bib"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bib"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,BibTeX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bib"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bib\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bib\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bib\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bowerrc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.bowerrc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.bowerrc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bowerrc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Bower RC}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bowerrc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bowerrc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\bower.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bowerrc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.bowerrc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.c++\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.c++\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.c++"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c++"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c++"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c++\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c++\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.c\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.c\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.c"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\c.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.c\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cfg\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cfg\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cfg"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cfg"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Configuration}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cfg"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cfg\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cfg\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cfg\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cjs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cjs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cjs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cjs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JavaScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cjs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cjs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\javascript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cjs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cjs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.clj\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.clj\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.clj"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clj"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Clojure}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clj"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clj\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clj\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clj\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cljs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cljs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cljs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,ClojureScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cljx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cljx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cljx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CLJX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cljx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.clojure\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.clojure\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.clojure"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clojure"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Clojure}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clojure"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clojure\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clojure\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.clojure\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cls\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cls\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cls"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cls"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,LaTeX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cls"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cls\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cls\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cls\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.code-workspace\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.code-workspace\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.code-workspace"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Code Workspace}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cmake\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cmake\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cmake"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cmake"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CMake}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cmake"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cmake\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cmake\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cmake\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.coffee\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.coffee\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.coffee"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.coffee"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CoffeeScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.coffee"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.coffee\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.coffee\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.coffee\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.config\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.config\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.config"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.config"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Configuration}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.config"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.config\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.config\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.config\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.containerfile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.containerfile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.containerfile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.containerfile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Containerfile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.containerfile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.containerfile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.containerfile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cpp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cpp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cpp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cpp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cpp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cpp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cpp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cpp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C#}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\csharp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cshtml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cshtml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cshtml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cshtml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CSHTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cshtml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cshtml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cshtml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cshtml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csproj\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csproj\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.csproj"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csproj"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C# Project}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csproj"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csproj\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\xml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csproj\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csproj\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.css\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.css\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.css"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.css"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CSS}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.css"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.css\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\css.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.css\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.css\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csv\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csv\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.csv"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csv"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Comma Separated Values}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csv"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csv\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csv\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csv\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.csx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.csx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C# Script}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\csharp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.csx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ctp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ctp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ctp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ctp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,CakePHP Template}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ctp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ctp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ctp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ctp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cxx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.cxx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.cxx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cxx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cxx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cxx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cxx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.cxx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dart\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dart\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.dart"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dart"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Dart}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dart"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dart\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dart\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dart\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.diff\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.diff\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.diff"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.diff"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Diff}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.diff"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.diff\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.diff\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.diff\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dockerfile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dockerfile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.dockerfile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dockerfile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Dockerfile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dockerfile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dockerfile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dockerfile\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dockerfile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dot\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dot\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.dot"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dot"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Dot}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dot"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dot\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dot\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dot\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dtd\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.dtd\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.dtd"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dtd"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Document Type Definition}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dtd"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dtd\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\xml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dtd\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.dtd\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.editorconfig\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.editorconfig\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.editorconfig"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.editorconfig"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Editor Config}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.editorconfig"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.editorconfig\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.editorconfig\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.editorconfig\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.edn\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.edn\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.edn"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.edn"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Extensible Data Notation}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.edn"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.edn\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.edn\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.edn\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.erb\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.erb\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.erb"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.erb"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Ruby}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.erb"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.erb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\ruby.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.erb\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.erb\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.eyaml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.eyaml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.eyaml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyaml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Hiera Eyaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyaml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyaml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\yaml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyaml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyaml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.eyml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.eyml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.eyml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Hiera Eyaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\yaml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.eyml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.fs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,F#}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsi\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsi\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.fsi"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsi"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,F# Signature}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsi"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsi\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsi\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsi\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsscript\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsscript\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.fsscript"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsscript"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,F# Script}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsscript"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsscript\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsscript\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsscript\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.fsx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.fsx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,F# Script}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.fsx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gemspec\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gemspec\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.gemspec"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gemspec"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Gemspec}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gemspec"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gemspec\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\ruby.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gemspec\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gemspec\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitattributes\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitattributes\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.gitattributes"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Git Attributes}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes"; ValueType: string; ValueName: "AlwaysShowExt"; ValueData: ""; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitattributes\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitconfig\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitconfig\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.gitconfig"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Git Config}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig"; ValueType: string; ValueName: "AlwaysShowExt"; ValueData: ""; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitconfig\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitignore\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gitignore\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.gitignore"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Git Ignore}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore"; ValueType: string; ValueName: "AlwaysShowExt"; ValueData: ""; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gitignore\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.go\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.go\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.go"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.go"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Go}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.go"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.go\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\go.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.go\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.go\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gradle\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.gradle\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.gradle"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gradle"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Gradle}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gradle"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gradle\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gradle\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.gradle\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.groovy\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.groovy\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.groovy"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.groovy"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Groovy}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.groovy"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.groovy\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.groovy\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.groovy\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.h\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.h\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.h"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C Header}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\c.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.handlebars\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.handlebars\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.handlebars"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.handlebars"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Handlebars}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.handlebars"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.handlebars\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.handlebars\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.handlebars\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hbs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hbs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.hbs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hbs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Handlebars}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hbs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hbs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hbs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hbs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.h++\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.h++\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.h++"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h++"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++ Header}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h++"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h++\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.h++\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hh\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hh\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.hh"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hh"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++ Header}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hh"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hh\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hh\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hh\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hpp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hpp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.hpp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hpp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++ Header}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hpp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hpp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hpp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hpp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.htm\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.htm\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.htm"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.htm"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,HTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.htm"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.htm\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.htm\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.htm\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.html\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.html\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.html"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.html"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,HTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.html"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.html\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.html\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.html\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hxx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.hxx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.hxx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hxx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,C++ Header}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hxx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hxx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\cpp.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hxx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.hxx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ini\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ini\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ini"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ini"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,INI}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ini"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ini\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\config.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ini\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ini\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ipynb\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ipynb\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ipynb"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Jupyter}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jade\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jade\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jade"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jade"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Jade}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jade"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jade\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\jade.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jade\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jade\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jav\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jav\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jav"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jav"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Java}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jav"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jav\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\java.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jav\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jav\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.java\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.java\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.java"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.java"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Java}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.java"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.java\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\java.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.java\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.java\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.js\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.js\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.js"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.js"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JavaScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.js"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.js\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\javascript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.js\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.js\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jsx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jsx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jsx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JavaScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\react.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jscsrc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jscsrc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jscsrc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jscsrc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JSCS RC}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jscsrc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jscsrc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\javascript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jscsrc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jscsrc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jshintrc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jshintrc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jshintrc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshintrc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JSHint RC}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshintrc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshintrc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\javascript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshintrc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshintrc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jshtm\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jshtm\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jshtm"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshtm"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JavaScript HTML Template}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshtm"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshtm\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshtm\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jshtm\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.json\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.json\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.json"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.json"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JSON}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.json"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.json\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\json.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.json\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.json\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jsp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.jsp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.jsp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Java Server Pages}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.jsp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.less\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.less\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.less"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.less"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,LESS}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.less"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.less\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\less.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.less\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.less\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.log\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.log\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.log"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.log"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Log file}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.log"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.log\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.log\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.log\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.lua\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.lua\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.lua"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.lua"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Lua}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.lua"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.lua\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.lua\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.lua\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.m\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.m\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.m"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.m"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Objective C}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.m"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.m\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.m\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.m\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.makefile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.makefile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.makefile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.makefile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Makefile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.makefile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.makefile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.makefile\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.makefile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.markdown\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.markdown\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.markdown"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.markdown"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.markdown"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.markdown\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.markdown\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.markdown\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.md\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.md\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.md"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.md"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.md"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.md\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.md\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.md\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdoc\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdoc\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mdoc"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdoc"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,MDoc}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdoc"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdoc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdoc\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdoc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdown\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdown\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mdown"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdown"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdown"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdown\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdown\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdown\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdtext\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdtext\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mdtext"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtext"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtext"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtext\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtext\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtext\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdtxt\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdtxt\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mdtxt"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtxt"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtxt"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtxt\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtxt\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdtxt\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdwn\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mdwn\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mdwn"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdwn"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdwn"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdwn\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdwn\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mdwn\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mk\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mk\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mk"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mk"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Makefile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mk"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mk\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mk\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mk\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mkd\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mkd\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mkd"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkd"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkd"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkd\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkd\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkd\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mkdn\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mkdn\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mkdn"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkdn"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Markdown}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkdn"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkdn\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\markdown.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkdn\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mkdn\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,OCaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mli\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mli\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mli"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mli"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,OCaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mli"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mli\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mli\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mli\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mjs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.mjs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.mjs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mjs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,JavaScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mjs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mjs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\javascript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mjs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.mjs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.npmignore\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.npmignore\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.npmignore"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,NPM Ignore}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore"; ValueType: string; ValueName: "AlwaysShowExt"; ValueData: ""; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.npmignore\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.php\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.php\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.php"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.php"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,PHP}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.php"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.php\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\php.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.php\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.php\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.phtml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.phtml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.phtml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.phtml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,PHP HTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.phtml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.phtml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.phtml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.phtml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pl\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pl\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pl"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pl6\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pl6\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pl6"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl6"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl 6}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl6"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl6\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl6\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pl6\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.plist\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.plist\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.plist"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.plist"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Properties file}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.plist"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.plist\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.plist\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.plist\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pm\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pm\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pm"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl Module}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pm6\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pm6\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pm6"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm6"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl 6 Module}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm6"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm6\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm6\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pm6\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pod\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pod\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pod"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pod"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl POD}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pod"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pod\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pod\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pod\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pp\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pp\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pp"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pp"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pp\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pp\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pp\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.profile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.profile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.profile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.profile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Profile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.profile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.profile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.profile\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.profile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.properties\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.properties\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.properties"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.properties"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Properties}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.properties"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.properties\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.properties\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.properties\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ps1\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ps1\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ps1"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ps1"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,PowerShell}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ps1"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ps1\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\powershell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ps1\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ps1\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psd1\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psd1\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.psd1"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psd1"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,PowerShell Module Manifest}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psd1"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psd1\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\powershell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psd1\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psd1\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psgi\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psgi\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.psgi"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psgi"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl CGI}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psgi"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psgi\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psgi\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psgi\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psm1\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.psm1\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.psm1"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psm1"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,PowerShell Module}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psm1"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psm1\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\powershell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psm1\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.psm1\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.py\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.py\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.py"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.py"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Python}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.py"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.py\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\python.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.py\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.py\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pyi\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.pyi\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.pyi"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pyi"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Python}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pyi"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pyi\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\python.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pyi\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.pyi\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.r\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.r\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.r"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.r"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,R}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.r"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.r\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.r\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.r\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rb\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rb\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rb"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rb"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Ruby}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rb"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\ruby.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rb\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rb\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rhistory\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rhistory\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rhistory"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rhistory"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,R History}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rhistory"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rhistory\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rhistory\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rhistory\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rprofile\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rprofile\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rprofile"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rprofile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,R Profile}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rprofile"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rprofile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rprofile\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rprofile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Rust}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rst\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rst\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rst"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rst"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Restructured Text}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rst"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rst\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rst\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rst\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rt\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.rt\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.rt"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rt"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Rich Text}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rt"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rt\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rt\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.rt\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sass\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sass\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.sass"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sass"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Sass}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sass"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sass\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\sass.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sass\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sass\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.scss\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.scss\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.scss"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.scss"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Sass}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.scss"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.scss\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\sass.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.scss\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.scss\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sh\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sh\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.sh"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sh"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SH}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sh"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sh\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sh\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sh\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.shtml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.shtml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.shtml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.shtml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SHTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.shtml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.shtml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.shtml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.shtml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.sql\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.sql"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SQL}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\sql.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.sql\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.svg\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.svg\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.svg"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.svg"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,SVG}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.svg"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.svg\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.svg\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.svg\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.t\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.t\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.t"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.t"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Perl}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.t"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.t\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.t\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.t\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.tex\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.tex\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.tex"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tex"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,LaTeX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tex"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tex\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tex\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tex\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ts\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ts\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ts"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ts"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,TypeScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ts"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ts\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\typescript.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ts\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ts\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.toml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.toml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.toml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.toml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Toml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.toml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.toml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.toml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.toml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.tsx\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.tsx\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.tsx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tsx"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,TypeScript}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tsx"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tsx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\react.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tsx\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.tsx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.txt\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.txt\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.txt"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.txt"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Text}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.txt"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.txt\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.txt\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.txt\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.vb\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.vb\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.vb"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vb"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Visual Basic}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vb"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vb\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vb\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.vue\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.vue\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.vue"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vue"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,VUE}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vue"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vue\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\vue.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vue\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.vue\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxi\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxi\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.wxi"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxi"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,WiX Include}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxi"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxi\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxi\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxi\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxl\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxl\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.wxl"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxl"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,WiX Localization}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxl"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxl\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxl\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxl\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxs\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.wxs\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.wxs"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxs"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,WiX}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxs"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxs\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxs\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.wxs\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xaml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xaml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.xaml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xaml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,XAML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xaml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xaml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\xml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xaml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xaml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xhtml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xhtml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.xhtml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xhtml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,HTML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xhtml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xhtml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\html.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xhtml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xhtml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.xml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.xml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,XML}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\xml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.xml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.yaml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.yaml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.yaml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yaml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Yaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yaml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yaml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\yaml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yaml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yaml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.yml\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.yml\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.yml"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yml"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Yaml}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yml"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yml\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\yaml.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yml\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.yml\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.zsh\OpenWithProgids"; ValueType: none; ValueName: "{#RegValueName}"; Flags: deletevalue uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.zsh\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.zsh"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.zsh"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,ZSH}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.zsh"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.zsh\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\shell.ico"; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.zsh\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.zsh\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,{#NameLong}}"; Flags: uninsdeletekey Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile\shell\open"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe""" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}SourceFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1""" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe"; ValueType: none; ValueName: ""; Flags: uninsdeletekey Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe""" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1""" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}ContextMenu"; ValueType: expandsz; ValueName: "Title"; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey; Check: IsWindows11OrLater and QualityIsInsiders Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufiles; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: addcontextmenufiles; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders; Check: not (IsWindows11OrLater and QualityIsInsiders) ; Environment #if "user" == InstallTarget #define EnvironmentRootKey "HKCU" #define EnvironmentKey "Environment" #define Uninstall64RootKey "HKCU64" #define Uninstall32RootKey "HKCU32" #else #define EnvironmentRootKey "HKLM" #define EnvironmentKey "System\CurrentControlSet\Control\Session Manager\Environment" #define Uninstall64RootKey "HKLM64" #define Uninstall32RootKey "HKLM32" #endif Root: {#EnvironmentRootKey}; Subkey: "{#EnvironmentKey}"; ValueType: expandsz; ValueName: "Path"; ValueData: "{code:AddToPath|{app}\bin}"; Tasks: addtopath; Check: NeedsAddToPath(ExpandConstant('{app}\bin')) [Code] function IsBackgroundUpdate(): Boolean; begin Result := ExpandConstant('{param:update|false}') <> 'false'; end; function IsNotBackgroundUpdate(): Boolean; begin Result := not IsBackgroundUpdate(); end; // Don't allow installing conflicting architectures function InitializeSetup(): Boolean; var RegKey: String; ThisArch: String; AltArch: String; begin Result := True; #if "user" == InstallTarget if not WizardSilent() and IsAdmin() then begin if MsgBox('This User Installer is not meant to be run as an Administrator. If you would like to install VS Code for all users in this system, download the System Installer instead from https://code.visualstudio.com. Are you sure you want to continue?', mbError, MB_OKCANCEL) = IDCANCEL then begin Result := False; end; end; #endif #if "user" == InstallTarget #if "arm64" == Arch #define IncompatibleArchRootKey "HKLM32" #else #define IncompatibleArchRootKey "HKLM64" #endif if Result and not WizardSilent() then begin RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + copy('{#IncompatibleTargetAppId}', 2, 38) + '_is1'; if RegKeyExists({#IncompatibleArchRootKey}, RegKey) then begin if MsgBox('{#NameShort} is already installed on this system for all users. We recommend first uninstalling that version before installing this one. Are you sure you want to continue the installation?', mbConfirmation, MB_YESNO) = IDNO then begin Result := False; end; end; end; #endif end; function WizardNotSilent(): Boolean; begin Result := not WizardSilent(); end; // Updates var ShouldRestartTunnelService: Boolean; function StopTunnelOtherProcesses(): Boolean; var WaitCounter: Integer; TaskKilled: Integer; begin Log('Stopping all tunnel services (at ' + ExpandConstant('"{app}\bin\{#TunnelApplicationName}.exe"') + ')'); ShellExec('', 'powershell.exe', '-Command "Get-WmiObject Win32_Process | Where-Object { $_.ExecutablePath -eq ' + ExpandConstant('''{app}\bin\{#TunnelApplicationName}.exe''') + ' } | Select @{Name=''Id''; Expression={$_.ProcessId}} | Stop-Process -Force"', '', SW_HIDE, ewWaitUntilTerminated, TaskKilled) WaitCounter := 10; while (WaitCounter > 0) and CheckForMutexes('{#TunnelMutex}') do begin Log('Tunnel process is is still running, waiting'); Sleep(500); WaitCounter := WaitCounter - 1 end; if CheckForMutexes('{#TunnelMutex}') then begin Log('Unable to stop tunnel processes'); Result := False; end else Result := True; end; procedure StopTunnelServiceIfNeeded(); var StopServiceResultCode: Integer; WaitCounter: Integer; begin ShouldRestartTunnelService := False; if CheckForMutexes('{#TunnelServiceMutex}') then begin // stop the tunnel service Log('Stopping the tunnel service using ' + ExpandConstant('"{app}\bin\{#ApplicationName}.cmd"')); ShellExec('', ExpandConstant('"{app}\bin\{#ApplicationName}.cmd"'), 'tunnel service uninstall', '', SW_HIDE, ewWaitUntilTerminated, StopServiceResultCode); Log('Stopping the tunnel service completed with result code ' + IntToStr(StopServiceResultCode)); WaitCounter := 10; while (WaitCounter > 0) and CheckForMutexes('{#TunnelServiceMutex}') do begin Log('Tunnel service is still running, waiting'); Sleep(500); WaitCounter := WaitCounter - 1 end; if CheckForMutexes('{#TunnelServiceMutex}') then Log('Unable to stop tunnel service') else ShouldRestartTunnelService := True; end end; // called before the wizard checks for running application function PrepareToInstall(var NeedsRestart: Boolean): String; begin if IsNotBackgroundUpdate() then StopTunnelServiceIfNeeded(); if IsNotBackgroundUpdate() and not StopTunnelOtherProcesses() then Result := '{#NameShort} is still running a tunnel process. Please stop the tunnel before installing.' else Result := ''; end; // VS Code will create a flag file before the update starts (/update=C:\foo\bar) // - if the file exists at this point, the user quit Code before the update finished, so don't start Code after update // - otherwise, the user has accepted to apply the update and Code should start function LockFileExists(): Boolean; begin Result := FileExists(ExpandConstant('{param:update}')) end; function ShouldRunAfterUpdate(): Boolean; begin if IsBackgroundUpdate() then Result := not LockFileExists() else Result := True; end; function IsWindows11OrLater(): Boolean; begin Result := (GetWindowsVersion >= $0A0055F0); end; function GetAppMutex(Value: string): string; begin if IsBackgroundUpdate() then Result := '' else Result := '{#AppMutex}'; end; function GetDestDir(Value: string): string; begin if IsBackgroundUpdate() then Result := ExpandConstant('{app}\_') else Result := ExpandConstant('{app}'); end; function BoolToStr(Value: Boolean): String; begin if Value then Result := 'true' else Result := 'false'; end; function QualityIsInsiders(): boolean; begin if '{#Quality}' = 'insider' then Result := True else Result := False; end; #ifdef AppxPackageFullname procedure AddAppxPackage(); var AddAppxPackageResultCode: Integer; begin if WizardIsTaskSelected('addcontextmenufiles') then begin ShellExec('', 'powershell.exe', '-Command ' + AddQuotes('Add-AppxPackage -Path ''' + ExpandConstant('{app}\appx\{#AppxPackage}') + ''' -ExternalLocation ''' + ExpandConstant('{app}\appx') + ''''), '', SW_HIDE, ewWaitUntilTerminated, AddAppxPackageResultCode); RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\*\shell\{#RegValueName}'); RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\shell\{#RegValueName}'); RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\directory\background\shell\{#RegValueName}'); RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\Drive\shell\{#RegValueName}'); end; end; procedure RemoveAppxPackage(); var RemoveAppxPackageResultCode: Integer; begin ShellExec('', 'powershell.exe', '-Command ' + AddQuotes('Remove-AppxPackage -Package ''{#AppxPackageFullname}'''), '', SW_HIDE, ewWaitUntilTerminated, RemoveAppxPackageResultCode); if not WizardIsTaskSelected('addcontextmenufiles') then begin RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\{#RegValueName}ContextMenu'); end; end; #endif procedure CurStepChanged(CurStep: TSetupStep); var UpdateResultCode: Integer; StartServiceResultCode: Integer; begin if CurStep = ssPostInstall then begin if IsBackgroundUpdate() then begin CreateMutex('{#AppMutex}-ready'); Log('Checking whether application is still running...'); while (CheckForMutexes('{#AppMutex}')) do begin Sleep(1000) end; Log('Application appears not to be running.'); StopTunnelServiceIfNeeded(); Exec(ExpandConstant('{app}\tools\inno_updater.exe'), ExpandConstant('"{app}\{#ExeBasename}.exe" ' + BoolToStr(LockFileExists()) + ' "{cm:UpdatingVisualStudioCode}"'), '', SW_SHOW, ewWaitUntilTerminated, UpdateResultCode); end; if ShouldRestartTunnelService then begin // start the tunnel service Log('Restarting the tunnel service...'); ShellExec('', ExpandConstant('"{app}\bin\{#ApplicationName}.cmd"'), 'tunnel service install', '', SW_HIDE, ewWaitUntilTerminated, StartServiceResultCode); Log('Starting the tunnel service completed with result code ' + IntToStr(StartServiceResultCode)); ShouldRestartTunnelService := False end; end; end; // https://stackoverflow.com/a/23838239/261019 procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); var i, p: Integer; begin i := 0; repeat SetArrayLength(Dest, i+1); p := Pos(Separator,Text); if p > 0 then begin Dest[i] := Copy(Text, 1, p-1); Text := Copy(Text, p + Length(Separator), Length(Text)); i := i + 1; end else begin Dest[i] := Text; Text := ''; end; until Length(Text)=0; end; function NeedsAddToPath(VSCode: string): boolean; var OrigPath: string; begin if not RegQueryStringValue({#EnvironmentRootKey}, '{#EnvironmentKey}', 'Path', OrigPath) then begin Result := True; exit; end; Result := Pos(';' + VSCode + ';', ';' + OrigPath + ';') = 0; end; function AddToPath(VSCode: string): string; var OrigPath: string; begin RegQueryStringValue({#EnvironmentRootKey}, '{#EnvironmentKey}', 'Path', OrigPath) if (Length(OrigPath) > 0) and (OrigPath[Length(OrigPath)] = ';') then Result := OrigPath + VSCode else Result := OrigPath + ';' + VSCode end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var Path: string; VSCodePath: string; Parts: TArrayOfString; NewPath: string; i: Integer; begin if not CurUninstallStep = usUninstall then begin exit; end; if not RegQueryStringValue({#EnvironmentRootKey}, '{#EnvironmentKey}', 'Path', Path) then begin exit; end; NewPath := ''; VSCodePath := ExpandConstant('{app}\bin') Explode(Parts, Path, ';'); for i:=0 to GetArrayLength(Parts)-1 do begin if CompareText(Parts[i], VSCodePath) <> 0 then begin NewPath := NewPath + Parts[i]; if i < GetArrayLength(Parts) - 1 then begin NewPath := NewPath + ';'; end; end; end; RegWriteExpandStringValue({#EnvironmentRootKey}, '{#EnvironmentKey}', 'Path', NewPath); end; #ifdef Debug #expr SaveToFile(AddBackslash(SourcePath) + "code-processed.iss") #endif // https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/icacls // https://docs.microsoft.com/en-US/windows/security/identity-protection/access-control/security-identifiers procedure DisableAppDirInheritance(); var ResultCode: Integer; Permissions: string; begin Permissions := '/grant:r "*S-1-5-18:(OI)(CI)F" /grant:r "*S-1-5-32-544:(OI)(CI)F" /grant:r "*S-1-5-11:(OI)(CI)RX" /grant:r "*S-1-5-32-545:(OI)(CI)RX"'; #if "user" == InstallTarget Permissions := Permissions + Format(' /grant:r "*S-1-3-0:(OI)(CI)F" /grant:r "%s:(OI)(CI)F"', [GetUserNameString()]); #endif Exec(ExpandConstant('{sys}\icacls.exe'), ExpandConstant('"{app}" /inheritancelevel:r ') + Permissions, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); end; ================================================ FILE: build/win32/explorer-appx-fetcher.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.downloadExplorerAppx = downloadExplorerAppx; const fs_1 = __importDefault(require("fs")); const debug_1 = __importDefault(require("debug")); const extract_zip_1 = __importDefault(require("extract-zip")); const path_1 = __importDefault(require("path")); const get_1 = require("@electron/get"); const root = path_1.default.dirname(path_1.default.dirname(__dirname)); const d = (0, debug_1.default)('explorer-appx-fetcher'); async function downloadExplorerAppx(outDir, quality = 'stable', targetArch = 'x64') { const fileNamePrefix = quality === 'insider' ? 'code_insiders' : 'code'; const fileName = `${fileNamePrefix}_explorer_${targetArch}.zip`; if (await fs_1.default.existsSync(path_1.default.resolve(outDir, 'resources.pri'))) { return; } if (!await fs_1.default.existsSync(outDir)) { await fs_1.default.mkdirSync(outDir, { recursive: true }); } d(`downloading ${fileName}`); const artifact = await (0, get_1.downloadArtifact)({ isGeneric: true, version: '3.0.4', artifactName: fileName, unsafelyDisableChecksums: true, mirrorOptions: { mirror: 'https://github.com/microsoft/vscode-explorer-command/releases/download/', customDir: '3.0.4', customFilename: fileName } }); d(`unpacking from ${fileName}`); await (0, extract_zip_1.default)(artifact, { dir: fs_1.default.realpathSync(outDir) }); } async function main(outputDir) { const arch = process.env['VSCODE_ARCH']; if (!outputDir) { throw new Error('Required build env not set'); } const product = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'product.json'), 'utf8')); await downloadExplorerAppx(outputDir, product.quality, arch); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } //# sourceMappingURL=explorer-appx-fetcher.js.map ================================================ FILE: build/win32/explorer-appx-fetcher.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import fs from 'fs'; import debug from 'debug'; import extract from 'extract-zip'; import path from 'path'; import { downloadArtifact } from '@electron/get'; const root = path.dirname(path.dirname(__dirname)); const d = debug('explorer-appx-fetcher'); export async function downloadExplorerAppx(outDir: string, quality: string = 'stable', targetArch: string = 'x64'): Promise { const fileNamePrefix = quality === 'insider' ? 'code_insiders' : 'code'; const fileName = `${fileNamePrefix}_explorer_${targetArch}.zip`; if (await fs.existsSync(path.resolve(outDir, 'resources.pri'))) { return; } if (!await fs.existsSync(outDir)) { await fs.mkdirSync(outDir, { recursive: true }); } d(`downloading ${fileName}`); const artifact = await downloadArtifact({ isGeneric: true, version: '3.0.4', artifactName: fileName, unsafelyDisableChecksums: true, mirrorOptions: { mirror: 'https://github.com/microsoft/vscode-explorer-command/releases/download/', customDir: '3.0.4', customFilename: fileName } }); d(`unpacking from ${fileName}`); await extract(artifact, { dir: fs.realpathSync(outDir) }); } async function main(outputDir?: string): Promise { const arch = process.env['VSCODE_ARCH']; if (!outputDir) { throw new Error('Required build env not set'); } const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8')); await downloadExplorerAppx(outputDir, (product as any).quality, arch); } if (require.main === module) { main(process.argv[2]).catch(err => { console.error(err); process.exit(1); }); } ================================================ FILE: build/win32/i18n/Default.hu.isl ================================================ ;Inno Setup version 6.0.3+ Hungarian messages ;Based on the translation of Kornl Pl, kornelpal@gmail.com ;Istvn Szab, E-mail: istvanszabo890629@gmail.com ; ; To download user-contributed translations of this file, go to: ; http://www.jrsoftware.org/files/istrans/ ; ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno ; Setup adds the periods automatically (appending a period would result in ; two periods being displayed). [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. LanguageName=Magyar LanguageID=$040E LanguageCodePage=1250 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial CE ;TitleFontSize=29 ;CopyrightFontName=Arial CE ;CopyrightFontSize=8 [Messages] ; *** Application titles SetupAppTitle=Telept SetupWindowTitle=%1 - Telept UninstallAppTitle=Eltvolt UninstallAppFullTitle=%1 Eltvolt ; *** Misc. common InformationTitle=Informcik ConfirmTitle=Megerst ErrorTitle=Hiba ; *** SetupLdr messages SetupLdrStartupMessage=%1 teleptve lesz. Szeretn folytatni? LdrCannotCreateTemp=tmeneti fjl ltrehozsa nem lehetsges. A telepts megszaktva LdrCannotExecTemp=Fjl futtatsa nem lehetsges az tmeneti knyvtrban. A telepts megszaktva HelpTextNote= ; *** Startup error messages LastErrorMessage=%1.%n%nHiba %2: %3 SetupFileMissing=A(z) %1 fjl hinyzik a telept knyvtrbl. Krem hrtsa el a problmt, vagy szerezzen be egy msik pldnyt a programbl! SetupFileCorrupt=A teleptsi fjlok srltek. Krem, szerezzen be j msolatot a programbl! SetupFileCorruptOrWrongVer=A teleptsi fjlok srltek, vagy inkompatibilisek a telept ezen verzijval. Hrtsa el a problmt, vagy szerezzen be egy msik pldnyt a programbl! InvalidParameter=A parancssorba tadott paramter rvnytelen:%n%n%1 SetupAlreadyRunning=A Telept mr fut. WindowsVersionNotSupported=A program nem tmogatja a Windows ezen verzijt. WindowsServicePackRequired=A program futtatshoz %1 Service Pack %2 vagy jabb szksges. NotOnThisPlatform=Ez a program nem futtathat %1 alatt. OnlyOnThisPlatform=Ezt a programot %1 alatt kell futtatni. OnlyOnTheseArchitectures=A program kizrlag a kvetkez processzor architektrkhoz tervezett Windows-on telepthet:%n%n%1 WinVersionTooLowError=A program futtatshoz %1 %2 verzija vagy ksbbi szksges. WinVersionTooHighError=Ez a program nem telepthet %1 %2 vagy ksbbire. AdminPrivilegesRequired=Csak rendszergazdai mdban telepthet ez a program. PowerUserPrivilegesRequired=Csak rendszergazdaknt vagy kiemelt felhasznlknt telepthet ez a program. SetupAppRunningError=A telept gy szlelte %1 jelenleg fut.%n%nZrja be az sszes pldnyt, majd kattintson az 'OK'-ra a folytatshoz, vagy a 'Mgse'-re a kilpshez. UninstallAppRunningError=Az eltvolt gy szlelte %1 jelenleg fut.%n%nZrja be az sszes pldnyt, majd kattintson az 'OK'-ra a folytatshoz, vagy a 'Mgse'-re a kilpshez. ; *** Startup questions PrivilegesRequiredOverrideTitle=Teleptsi md kivlasztsa PrivilegesRequiredOverrideInstruction=Vlasszon teleptsi mdot PrivilegesRequiredOverrideText1=%1 telepthet az sszes felhasznlnak (rendszergazdai jogok szksgesek), vagy csak magnak. PrivilegesRequiredOverrideText2=%1 csak magnak telepthet, vagy az sszes felhasznlnak (rendszergazdai jogok szksgesek). PrivilegesRequiredOverrideAllUsers=Telepts &mindenkinek PrivilegesRequiredOverrideAllUsersRecommended=Telepts &mindenkinek (ajnlott) PrivilegesRequiredOverrideCurrentUser=Telepts csak &nekem PrivilegesRequiredOverrideCurrentUserRecommended=Telepts csak &nekem (ajnlott) ; *** Misc. errors ErrorCreatingDir=A Telept nem tudta ltrehozni a(z) "%1" knyvtrat ErrorTooManyFilesInDir=Nem hozhat ltre fjl a(z) "%1" knyvtrban, mert az mr tl sok fjlt tartalmaz ; *** Setup common messages ExitSetupTitle=Kilps a teleptbl ExitSetupMessage=A telepts mg folyamatban van. Ha most kilp, a program nem kerl teleptsre.%n%nMsik alkalommal is futtathat a telepts befejezshez%n%nKilp a teleptbl? AboutSetupMenuItem=&Nvjegy... AboutSetupTitle=Telept nvjegye AboutSetupMessage=%1 %2 verzi%n%3%n%nAz %1 honlapja:%n%4 AboutSetupNote= TranslatorNote= ; *** Buttons ButtonBack=< &Vissza ButtonNext=&Tovbb > ButtonInstall=&Telept ButtonOK=OK ButtonCancel=Mgse ButtonYes=&Igen ButtonYesToAll=&Mindet ButtonNo=&Nem ButtonNoToAll=&Egyiket se ButtonFinish=&Befejezs ButtonBrowse=&Tallzs... ButtonWizardBrowse=T&allzs... ButtonNewFolder=j &knyvtr ; *** "Select Language" dialog messages SelectLanguageTitle=Telept nyelvi bellts SelectLanguageLabel=Vlassza ki a telepts alatt hasznlt nyelvet. ; *** Common wizard text ClickNext=A folytatshoz kattintson a 'Tovbb'-ra, a kilpshez a 'Mgse'-re. BeveledLabel= BrowseDialogTitle=Vlasszon knyvtrt BrowseDialogLabel=Vlasszon egy knyvtrat az albbi listbl, majd kattintson az 'OK'-ra. NewFolderName=j knyvtr ; *** "Welcome" wizard page WelcomeLabel1=dvzli a(z) [name] Teleptvarzslja. WelcomeLabel2=A(z) [name/ver] teleptsre kerl a szmtgpn.%n%nAjnlott minden, egyb fut alkalmazs bezrsa a folytats eltt. ; *** "Password" wizard page WizardPassword=Jelsz PasswordLabel1=Ez a telepts jelszval vdett. PasswordLabel3=Krem adja meg a jelszt, majd kattintson a 'Tovbb'-ra. A jelszavak kis- s nagy bet rzkenyek lehetnek. PasswordEditLabel=&Jelsz: IncorrectPassword=Az n ltal megadott jelsz helytelen. Prblja jra. ; *** "License Agreement" wizard page WizardLicense=Licencszerzds LicenseLabel=Olvassa el figyelmesen az informcikat folytats eltt. LicenseLabel3=Krem, olvassa el az albbi licencszerzdst. A telepts folytatshoz, el kell fogadnia a szerzdst. LicenseAccepted=&Elfogadom a szerzdst LicenseNotAccepted=&Nem fogadom el a szerzdst ; *** "Information" wizard pages WizardInfoBefore=Informcik InfoBeforeLabel=Olvassa el a kvetkez fontos informcikat a folytats eltt. InfoBeforeClickLabel=Ha kszen ll, kattintson a 'Tovbb'-ra. WizardInfoAfter=Informcik InfoAfterLabel=Olvassa el a kvetkez fontos informcikat a folytats eltt. InfoAfterClickLabel=Ha kszen ll, kattintson a 'Tovbb'-ra. ; *** "User Information" wizard page WizardUserInfo=Felhasznl adatai UserInfoDesc=Krem, adja meg az adatait UserInfoName=&Felhasznlnv: UserInfoOrg=&Szervezet: UserInfoSerial=&Sorozatszm: UserInfoNameRequired=Meg kell adnia egy nevet. ; *** "Select Destination Location" wizard page WizardSelectDir=Vlasszon clknyvtrat SelectDirDesc=Hova telepljn a(z) [name]? SelectDirLabel3=A(z) [name] az albbi knyvtrba lesz teleptve. SelectDirBrowseLabel=A folytatshoz, kattintson a 'Tovbb'-ra. Ha msik knyvtrat vlasztana, kattintson a 'Tallzs'-ra. DiskSpaceGBLabel=At least [gb] GB szabad terletre van szksg. DiskSpaceMBLabel=Legalbb [mb] MB szabad terletre van szksg. CannotInstallToNetworkDrive=A Telept nem tud hlzati meghajtra telepteni. CannotInstallToUNCPath=A Telept nem tud hlzati UNC elrsi tra telepteni. InvalidPath=Teljes tvonalat adjon meg, a meghajt betjelvel; pldul:%n%nC:\Alkalmazs%n%nvagy egy hlzati tvonalat a kvetkez alakban:%n%n\\kiszolgl\megoszts InvalidDrive=A kivlasztott meghajt vagy hlzati megoszts nem ltezik vagy nem elrhet. Vlasszon egy msikat. DiskSpaceWarningTitle=Nincs elg szabad terlet DiskSpaceWarning=A Teleptnek legalbb %1 KB szabad lemezterletre van szksge, viszont a kivlasztott meghajtn csupn %2 KB ll rendelkezsre.%n%nMindenkppen folytatja? DirNameTooLong=A knyvtr neve vagy az tvonal tl hossz. InvalidDirName=A knyvtr neve rvnytelen. BadDirName32=A knyvtrak nevei ezen karakterek egyikt sem tartalmazhatjk:%n%n%1 DirExistsTitle=A knyvtr mr ltezik DirExists=A knyvtr:%n%n%1%n%nmr ltezik. Mindenkpp ide akar telepteni? DirDoesntExistTitle=A knyvtr nem ltezik DirDoesntExist=A knyvtr:%n%n%1%n%nnem ltezik. Szeretn ltrehozni? ; *** "Select Components" wizard page WizardSelectComponents=sszetevk kivlasztsa SelectComponentsDesc=Mely sszetevk kerljenek teleptsre? SelectComponentsLabel2=Jellje ki a teleptend sszetevket; trlje a telepteni nem kvnt sszetevket. Kattintson a 'Tovbb'-ra, ha kszen ll a folytatsra. FullInstallation=Teljes telepts ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=Szoksos telepts CustomInstallation=Egyni telepts NoUninstallWarningTitle=Ltez sszetev NoUninstallWarning=A telept gy tallta, hogy a kvetkez sszetevk mr teleptve vannak a szmtgpre:%n%n%1%n%nEzen sszetevk kijellsnek trlse, nem tvoltja el azokat a szmtgprl.%n%nMindenkppen folytatja? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceMBLabel=A jelenlegi kijells legalbb [gb] GB lemezterletet ignyel. ComponentsDiskSpaceMBLabel=A jelenlegi kijells legalbb [mb] MB lemezterletet ignyel. ; *** "Select Additional Tasks" wizard page WizardSelectTasks=Tovbbi feladatok SelectTasksDesc=Mely kiegszt feladatok kerljenek vgrehajtsra? SelectTasksLabel2=Jellje ki, mely kiegszt feladatokat hajtsa vgre a Telept a(z) [name] teleptse sorn, majd kattintson a 'Tovbb'-ra. ; *** "Select Start Menu Folder" wizard page WizardSelectProgramGroup=Start Men knyvtra SelectStartMenuFolderDesc=Hova helyezze a Telept a program parancsikonjait? SelectStartMenuFolderLabel3=A Telept a program parancsikonjait a Start men kvetkez mappjban fogja ltrehozni. SelectStartMenuFolderBrowseLabel=A folytatshoz kattintson a 'Tovbb'-ra. Ha msik mappt vlasztana, kattintson a 'Tallzs'-ra. MustEnterGroupName=Meg kell adnia egy mappanevet. GroupNameTooLong=A knyvtr neve vagy az tvonal tl hossz. InvalidGroupName=A knyvtr neve rvnytelen. BadGroupName=A knyvtrak nevei ezen karakterek egyikt sem tartalmazhatjk:%n%n%1 NoProgramGroupCheck2=&Ne hozzon ltre mappt a Start menben ; *** "Ready to Install" wizard page WizardReady=Kszen llunk a teleptsre ReadyLabel1=A Telept kszen ll, a(z) [name] szmtgpre teleptshez. ReadyLabel2a=Kattintson a 'Telepts'-re a folytatshoz, vagy a "Vissza"-ra a belltsok ttekintshez vagy megvltoztatshoz. ReadyLabel2b=Kattintson a 'Telepts'-re a folytatshoz. ReadyMemoUserInfo=Felhasznl adatai: ReadyMemoDir=Telepts clknyvtra: ReadyMemoType=Telepts tpusa: ReadyMemoComponents=Vlasztott sszetevk: ReadyMemoGroup=Start men mappja: ReadyMemoTasks=Kiegszt feladatok: ; *** "Preparing to Install" wizard page WizardPreparing=Felkszls a teleptsre PreparingDesc=A Telept felkszl a(z) [name] szmtgpre trtn teleptshez. PreviousInstallNotCompleted=gy korbbi program teleptse/eltvoltsa nem fejezdtt be. jra kell indtania a szmtgpt a msik telepts befejezshez.%n%nA szmtgpe jraindtsa utn ismt futtassa a Teleptt a(z) [name] teleptsnek befejezshez. CannotContinue=A telepts nem folytathat. A kilpshez kattintson a 'Mgse'-re ApplicationsFound=A kvetkez alkalmazsok olyan fjlokat hasznlnak, amelyeket a Teleptnek frissteni kell. Ajnlott, hogy engedlyezze a Teleptnek ezen alkalmazsok automatikus bezrst. ApplicationsFound2=A kvetkez alkalmazsok olyan fjlokat hasznlnak, amelyeket a Teleptnek frissteni kell. Ajnlott, hogy engedlyezze a Teleptnek ezen alkalmazsok automatikus bezrst. A telepts befejezse utn a Telept megksrli az alkalmazsok jraindtst. CloseApplications=&Alkalmazsok automatikus bezrsa DontCloseApplications=&Ne zrja be az alkalmazsokat ErrorCloseApplications=A Telept nem tudott minden alkalmazst automatikusan bezrni. A folytats eltt ajnlott minden, a Telept ltal frisstend fjlokat hasznl alkalmazst bezrni. PrepareToInstallNeedsRestart=A teleptnek jra kell indtania a szmtgpet. jraindtst kveten, futtassa jbl a teleptt, a [name] teleptsnek befejezshez .%n%njra szeretn indtani most a szmtgpet? ; *** "Installing" wizard page WizardInstalling=Telepts InstallingLabel=Krem vrjon, amg a(z) [name] teleptse zajlik. ; *** "Setup Completed" wizard page FinishedHeadingLabel=A(z) [name] teleptsnek befejezse FinishedLabelNoIcons=A Telept vgzett a(z) [name] teleptsvel. FinishedLabel=A Telept vgzett a(z) [name] teleptsvel. Az alkalmazst a ltrehozott ikonok kivlasztsval indthatja. ClickFinish=Kattintson a 'Befejezs'-re a kilpshez. FinishedRestartLabel=A(z) [name] teleptsnek befejezshez jra kell indtani a szmtgpet. jraindtja most? FinishedRestartMessage=A(z) [name] teleptsnek befejezshez, a Teleptnek jra kell indtani a szmtgpet.%n%njraindtja most? ShowReadmeCheck=Igen, szeretnm elolvasni a FONTOS fjlt YesRadio=&Igen, jraindts most NoRadio=&Nem, ksbb indtom jra ; used for example as 'Run MyProg.exe' RunEntryExec=%1 futtatsa ; used for example as 'View Readme.txt' RunEntryShellExec=%1 megtekintse ; *** "Setup Needs the Next Disk" stuff ChangeDiskTitle=A Teleptnek szksge van a kvetkez lemezre SelectDiskLabel2=Helyezze be a(z) %1. lemezt s kattintson az 'OK'-ra.%n%nHa a fjlok a lemez egy a megjelentettl klnbz mappjban tallhatk, rja be a helyes tvonalat vagy kattintson a 'Tallzs'-ra. PathLabel=&tvonal: FileNotInDir2=A(z) "%1" fjl nem tallhat a kvetkez helyen: "%2". Helyezze be a megfelel lemezt vagy vlasszon egy msik mappt. SelectDirectoryLabel=Adja meg a kvetkez lemez helyt. ; *** Installation phase messages SetupAborted=A telepts nem fejezdtt be.%n%nHrtsa el a hibt s futtassa jbl a Teleptt. AbortRetryIgnoreSelectAction=Vlasszon mveletet AbortRetryIgnoreRetry=&jra AbortRetryIgnoreIgnore=&Hiba elvetse s folytats AbortRetryIgnoreCancel=Telepts megszaktsa ; *** Installation status messages StatusClosingApplications=Alkalmazsok bezrsa... StatusCreateDirs=Knyvtrak ltrehozsa... StatusExtractFiles=Fjlok kibontsa... StatusCreateIcons=Parancsikonok ltrehozsa... StatusCreateIniEntries=INI bejegyzsek ltrehozsa... StatusCreateRegistryEntries=Rendszerler bejegyzsek ltrehozsa... StatusRegisterFiles=Fjlok regisztrlsa... StatusSavingUninstall=Eltvolt informcik mentse... StatusRunProgram=Telepts befejezse... StatusRestartingApplications=Alkalmazsok jraindtsa... StatusRollback=Vltoztatsok visszavonsa... ; *** Misc. errors ErrorInternal2=Bels hiba: %1 ErrorFunctionFailedNoCode=Sikertelen %1 ErrorFunctionFailed=Sikertelen %1; kd: %2 ErrorFunctionFailedWithMessage=Sikertelen %1; kd: %2.%n%3 ErrorExecutingProgram=Nem hajthat vgre a fjl:%n%1 ; *** Registry errors ErrorRegOpenKey=Nem nyithat meg a rendszerler kulcs:%n%1\%2 ErrorRegCreateKey=Nem hozhat ltre a rendszerler kulcs:%n%1\%2 ErrorRegWriteKey=Nem mdosthat a rendszerler kulcs:%n%1\%2 ; *** INI errors ErrorIniEntry=Bejegyzs ltrehozsa sikertelen a kvetkez INI fjlban: "%1". ; *** File copying errors FileAbortRetryIgnoreSkipNotRecommended=&Fjl kihagysa (nem ajnlott) FileAbortRetryIgnoreIgnoreNotRecommended=&Hiba elvetse s folytats (nem ajnlott) SourceIsCorrupted=A forrsfjl megsrlt SourceDoesntExist=A(z) "%1" forrsfjl nem ltezik ExistingFileReadOnly2=A fjl csak olvashatknt van jellve. ExistingFileReadOnlyRetry=Csak &olvashat tulajdonsg eltvoltsa s jra prblkozs ExistingFileReadOnlyKeepExisting=&Ltez fjl megtartsa ErrorReadingExistingDest=Hiba lpett fel a fjl olvassa kzben: FileExists=A fjl mr ltezik.%n%nFell kvnja rni? ExistingFileNewer=A ltez fjl jabb a teleptsre kerlnl. Ajnlott a ltez fjl megtartsa.%n%nMeg kvnja tartani a ltez fjlt? ErrorChangingAttr=Hiba lpett fel a fjl attribtumnak mdostsa kzben: ErrorCreatingTemp=Hiba lpett fel a fjl teleptsi knyvtrban trtn ltrehozsa kzben: ErrorReadingSource=Hiba lpett fel a forrsfjl olvassa kzben: ErrorCopying=Hiba lpett fel a fjl msolsa kzben: ErrorReplacingExistingFile=Hiba lpett fel a ltez fjl cserje kzben: ErrorRestartReplace=A fjl cserje az jraindts utn sikertelen volt: ErrorRenamingTemp=Hiba lpett fel fjl teleptsi knyvtrban trtn tnevezse kzben: ErrorRegisterServer=Nem lehet regisztrlni a DLL-t/OCX-et: %1 ErrorRegSvr32Failed=Sikertelen RegSvr32. A visszaadott kd: %1 ErrorRegisterTypeLib=Nem lehet regisztrlni a tpustrat: %1 ; *** Uninstall display name markings ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32-bit UninstallDisplayNameMark64Bit=64-bit UninstallDisplayNameMarkAllUsers=Minden felhasznl UninstallDisplayNameMarkCurrentUser=Jelenlegi felhasznl ; *** Post-installation errors ErrorOpeningReadme=Hiba lpett fel a FONTOS fjl megnyitsa kzben. ErrorRestartingComputer=A Telept nem tudta jraindtani a szmtgpet. Indtsa jra kzileg. ; *** Uninstaller messages UninstallNotFound=A(z) "%1" fjl nem ltezik. Nem tvolthat el. UninstallOpenError=A(z) "%1" fjl nem nyithat meg. Nem tvolthat el. UninstallUnsupportedVer=A(z) "%1" eltvoltsi naplfjl formtumt nem tudja felismerni az eltvolt jelen verzija. Az eltvolts nem folytathat UninstallUnknownEntry=Egy ismeretlen bejegyzs (%1) tallhat az eltvoltsi naplfjlban ConfirmUninstall=Biztosan el kvnja tvoltani a(z) %1 programot s minden sszetevjt? UninstallOnlyOnWin64=Ezt a teleptst csak 64-bites Windowson lehet eltvoltani. OnlyAdminCanUninstall=Ezt a teleptst csak adminisztrcis jogokkal rendelkez felhasznl tvolthatja el. UninstallStatusLabel=Legyen trelemmel, amg a(z) %1 szmtgprl trtn eltvoltsa befejezdik. UninstalledAll=A(z) %1 sikeresen el lett tvoltva a szmtgprl. UninstalledMost=A(z) %1 eltvoltsa befejezdtt.%n%nNhny elemet nem lehetett eltvoltani. Trlje kzileg. UninstalledAndNeedsRestart=A(z) %1 eltvoltsnak befejezshez jra kell indtania a szmtgpt.%n%njraindtja most? UninstallDataCorrupted=A(z) "%1" fjl srlt. Nem tvolthat el. ; *** Uninstallation phase messages ConfirmDeleteSharedFileTitle=Trli a megosztott fjlt? ConfirmDeleteSharedFile2=A rendszer azt jelzi, hogy a kvetkez megosztott fjlra mr nincs szksge egyetlen programnak sem. Eltvoltja a megosztott fjlt?%n%nHa ms programok mg mindig hasznljk a megosztott fjlt, akkor az eltvoltsa utn lehet, hogy nem fognak megfelelen mkdni. Ha bizonytalan, vlassza a Nemet. A fjl megtartsa nem okoz problmt a rendszerben. SharedFileNameLabel=Fjlnv: SharedFileLocationLabel=Helye: WizardUninstalling=Eltvolts llapota StatusUninstalling=%1 eltvoltsa... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=%1 teleptse. ShutdownBlockReasonUninstallingApp=%1 eltvoltsa. ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1, verzi: %2 AdditionalIcons=Tovbbi parancsikonok: CreateDesktopIcon=&Asztali ikon ltrehozsa CreateQuickLaunchIcon=&Gyorsindt parancsikon ltrehozsa ProgramOnTheWeb=%1 az interneten UninstallProgram=Eltvolts - %1 LaunchProgram=Indts %1 AssocFileExtension=A(z) %1 &trstsa a(z) %2 fjlkiterjesztssel AssocingFileExtension=A(z) %1 trstsa a(z) %2 fjlkiterjesztssel... AutoStartProgramGroupDescription=Indtpult: AutoStartProgram=%1 automatikus indtsa AddonHostProgramNotFound=A(z) %1 nem tallhat a kivlasztott knyvtrban.%n%nMindenkppen folytatja? ================================================ FILE: build/win32/i18n/Default.ko.isl ================================================ ; *** Inno Setup version 6.0.0+ Korean messages *** ; ; 6.0.3+ Translator: SungDong Kim (acroedit@gmail.com) ; 5.5.3+ Translator: Domddol (domddol@gmail.com) ; Translation date: MAR 04, 2014 ; Contributors: Hansoo KIM (iryna7@gmail.com), Woong-Jae An (a183393@hanmail.net) ; Storage: http://www.jrsoftware.org/files/istrans/ ; ο ѱ Ģ ؼմϴ. ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno ; Setup adds the periods automatically (appending a period would result in ; two periods being displayed). [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. LanguageName=Korean LanguageID=$0412 LanguageCodePage=949 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial ;TitleFontSize=29 ;CopyrightFontName=Arial ;CopyrightFontSize=8 [Messages] ; *** Application titles SetupAppTitle=ġ SetupWindowTitle=%1 ġ UninstallAppTitle= UninstallAppFullTitle=%1 ; *** Misc. common InformationTitle= ConfirmTitle=Ȯ ErrorTitle= ; *** SetupLdr messages SetupLdrStartupMessage=%1() ġմϴ, Ͻðڽϱ? LdrCannotCreateTemp=ӽ ϴ, ġ ߴմϴ LdrCannotExecTemp=ӽ ϴ, ġ ߴմϴ HelpTextNote= ; *** Startup error messages LastErrorMessage=%1.%n%n %2: %3 SetupFileMissing=%1 ʽϴ, ذ ų ο ġ α׷ Ͻñ ٶϴ. SetupFileCorrupt=ġ ջǾϴ, ο ġ α׷ Ͻñ ٶϴ. SetupFileCorruptOrWrongVer=ġ ջ̰ų ġ ȣȯ ʽϴ, ذ ų ο ġ α׷ Ͻñ ٶϴ. InvalidParameter=߸ Ű Դϴ:%n%n%1 SetupAlreadyRunning=ġ ̹ Դϴ. WindowsVersionNotSupported= α׷ Windows ʽϴ. WindowsServicePackRequired= α׷ Ϸ %1 sp%2 ̻̾ մϴ. NotOnThisPlatform= α׷ %1 ۵ ʽϴ. OnlyOnThisPlatform= α׷ %1 ؾ մϴ. OnlyOnTheseArchitectures= α׷ Ʒ ó ȣȯǴ Windows ġ ֽϴ:%n%n%1 WinVersionTooLowError= α׷ %1 %2 ̻ ʿմϴ. WinVersionTooHighError= α׷ %1 %2 ̻󿡼 ġ ϴ. AdminPrivilegesRequired= α׷ ġϷ ڷ αؾ մϴ. PowerUserPrivilegesRequired= α׷ ġϷ Ǵ ڷ αؾ մϴ. SetupAppRunningError= %1() Դϴ!%n%n װ νϽ ݾ ֽʽÿ. ׷ Ϸ "Ȯ", Ϸ "" ŬϽʽÿ. UninstallAppRunningError= %1() Դϴ!%n%n װ νϽ ݾ ֽʽÿ. ׷ Ϸ "Ȯ", Ϸ "" ŬϽʽÿ. ; *** Startup questions PrivilegesRequiredOverrideTitle=ġ PrivilegesRequiredOverrideInstruction=ġ 带 ֽʽÿ PrivilegesRequiredOverrideText1=%1 ( ʿ) Ǵ ڿ ġմϴ. PrivilegesRequiredOverrideText2=%1 Ǵ ( ʿ) ġմϴ. PrivilegesRequiredOverrideAllUsers= ڿ ġ(&A) PrivilegesRequiredOverrideAllUsersRecommended= ڿ ġ(&A) (õ) PrivilegesRequiredOverrideCurrentUser= ڿ ġ(&M) PrivilegesRequiredOverrideCurrentUserRecommended= ڿ ġ(&M) (õ) ; *** Misc. errors ErrorCreatingDir="%1" ϴ. ErrorTooManyFilesInDir="%1" ʹ ϴ. ; *** Setup common messages ExitSetupTitle=ġ Ϸ ExitSetupMessage=ġ Ϸ ʾҽϴ, ⼭ ġ ϸ α׷ ġ ʽϴ.%n%nġ ϷϷ ߿ ٽ ġ α׷ ؾ մϴ.%n%n׷ ġ Ͻðڽϱ? AboutSetupMenuItem=ġ (&A)... AboutSetupTitle=ġ AboutSetupMessage=%1 %2%n%3%n%n%1 Ȩ :%n%4 AboutSetupNote= TranslatorNote= ; *** Buttons ButtonBack=< ڷ(&B) ButtonNext=(&N) > ButtonInstall=ġ(&I) ButtonOK=Ȯ ButtonCancel= ButtonYes=(&Y) ButtonYesToAll= (&A) ButtonNo=ƴϿ(&N) ButtonNoToAll= ƴϿ(&O) ButtonFinish=(&F) ButtonBrowse=ãƺ(&B)... ButtonWizardBrowse=ãƺ(&R)... ButtonNewFolder= (&M) ; *** "Select Language" dialog messages SelectLanguageTitle=ġ SelectLanguageLabel=ġ  Ͻʽÿ. ; *** Common wizard text ClickNext=Ϸ "" Ŭϰ ġ Ϸ "" Ŭմϴ. BeveledLabel= BrowseDialogTitle= ãƺ BrowseDialogLabel=Ʒ Ͽ "Ȯ" Ŭմϴ. NewFolderName= ; *** "Welcome" wizard page WelcomeLabel1=[name] ġ WelcomeLabel2= ǻͿ [name/ver]() ġ Դϴ.%n%nġϱ ٸ α׷ ñ ٶϴ. ; *** "Password" wizard page WizardPassword= ȣ PasswordLabel1= ġ ȣ ȣǾ ֽϴ. PasswordLabel3= ȣ Էϰ "" ŬϽʽÿ. ȣ ҹڸ ؾ մϴ. PasswordEditLabel= ȣ(&P): IncorrectPassword= ȣ Ȯ ʽϴ, ٽ ԷϽʽÿ. ; *** "License Agreement" wizard page WizardLicense= LicenseLabel=ϱ ߿ оʽÿ. LicenseLabel3= оʽÿ, ġ Ϸ ࿡ ؾ մϴ. LicenseAccepted=մϴ(&A) LicenseNotAccepted= ʽϴ(&D) ; *** "Information" wizard pages WizardInfoBefore= InfoBeforeLabel=ϱ ߿ оʽÿ. InfoBeforeClickLabel=ġ Ϸ "" ŬϽʽÿ. WizardInfoAfter= InfoAfterLabel=ϱ ߿ оʽÿ. InfoAfterClickLabel=ġ Ϸ "" ŬϽʽÿ. ; *** "User Information" wizard page WizardUserInfo= UserInfoDesc= ԷϽʽÿ. UserInfoName= ̸(&U): UserInfoOrg=(&O): UserInfoSerial=ø ȣ(&S): UserInfoNameRequired= ̸ ԷϽʽÿ. ; *** "Select Destination Location" wizard page WizardSelectDir=ġ ġ SelectDirDesc=[name] ġ ġ Ͻʽÿ. SelectDirLabel3= [name]() ġմϴ. SelectDirBrowseLabel=Ϸ "", ٸ Ϸ "ãƺ" ŬϽʽÿ. DiskSpaceGBLabel= α׷ ּ [gb] GB ũ ʿմϴ. DiskSpaceMBLabel= α׷ ּ [mb] MB ũ ʿմϴ. CannotInstallToNetworkDrive=Ʈũ ̺꿡 ġ ϴ. CannotInstallToUNCPath=UNC ο ġ ϴ. InvalidPath=̺ ڸ ü θ ԷϽʽÿ.%n : C:\APP %n%nǴ, UNC θ ԷϽʽÿ.%n : \\server\share InvalidDrive= ̺ Ǵ UNC ʰų ׼ ϴ, ٸ θ Ͻʽÿ. DiskSpaceWarningTitle=ũ մϴ DiskSpaceWarning=ġ ּ %1 KB ũ ʿ, ̺ %2 KB ۿ ϴ.%n%n׷ Ͻðڽϱ? DirNameTooLong= ̸ Ǵ ΰ ʹ ϴ. InvalidDirName= ̸ ȿ ʽϴ. BadDirName32= ̸ ڸ ϴ:%n%n%1 DirExistsTitle= մϴ DirExists= %n%n%1%n%n() ̹ մϴ, ġϽðڽϱ? DirDoesntExistTitle= ʽϴ DirDoesntExist= %n%n%1%n%n() ʽϴ, ðڽϱ? ; *** "Select Components" wizard page WizardSelectComponents= SelectComponentsDesc=ġ Ҹ Ͻʽÿ. SelectComponentsLabel2=ʿ Ҵ üũϰ ʿ Ҵ üũ մϴ, Ϸ "" ŬϽʽÿ. FullInstallation= ġ ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=ּ ġ CustomInstallation= ġ NoUninstallWarningTitle= Ұ մϴ NoUninstallWarning= Ұ ̹ ġǾ ֽϴ:%n%n%1%n%n , α׷ Ž ҵ ŵ ̴ϴ.%n%n׷ Ͻðڽϱ? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceGBLabel= ּ [gb] GB ũ ʿմϴ. ComponentsDiskSpaceMBLabel= ּ [mb] MB ũ ʿմϴ. ; *** "Select Additional Tasks" wizard page WizardSelectTasks=߰ ۾ SelectTasksDesc= ߰ ۾ Ͻʽÿ. SelectTasksLabel2=[name] ġ ߰ ۾ , "" ŬϽʽÿ. ; *** "Select Start Menu Folder" wizard page WizardSelectProgramGroup= ޴ SelectStartMenuFolderDesc= α׷ ٷΰ⸦ ġϰڽϱ? SelectStartMenuFolderLabel3= ޴ α׷ ٷΰ⸦ ϴ. SelectStartMenuFolderBrowseLabel=Ϸ "" Ŭϰ, ٸ Ϸ "ãƺ" ŬϽʽÿ. MustEnterGroupName= ̸ ԷϽʽÿ. GroupNameTooLong= ̸ Ǵ ΰ ʹ ϴ. InvalidGroupName= ̸ ȿ ʽϴ. BadGroupName= ̸ ڸ ϴ:%n%n%1 NoProgramGroupCheck2= ޴ (&D) ; *** "Ready to Install" wizard page WizardReady=ġ غ Ϸ ReadyLabel1= ǻͿ [name]() ġ غ Ǿϴ. ReadyLabel2a=ġ Ϸ "ġ", ϰų Ϸ "ڷ" ŬϽʽÿ. ReadyLabel2b=ġ Ϸ "ġ" ŬϽʽÿ. ReadyMemoUserInfo= : ReadyMemoDir=ġ ġ: ReadyMemoType=ġ : ReadyMemoComponents= : ReadyMemoGroup= ޴ : ReadyMemoTasks=߰ ۾: ; *** "Preparing to Install" wizard page WizardPreparing=ġ غ PreparingDesc= ǻͿ [name] ġ غϴ Դϴ. PreviousInstallNotCompleted= α׷ ġ/ ۾ Ϸ ʾҽϴ, ϷϷ ǻ͸ ٽ ؾ մϴ.%n%nǻ͸ ٽ , ġ 縦 ٽ Ͽ [name] ġ ϷϽñ ٶϴ. CannotContinue=ġ ϴ, "" ŬϿ ġ Ͻʽÿ. ApplicationsFound= α׷ ġ Ʈ ʿ ϰ ֽϴ, ġ 簡 ̷ α׷ ڵ ֵ Ͻñ ٶϴ. ApplicationsFound2= α׷ ġ Ʈ ʿ ϰ ֽϴ, ġ 簡 ̷ α׷ ڵ ֵ Ͻñ ٶϴ. ġ ϷǸ, ġ α׷ ٽ ۵ǵ õ ̴ϴ. CloseApplications=ڵ α׷ (&A) DontCloseApplications=α׷ (&D) ErrorCloseApplications=ġ 簡 α׷ ڵ ϴ, ϱ ġ Ʈ ʿ ϰ ִ α׷ Ͻñ ٶϴ. PrepareToInstallNeedsRestart=ġ ǻ͸ ؾ մϴ. [name] ġ Ϸϱ ǻ͸ ٽ Ŀ ġ 縦 ٽ ֽʽÿ.%n%n ٽ Ͻðڽϱ? ; *** "Installing" wizard page WizardInstalling=ġ InstallingLabel= ǻͿ [name]() ġϴ ... ٷ ֽʽÿ. ; *** "Setup Completed" wizard page FinishedHeadingLabel=[name] ġ Ϸ FinishedLabelNoIcons= ǻͿ [name]() ġǾϴ. FinishedLabel= ǻͿ [name]() ġǾϴ, α׷ ġ Ͽ ֽϴ. ClickFinish=ġ "" ŬϽʽÿ. FinishedRestartLabel=[name] ġ ϷϷ, ǻ͸ ٽ ؾ մϴ. ٽ Ͻðڽϱ? FinishedRestartMessage=[name] ġ ϷϷ, ǻ͸ ٽ ؾ մϴ.%n%n ٽ Ͻðڽϱ? ShowReadmeCheck=, README ǥմϴ YesRadio=, ٽ մϴ(&Y) NoRadio=ƴϿ, ߿ ٽ մϴ(&N) ; used for example as 'Run MyProg.exe' RunEntryExec=%1 ; used for example as 'View Readme.txt' RunEntryShellExec=%1 ǥ ; *** "Setup Needs the Next Disk" stuff ChangeDiskTitle=ũ ʿմϴ SelectDiskLabel2=ũ %1() ϰ "Ȯ" ŬϽʽÿ.%n%n ũ Ʒ ΰ ƴ ִ , ùٸ θ Էϰų "ãƺ" ŬϽñ ٶϴ. PathLabel=(&P): FileNotInDir2=%2 %1() ġ ϴ, ùٸ ũ ϰų ٸ Ͻʽÿ. SelectDirectoryLabel= ũ ġ Ͻʽÿ. ; *** Installation phase messages SetupAborted=ġ Ϸ ʾҽϴ.%n%n ذ , ٽ ġ Ͻʽÿ. AbortRetryIgnoreSelectAction=׼ ֽʽÿ. AbortRetryIgnoreRetry=õ(&T) AbortRetryIgnoreIgnore= ϰ (&I) AbortRetryIgnoreCancel=ġ ; *** Installation status messages StatusClosingApplications=α׷ ϴ ... StatusCreateDirs= ... StatusExtractFiles= ϴ ... StatusCreateIcons=ٷΰ⸦ ϴ ... StatusCreateIniEntries=INI ׸ ... StatusCreateRegistryEntries=Ʈ ׸ ... StatusRegisterFiles= ϴ ... StatusSavingUninstall= ϴ ... StatusRunProgram=ġ Ϸϴ ... StatusRestartingApplications=α׷ ٽ ϴ ... StatusRollback= ϴ ... ; *** Misc. errors ErrorInternal2= : %1 ErrorFunctionFailedNoCode=%1 ErrorFunctionFailed=%1 ; ڵ %2 ErrorFunctionFailedWithMessage=%1 , ڵ: %2.%n%3 ErrorExecutingProgram= :%n%1 ; *** Registry errors ErrorRegOpenKey=Ʈ Ű :%n%1\%2 ErrorRegCreateKey=Ʈ Ű :%n%1\%2 ErrorRegWriteKey=Ʈ Ű :%n%1\%2 ; *** INI errors ErrorIniEntry=%1 Ͽ INI ׸ Դϴ. ; *** File copying errors FileAbortRetryIgnoreSkipNotRecommended= dzʶ(&S) ( ʽϴ) FileAbortRetryIgnoreIgnoreNotRecommended= ϰ (&I) ( ʽϴ) SourceIsCorrupted= ջ SourceDoesntExist= %1() ExistingFileReadOnly2= б ̱⶧ ü ϴ. ExistingFileReadOnlyRetry=б Ӽ ϰ ٽ õϷ(&R) ExistingFileReadOnlyKeepExisting= (&K) ErrorReadingExistingDest= д ߻: FileExists= ̹ մϴ.%n%n ðڽϱ? ExistingFileNewer= ġϷ ϴ Ϻ Դϴ, Ͻñ ٶϴ.%n%n Ͻðڽϱ? ErrorChangingAttr= Ӽ ϴ ߻: ErrorCreatingTemp= ߻: ErrorReadingSource= д ߻: ErrorCopying= ϴ ߻: ErrorReplacingExistingFile= üϴ ߻: ErrorRestartReplace=RestartReplace : ErrorRenamingTemp= ̸ ٲٴ ߻: ErrorRegisterServer=DLL/OCX : %1 ErrorRegSvr32Failed=RegSvr32 ڵ : %1 ErrorRegisterTypeLib= ̺귯 Ͽ : %1 ; *** Uninstall display name markings ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32Ʈ UninstallDisplayNameMark64Bit=64Ʈ UninstallDisplayNameMarkAllUsers= UninstallDisplayNameMarkCurrentUser= ; *** Post-installation errors ErrorOpeningReadme=README ߻߽ϴ. ErrorRestartingComputer=ǻ͸ ٽ ϴ, ٽ Ͻʽÿ. ; *** Uninstaller messages UninstallNotFound= %1() ʱ , Ÿ ϴ. UninstallOpenError= %1() , Ÿ ϴ. UninstallUnsupportedVer= α "%1"() ν ̱ , Ÿ ϴ. UninstallUnknownEntry= ׸ %1() α׿ ԵǾ ֽϴ. ConfirmUninstall= %1() Ҹ Ͻðڽϱ? UninstallOnlyOnWin64= α׷ 64Ʈ Windows ֽϴ. OnlyAdminCanUninstall= α׷ Ϸ ʿմϴ. UninstallStatusLabel= ǻͿ %1() ϴ ... ٷ ֽʽÿ. UninstalledAll=%1() ŵǾϴ! UninstalledMost=%1 Ű ϷǾϴ.%n%nϺ Ҵ , Ͻñ ٶϴ. UninstalledAndNeedsRestart=%1 Ÿ ϷϷ, ǻ͸ ٽ ؾ մϴ.%n%n ٽ Ͻðڽϱ? UninstallDataCorrupted= "%1"() ջǾ , Ÿ ϴ. ; *** Uninstallation phase messages ConfirmDeleteSharedFileTitle= Ͻðڽϱ? ConfirmDeleteSharedFile2=ý  α׷ ʽϴ, Ͻðڽϱ?%n%n ٸ α׷ ϰ ִ ¿ , ش α׷ ۵ , Ȯ "ƴϿ" ϼŵ ˴ϴ. ýۿ ־ ʽϴ. SharedFileNameLabel= ̸: SharedFileLocationLabel=ġ: WizardUninstalling= StatusUninstalling=%1() ϴ ... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=%1() ġϴ Դϴ. ShutdownBlockReasonUninstallingApp=%1() ϴ Դϴ. ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1 %2 AdditionalIcons= ߰: CreateDesktopIcon= ȭ鿡 ٷΰ (&D) CreateQuickLaunchIcon= (&Q) ProgramOnTheWeb=%1 UninstallProgram=%1 LaunchProgram=%1 AssocFileExtension= Ȯ %2() %1 մϴ. AssocingFileExtension= Ȯ %2() %1 ϴ ... AutoStartProgramGroupDescription=: AutoStartProgram=%1() ڵ AddonHostProgramNotFound=%1() ġ ϴ.%n%n׷ Ͻðڽϱ? ================================================ FILE: build/win32/i18n/Default.zh-cn.isl ================================================ ; *** Inno Setup version 6.0.3+ Chinese Simplified messages *** ; ; Maintained by Zhenghan Yang ; Email: 847320916@QQ.com ; Translation based on network resource ; The latest Translation is on https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation ; [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. LanguageName=简体中文 ; If Language Name display incorrect, uncomment next line ; LanguageName=<7B80><4F53><4E2D><6587> LanguageID=$0804 LanguageCodePage=936 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial ;TitleFontSize=29 ;CopyrightFontName=Arial ;CopyrightFontSize=8 [Messages] ; *** 应用程序标题 SetupAppTitle=安装 SetupWindowTitle=安装 - %1 UninstallAppTitle=卸载 UninstallAppFullTitle=%1 卸载 ; *** Misc. common InformationTitle=信息 ConfirmTitle=确认 ErrorTitle=错误 ; *** SetupLdr messages SetupLdrStartupMessage=现在将安装 %1。您想要继续吗? LdrCannotCreateTemp=不能创建临时文件。安装中断。 LdrCannotExecTemp=不能执行临时目录中的文件。安装中断。 HelpTextNote= ; *** 启动错误消息 LastErrorMessage=%1.%n%n错误 %2: %3 SetupFileMissing=安装目录中的文件 %1 丢失。请修正这个问题或获取一个新的程序副本。 SetupFileCorrupt=安装文件已损坏。请获取一个新的程序副本。 SetupFileCorruptOrWrongVer=安装文件已损坏,或是与这个安装程序的版本不兼容。请修正这个问题或获取新的程序副本。 InvalidParameter=无效的命令行参数: %n%n%1 SetupAlreadyRunning=安装程序正在运行。 WindowsVersionNotSupported=这个程序不支持该版本的计算机运行。 WindowsServicePackRequired=这个程序要求%1服务包%1或更高。 NotOnThisPlatform=这个程序将不能运行于 %1。 OnlyOnThisPlatform=这个程序必须运行于 %1。 OnlyOnTheseArchitectures=这个程序只能在为下列处理器结构设计的 Windows 版本中进行安装:%n%n%1 WinVersionTooLowError=这个程序需要 %1 版本 %2 或更高。 WinVersionTooHighError=这个程序不能安装于 %1 版本 %2 或更高。 AdminPrivilegesRequired=在安装这个程序时您必须以管理员身份登录。 PowerUserPrivilegesRequired=在安装这个程序时您必须以管理员身份或有权限的用户组身份登录。 SetupAppRunningError=安装程序发现 %1 当前正在运行。%n%n请先关闭所有运行的窗口,然后单击“确定”继续,或按“取消”退出。 UninstallAppRunningError=卸载程序发现 %1 当前正在运行。%n%n请先关闭所有运行的窗口,然后单击“确定”继续,或按“取消”退出。 ; *** 启动问题 PrivilegesRequiredOverrideTitle=选择安装程序模式 PrivilegesRequiredOverrideInstruction=选择安装模式 PrivilegesRequiredOverrideText1=%1 可以为所有用户安装(需要管理员权限),或仅为您安装。 PrivilegesRequiredOverrideText2=%1 只能为您安装,或为所有用户安装(需要管理员权限)。 PrivilegesRequiredOverrideAllUsers=为所有用户安装(&A) PrivilegesRequiredOverrideAllUsersRecommended=为所有用户安装(建议选项)(&A) PrivilegesRequiredOverrideCurrentUser=只为我安装(&M) PrivilegesRequiredOverrideCurrentUserRecommended=只为我安装(建议选项)(&M) ; *** 其它错误 ErrorCreatingDir=安装程序不能创建目录“%1”。 ErrorTooManyFilesInDir=不能在目录“%1”中创建文件,因为里面的文件太多 ; *** 安装程序公共消息 ExitSetupTitle=退出安装程序 ExitSetupMessage=安装程序未完成安装。如果您现在退出,您的程序将不能安装。%n%n您可以以后再运行安装程序完成安装。%n%n退出安装程序吗? AboutSetupMenuItem=关于安装程序(&A)... AboutSetupTitle=关于安装程序 AboutSetupMessage=%1 版本 %2%n%3%n%n%1 主页:%n%4 AboutSetupNote= TranslatorNote= ; *** 按钮 ButtonBack=< 上一步(&B) ButtonNext=下一步(&N) > ButtonInstall=安装(&I) ButtonOK=确定 ButtonCancel=取消 ButtonYes=是(&Y) ButtonYesToAll=全是(&A) ButtonNo=否(&N) ButtonNoToAll=全否(&O) ButtonFinish=完成(&F) ButtonBrowse=浏览(&B)... ButtonWizardBrowse=浏览(&R)... ButtonNewFolder=新建文件夹(&M) ; *** “选择语言”对话框消息 SelectLanguageTitle=选择安装语言 SelectLanguageLabel=选择安装时要使用的语言。 ; *** 公共向导文字 ClickNext=单击“下一步”继续,或单击“取消”退出安装程序。 BeveledLabel= BrowseDialogTitle=浏览文件夹 BrowseDialogLabel=在下列列表中选择一个文件夹,然后单击“确定”。 NewFolderName=新建文件夹 ; *** “欢迎”向导页 WelcomeLabel1=欢迎使用 [name] 安装向导 WelcomeLabel2=现在将安装 [name/ver] 到您的电脑中。%n%n推荐您在继续安装前关闭所有其它应用程序。 ; *** “密码”向导页 WizardPassword=密码 PasswordLabel1=这个安装程序有密码保护。 PasswordLabel3=请输入密码,然后单击“下一步”继续。密码区分大小写。 PasswordEditLabel=密码(&P): IncorrectPassword=您输入的密码不正确,请重试。 ; *** “许可协议”向导页 WizardLicense=许可协议 LicenseLabel=继续安装前请阅读下列重要信息。 LicenseLabel3=请仔细阅读下列许可协议。您在继续安装前必须同意这些协议条款。 LicenseAccepted=我同意此协议(&A) LicenseNotAccepted=我不同意此协议(&D) ; *** “信息”向导页 WizardInfoBefore=信息 InfoBeforeLabel=请在继续安装前阅读下列重要信息。 InfoBeforeClickLabel=如果您想继续安装,单击“下一步”。 WizardInfoAfter=信息 InfoAfterLabel=请在继续安装前阅读下列重要信息。 InfoAfterClickLabel=如果您想继续安装,单击“下一步”。 ; *** “用户信息”向导页 WizardUserInfo=用户信息 UserInfoDesc=请输入您的信息。 UserInfoName=用户名(&U): UserInfoOrg=组织(&O): UserInfoSerial=序列号(&S): UserInfoNameRequired=您必须输入名字。 ; *** “选择目标目录”向导面 WizardSelectDir=选择目标位置 SelectDirDesc=您想将 [name] 安装在什么地方? SelectDirLabel3=安装程序将安装 [name] 到下列文件夹中。 SelectDirBrowseLabel=单击“下一步”继续。如果您想选择其它文件夹,单击“浏览”。 DiskSpaceGBLabel=至少需要有 [gb] GB 的可用磁盘空间。 DiskSpaceMBLabel=至少需要有 [mb] MB 的可用磁盘空间。 CannotInstallToNetworkDrive=安装程序无法安装到一个网络驱动器。 CannotInstallToUNCPath=安装程序无法安装到一个UNC路径。 InvalidPath=您必须输入一个带驱动器卷标的完整路径,例如:%n%nC:\APP%n%n或下列形式的 UNC 路径:%n%n\\server\share InvalidDrive=您选定的驱动器或 UNC 共享不存在或不能访问。请选选择其它位置。 DiskSpaceWarningTitle=没有足够的磁盘空间 DiskSpaceWarning=安装程序至少需要 %1 KB 的可用空间才能安装,但选定驱动器只有 %2 KB 的可用空间。%n%n您一定要继续吗? DirNameTooLong=文件夹名或路径太长。 InvalidDirName=文件夹名是无效的。 BadDirName32=文件夹名不能包含下列任何字符:%n%n%1 DirExistsTitle=文件夹存在 DirExists=文件夹:%n%n%1%n%n已经存在。您一定要安装到这个文件夹中吗? DirDoesntExistTitle=文件夹不存在 DirDoesntExist=文件夹:%n%n%1%n%n不存在。您想要创建此目录吗? ; *** “选择组件”向导页 WizardSelectComponents=选择组件 SelectComponentsDesc=您想安装哪些程序的组件? SelectComponentsLabel2=选择您想要安装的组件;清除您不想安装的组件。然后单击“下一步”继续。 FullInstallation=完全安装 ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=简洁安装 CustomInstallation=自定义安装 NoUninstallWarningTitle=组件存在 NoUninstallWarning=安装程序侦测到下列组件已在您的电脑中安装。:%n%n%1%n%n取消选定这些组件将不能卸载它们。%n%n您一定要继续吗? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceGBLabel=当前选择的组件至少需要 [gb] GB 的磁盘空间。 ComponentsDiskSpaceMBLabel=当前选择的组件至少需要 [mb] MB 的磁盘空间。 ; *** “选择附加任务”向导页 WizardSelectTasks=选择附加任务 SelectTasksDesc=您想要安装程序执行哪些附加任务? SelectTasksLabel2=选择您想要安装程序在安装 [name] 时执行的附加任务,然后单击“下一步”。 ; *** “选择开始菜单文件夹”向导页 WizardSelectProgramGroup=选择开始菜单文件夹 SelectStartMenuFolderDesc=您想在哪里放置程序的快捷方式? SelectStartMenuFolderLabel3=安装程序现在将在下列开始菜单文件夹中创建程序的快捷方式。 SelectStartMenuFolderBrowseLabel=单击“下一步”继续。如果您想选择其它文件夹,单击“浏览”。 MustEnterGroupName=您必须输入一个文件夹名。 GroupNameTooLong=文件夹名或路径太长。 InvalidGroupName=文件夹名是无效的。 BadGroupName=文件夹名不能包含下列任何字符:%n%n%1 NoProgramGroupCheck2=不创建开始菜单文件夹(&D) ; *** “准备安装”向导页 WizardReady=准备安装 ReadyLabel1=安装程序现在准备开始安装 [name] 到您的电脑中。 ReadyLabel2a=单击“安装”继续此安装程序。如果您想要回顾或改变设置,请单击“上一步”。 ReadyLabel2b=单击“安装”继续此安装程序? ReadyMemoUserInfo=用户信息: ReadyMemoDir=目标位置: ReadyMemoType=安装类型: ReadyMemoComponents=选定组件: ReadyMemoGroup=开始菜单文件夹: ReadyMemoTasks=附加任务: ; *** “正在准备安装”向导页 WizardPreparing=正在准备安装 PreparingDesc=安装程序正在准备安装 [name] 到您的电脑中。 PreviousInstallNotCompleted=先前程序的安装/卸载未完成。您需要重新启动您的电脑才能完成安装。%n%n在重新启动电脑后,再运行安装完成 [name] 的安装。 CannotContinue=安装程序不能继续。请单击“取消”退出。 ApplicationsFound=下列应用程序正在使用的文件需要更新设置。它是建议您允许安装程序自动关闭这些应用程序。 ApplicationsFound2=下列应用程序正在使用的文件需要更新设置。它是建议您允许安装程序自动关闭这些应用程序。安装完成后,安装程序将尝试重新启动应用程序。 CloseApplications=自动关闭该应用程序(&A) DontCloseApplications=不要关闭该应用程序(D) ErrorCloseApplications=安装程序无法自动关闭所有应用程序。在继续之前,我们建议您关闭所有使用需要更新的安装程序文件。 PrepareToInstallNeedsRestart=安装程序必须重新启动计算机。重新启动计算机后,请再次运行安装程序以完成 [name] 的安装。%n%n是否立即重新启动? ; *** “正在安装”向导页 WizardInstalling=正在安装 InstallingLabel=安装程序正在安装 [name] 到您的电脑中,请稍等。 ; *** “安装完成”向导页 FinishedHeadingLabel=[name] 安装完成 FinishedLabelNoIcons=安装程序已在您的电脑中安装了 [name]。 FinishedLabel=安装程序已在您的电脑中安装了 [name]。此应用程序可以通过选择安装的快捷方式运行。 ClickFinish=单击“完成”退出安装程序。 FinishedRestartLabel=要完成 [name] 的安装,安装程序必须重新启动您的电脑。您想现在重新启动吗? FinishedRestartMessage=要完成 [name] 的安装,安装程序必须重新启动您的电脑。%n%n您想现在重新启动吗? ShowReadmeCheck=是,您想查阅自述文件 YesRadio=是,立即重新启动电脑(&Y) NoRadio=否,稍后重新启动电脑(&N) ; 用于象“运行 MyProg.exe” RunEntryExec=运行 %1 ; 用于象“查阅 Readme.txt” RunEntryShellExec=查阅 %1 ; *** “安装程序需要下一张磁盘”提示 ChangeDiskTitle=安装程序需要下一张磁盘 SelectDiskLabel2=请插入磁盘 %1 并单击“确定”。%n%n如果这个磁盘中的文件不能在不同于下列显示的文件夹中找到,输入正确的路径或单击“浏览”。 PathLabel=路径(&P): FileNotInDir2=文件“%1”不能在“%2”定位。请插入正确的磁盘或选择其它文件夹。 SelectDirectoryLabel=请指定下一张磁盘的位置。 ; *** 安装状态消息 SetupAborted=安装程序未完成安装。%n%n请修正这个问题并重新运行安装程序。 AbortRetryIgnoreSelectAction=选项 AbortRetryIgnoreRetry=重试(&T) AbortRetryIgnoreIgnore=忽略错误并继续(&I) AbortRetryIgnoreCancel=关闭安装程序 ; *** 安装状态消息 StatusClosingApplications=正在关闭应用程序... StatusCreateDirs=正在创建目录... StatusExtractFiles=正在解压缩文件... StatusCreateIcons=正在创建快捷方式... StatusCreateIniEntries=正在创建 INI 条目... StatusCreateRegistryEntries=正在创建注册表条目... StatusRegisterFiles=正在注册文件... StatusSavingUninstall=正在保存卸载信息... StatusRunProgram=正在完成安装... StatusRestartingApplications=正在重启应用程序... StatusRollback=正在撤销更改... ; *** 其它错误 ErrorInternal2=内部错误: %1 ErrorFunctionFailedNoCode=%1 失败 ErrorFunctionFailed=%1 失败;错误代码 %2 ErrorFunctionFailedWithMessage=%1 失败;错误代码 %2.%n%3 ErrorExecutingProgram=不能执行文件:%n%1 ; *** 注册表错误 ErrorRegOpenKey=打开注册表项时出错:%n%1\%2 ErrorRegCreateKey=创建注册表项时出错:%n%1\%2 ErrorRegWriteKey=写入注册表项时出错:%n%1\%2 ; *** INI 错误 ErrorIniEntry=在文件“%1”创建 INI 项目错误。 ; *** 文件复制错误 FileAbortRetryIgnoreSkipNotRecommended=跳过这个文件 (不推荐)(&S) FileAbortRetryIgnoreIgnoreNotRecommended=忽略错误并继续 (不推荐)(&I) SourceIsCorrupted=源文件已损坏 SourceDoesntExist=源文件“%1”不存在 ExistingFileReadOnly2=无法替换现有文件,因为它是只读的。 ExistingFileReadOnlyRetry=移除只读属性并重试(&R) ExistingFileReadOnlyKeepExisting=保留现有文件(&K) ErrorReadingExistingDest=尝试读取现有文件时发生一个错误: FileExists=文件已经存在。%n%n您想要安装程序覆盖它吗? ExistingFileNewer=现有的文件新与安装程序要安装的文件。推荐您保留现有文件。%n%n您想要保留现有的文件吗? ErrorChangingAttr=尝试改变下列现有的文件的属性时发生一个错误: ErrorCreatingTemp=尝试在目标目录创建文件时发生一个错误: ErrorReadingSource=尝试读取下列源文件时发生一个错误: ErrorCopying=尝试复制下列文件时发生一个错误: ErrorReplacingExistingFile=尝试替换现有的文件时发生错误: ErrorRestartReplace=重启电脑后替换文件失败: ErrorRenamingTemp=尝试重新命名以下目标目录中的一个文件时发生错误: ErrorRegisterServer=不能注册 DLL/OCX: %1 ErrorRegSvr32Failed=RegSvr32 失败;退出代码 %1 ErrorRegisterTypeLib=不能注册类型库: %1 ; *** 卸载显示名字标记 ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32位 UninstallDisplayNameMark64Bit=64位 UninstallDisplayNameMarkAllUsers=所有用户 UninstallDisplayNameMarkCurrentUser=当前用户 ; *** 安装后错误 ErrorOpeningReadme=当尝试打开自述文件时发生一个错误。 ErrorRestartingComputer=安装程序不能重新启动电脑,请手动重启。 ; *** 卸载消息 UninstallNotFound=文件“%1”不存在。不能卸载。 UninstallOpenError=文件“%1”不能打开。不能卸载。 UninstallUnsupportedVer=卸载日志文件“%1”有未被这个版本的卸载器承认的格式。不能卸载 UninstallUnknownEntry=在卸载日志中遇到一个未知的条目 (%1) ConfirmUninstall=您确认想要完全删除 %1 及它的所有组件吗? UninstallOnlyOnWin64=这个安装程序只能在 64 位 Windows 中进行卸载。 OnlyAdminCanUninstall=这个安装的程序只能是有管理员权限的用户才能卸载。 UninstallStatusLabel=正在从您的电脑中删除 %1,请等待。 UninstalledAll=%1 已顺利地从您的电脑中删除。 UninstalledMost=%1 卸载完成。%n%n有一些内容不能被删除。您可以手工删除它们。 UninstalledAndNeedsRestart=要完成 %1 的卸载,您的电脑必须重新启动。%n%n您现在想重新启动电脑吗? UninstallDataCorrupted=“%1”文件被破坏,不能卸载 ; *** 卸载状态消息 ConfirmDeleteSharedFileTitle=删除共享文件吗? ConfirmDeleteSharedFile2=系统中包含的下列共享文件已经不被其它程序使用。您想要卸载程序删除这些共享文件吗?%n%n如果这些文件被删除,但还有程序正在使用这些文件,这些程序可能不能正确执行。如果您不能确定,选择“否”。把这些文件保留在系统中以免引起问题。 SharedFileNameLabel=文件名: SharedFileLocationLabel=位置: WizardUninstalling=卸载状态 StatusUninstalling=正在卸载 %1... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=正在安装 %1. ShutdownBlockReasonUninstallingApp=正在卸载 %1. ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1 版本 %2 AdditionalIcons=附加快捷方式: CreateDesktopIcon=创建桌面快捷方式(&D) CreateQuickLaunchIcon=创建快速运行栏快捷方式(&Q) ProgramOnTheWeb=%1 网站 UninstallProgram=卸载 %1 LaunchProgram=运行 %1 AssocFileExtension=将 %2 文件扩展名与 %1 建立关联(&A) AssocingFileExtension=正在将 %2 文件扩展名与 %1 建立关联... AutoStartProgramGroupDescription=启动组: AutoStartProgram=自动启动 %1 AddonHostProgramNotFound=%1无法找到您所选择的文件夹。%n%n您想要继续吗? ================================================ FILE: build/win32/i18n/Default.zh-tw.isl ================================================ ; *** Inno Setup version 6.0.0+ Chinese Traditional messages *** ; ; Name: John Wu, mr.johnwu@gmail.com ; Base on 5.5.3+ translations by Samuel Lee, Email: 751555749@qq.com ; Translation based on network resource ; [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. ; If Language Name display incorrect, uncomment next line LanguageName=<7e41><9ad4><4e2d><6587> LanguageID=$0404 LanguageCodepage=950 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. DialogFontName=新細明體 DialogFontSize=9 TitleFontName=Arial TitleFontSize=28 WelcomeFontName=新細明體 WelcomeFontSize=12 CopyrightFontName=新細明體 CopyrightFontSize=9 [Messages] ; *** Application titles SetupAppTitle=安裝程式 SetupWindowTitle=%1 安裝程式 UninstallAppTitle=解除安裝 UninstallAppFullTitle=解除安裝 %1 ; *** Misc. common InformationTitle=訊息 ConfirmTitle=確認 ErrorTitle=錯誤 ; *** SetupLdr messages SetupLdrStartupMessage=這將會安裝 %1。您想要繼續嗎? LdrCannotCreateTemp=無法建立暫存檔案。安裝程式將會結束。 LdrCannotExecTemp=無法執行暫存檔案。安裝程式將會結束。 HelpTextNote= ; *** Startup error messages LastErrorMessage=%1%n%n錯誤 %2: %3 SetupFileMissing=安裝資料夾中遺失檔案 %1。請修正此問題或重新取得此軟體。 SetupFileCorrupt=安裝檔案已經損毀。請重新取得此軟體。 SetupFileCorruptOrWrongVer=安裝檔案已經損毀,或與安裝程式的版本不符。請重新取得此軟體。 InvalidParameter=某個無效的變量已被傳遞到了命令列:%n%n%1 SetupAlreadyRunning=安裝程式已經在執行。 WindowsVersionNotSupported=本安裝程式並不支援目前在電腦所運行的 Windows 版本。 WindowsServicePackRequired=本安裝程式需要 %1 Service Pack %2 或更新。 NotOnThisPlatform=這個程式無法在 %1 執行。 OnlyOnThisPlatform=這個程式必須在 %1 執行。 OnlyOnTheseArchitectures=這個程式只能在專門為以下處理器架構而設計的 Windows 上安裝:%n%n%1 WinVersionTooLowError=這個程式必須在 %1 版本 %2 或以上的系統執行。 WinVersionTooHighError=這個程式無法安裝在 %1 版本 %2 或以上的系統。 AdminPrivilegesRequired=您必須登入成系統管理員以安裝這個程式。 PowerUserPrivilegesRequired=您必須登入成具有系統管理員或 Power User 權限的使用者以安裝這個程式。 SetupAppRunningError=安裝程式偵測到 %1 正在執行。%n%n請關閉該程式後按 [確定] 繼續,或按 [取消] 離開。 UninstallAppRunningError=解除安裝程式偵測到 %1 正在執行。%n%n請關閉該程式後按 [確定] 繼續,或按 [取消] 離開。 ; *** Startup questions PrivilegesRequiredOverrideTitle=選擇安裝程式安裝模式 PrivilegesRequiredOverrideInstruction=選擇安裝模式 PrivilegesRequiredOverrideText1=可以為所有使用者安裝 %1 (需要系統管理權限),或是僅為您安裝。 PrivilegesRequiredOverrideText2=可以僅為您安裝 %1,或是為所有使用者安裝 (需要系統管理權限)。 PrivilegesRequiredOverrideAllUsers=為所有使用者安裝 (&A) PrivilegesRequiredOverrideAllUsersRecommended=為所有使用者安裝 (建議選項) (&A) PrivilegesRequiredOverrideCurrentUser=僅為我安裝 (&M) PrivilegesRequiredOverrideCurrentUserRecommended=僅為我安裝 (建議選項) (&M) ; *** Misc. errors ErrorCreatingDir=安裝程式無法建立資料夾“%1”。 ErrorTooManyFilesInDir=無法在資料夾“%1”內建立檔案,因為資料夾內有太多的檔案。 ; *** Setup common messages ExitSetupTitle=結束安裝程式 ExitSetupMessage=安裝尚未完成。如果您現在結束安裝程式,這個程式將不會被安裝。%n%n您可以稍後再執行安裝程式以完成安裝程序。您現在要結束安裝程式嗎? AboutSetupMenuItem=關於安裝程式(&A)... AboutSetupTitle=關於安裝程式 AboutSetupMessage=%1 版本 %2%n%3%n%n%1 網址:%n%4 AboutSetupNote= TranslatorNote= ; *** Buttons ButtonBack=< 上一步(&B) ButtonInstall=安裝(&I) ButtonNext=下一步(&N) > ButtonOK=確定 ButtonCancel=取消 ButtonYes=是(&Y) ButtonYesToAll=全部皆是(&A) ButtonNo=否(&N) ButtonNoToAll=全部皆否(&O) ButtonFinish=完成(&F) ButtonBrowse=瀏覽(&B)... ButtonWizardBrowse=瀏覽(&R)... ButtonNewFolder=建立新資料夾(&M) ; *** "Select Language" dialog messages SelectLanguageTitle=選擇安裝語言 SelectLanguageLabel=選擇在安裝過程中使用的語言: ; *** Common wizard text ClickNext=按 [下一步] 繼續安裝,或按 [取消] 結束安裝程式。 BeveledLabel= BrowseDialogTitle=瀏覽資料夾 BrowseDialogLabel=在下面的資料夾列表中選擇一個資料夾,然後按 [確定]。 NewFolderName=新資料夾 ; *** "Welcome" wizard page WelcomeLabel1=歡迎使用 [name] 安裝程式 WelcomeLabel2=這個安裝程式將會安裝 [name/ver] 到您的電腦。%n%n我們強烈建議您在安裝過程中關閉其它的應用程式,以避免與安裝程式發生沖突。 ; *** "Password" wizard page WizardPassword=密碼 PasswordLabel1=這個安裝程式具有密碼保護。 PasswordLabel3=請輸入密碼,然後按 [下一步] 繼續。密碼是區分大小寫的。 PasswordEditLabel=密碼(&P): IncorrectPassword=您輸入的密碼不正確,請重新輸入。 ; *** "License Agreement" wizard page WizardLicense=授權合約 LicenseLabel=請閱讀以下授權合約。 LicenseLabel3=請閱讀以下授權合約,您必須接受合約的各項條款才能繼續安裝。 LicenseAccepted=我同意(&A) LicenseNotAccepted=我不同意(&D) ; *** "Information" wizard pages WizardInfoBefore=訊息 InfoBeforeLabel=在繼續安裝之前請閱讀以下重要資訊。 InfoBeforeClickLabel=當您準備好繼續安裝,請按 [下一步]。 WizardInfoAfter=訊息 InfoAfterLabel=在繼續安裝之前請閱讀以下重要資訊。 InfoAfterClickLabel=當您準備好繼續安裝,請按 [下一步]。 ; *** "User Information" wizard page WizardUserInfo=使用者資訊 UserInfoDesc=請輸入您的資料。 UserInfoName=使用者名稱(&U): UserInfoOrg=組織(&O): UserInfoSerial=序號(&S): UserInfoNameRequired=您必須輸入您的名稱。 ; *** "Select Destination Location" wizard page WizardSelectDir=選擇目的資料夾 SelectDirDesc=選擇安裝程式安裝 [name] 的位置。 SelectDirLabel3=安裝程式將會把 [name] 安裝到下面的資料夾。 SelectDirBrowseLabel=按 [下一步] 繼續,如果您想選擇另一個資料夾,請按 [瀏覽]。 DiskSpaceMBLabel=最少需要 [mb] MB 磁碟空間。 CannotInstallToNetworkDrive=安裝程式無法安裝於網絡磁碟機。 CannotInstallToUNCPath=安裝程式無法安裝於 UNC 路徑。 InvalidPath=您必須輸入完整的路徑名稱及磁碟機代碼。%n%n例如 C:\App 或 UNC 路徑格式 \\伺服器\共用資料夾。 InvalidDrive=您選取的磁碟機或 UNC 名稱不存在或無法存取,請選擇其他的目的地。 DiskSpaceWarningTitle=磁碟空間不足 DiskSpaceWarning=安裝程式需要至少 %1 KB 的磁碟空間,您所選取的磁碟只有 %2 KB 可用空間。%n%n您要繼續安裝嗎? DirNameTooLong=資料夾名稱或路徑太長。 InvalidDirName=資料夾名稱不正確。 BadDirName32=資料夾名稱不得包含以下特殊字元:%n%n%1 DirExistsTitle=資料夾已經存在 DirExists=資料夾:%n%n%1%n%n 已經存在。仍要安裝到該資料夾嗎? DirDoesntExistTitle=資料夾不存在 DirDoesntExist=資料夾:%n%n%1%n%n 不存在。要建立該資料夾嗎? ; *** "Select Components" wizard page WizardSelectComponents=選擇元件 SelectComponentsDesc=選擇將會被安裝的元件。 SelectComponentsLabel2=選擇您想要安裝的元件;清除您不想安裝的元件。然後按 [下一步] 繼續安裝。 FullInstallation=完整安裝 ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=最小安裝 CustomInstallation=自訂安裝 NoUninstallWarningTitle=元件已存在 NoUninstallWarning=安裝程式偵測到以下元件已經安裝在您的電腦上:%n%n%1%n%n取消選擇這些元件將不會移除它們。%n%n您仍然要繼續嗎? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceMBLabel=目前的選擇需要至少 [mb] MB 磁碟空間。 ; *** "Select Additional Tasks" wizard page WizardSelectTasks=選擇附加的工作 SelectTasksDesc=選擇要執行的附加工作。 SelectTasksLabel2=選擇安裝程式在安裝 [name] 時要執行的附加工作,然後按 [下一步]。 ; *** "Select Start Menu Folder" wizard page WizardSelectProgramGroup=選擇「開始」功能表的資料夾 SelectStartMenuFolderDesc=選擇安裝程式建立程式的捷徑的位置。 SelectStartMenuFolderLabel3=安裝程式將會把程式的捷徑建立在下面的「開始」功能表資料夾。 SelectStartMenuFolderBrowseLabel=按 [下一步] 繼續,如果您想選擇另一個資料夾,請按 [瀏覽]。 MustEnterGroupName=您必須輸入一個資料夾的名稱。 GroupNameTooLong=資料夾名稱或路徑太長。 InvalidGroupName=資料夾名稱不正確。 BadGroupName=資料夾名稱不得包含下列字元:%n%n%1 NoProgramGroupCheck2=不要在「開始」功能表中建立資料夾(&D) ; *** "Ready to Install" wizard page WizardReady=準備安裝 ReadyLabel1=安裝程式將開始安裝 [name] 到您的電腦中。 ReadyLabel2a=按下 [安裝] 繼續安裝,或按 [上一步] 重新檢視或設定各選項的內容。 ReadyLabel2b=按下 [安裝] 繼續安裝。 ReadyMemoUserInfo=使用者資訊 ReadyMemoDir=目的資料夾: ReadyMemoType=安裝型態: ReadyMemoComponents=選擇的元件: ReadyMemoGroup=「開始」功能表資料夾: ReadyMemoTasks=附加工作: ; *** "Preparing to Install" wizard page WizardPreparing=準備安裝程式 PreparingDesc=安裝程式準備將 [name] 安裝到您的電腦上。 PreviousInstallNotCompleted=先前的安裝/ 解除安裝尚未完成,您必須重新啟動電腦以完成該安裝。%n%n在重新啟動電腦之後,請再執行這個程式來安裝 [name]。 CannotContinue=安裝程式無法繼續。請按 [取消] 離開。 ApplicationsFound=下面的應用程式正在使用安裝程式所需要更新的文檔。建議您允許安裝程式自動關閉這些應用程式。 ApplicationsFound2=下面的應用程式正在使用安裝程式所需要更新的文檔。建議您允許安裝程式自動關閉這些應用程式。當安裝過程結束後,本安裝程式將會嘗試重新開啟該應用程式。 CloseApplications=關閉應用程式(&A) DontCloseApplications=不要關閉應用程式 (&D) ErrorCloseApplications=安裝程式無法自動關閉所有應用程式。建議您在繼續前先關閉所有應用程式使用的檔案。 ; *** "Installing" wizard page WizardInstalling=正在安裝 InstallingLabel=請稍候,安裝程式正在將 [name] 安裝到您的電腦上 ; *** "Setup Completed" wizard page FinishedHeadingLabel=安裝完成 FinishedLabelNoIcons=安裝程式已經將 [name] 安裝在您的電腦上。 FinishedLabel=安裝程式已經將 [name] 安裝在您的電腦中,您可以選擇程式的圖示來執行該應用程式。 ClickFinish=按 [完成] 以結束安裝程式。 FinishedRestartLabel=要完成 [name] 的安裝,安裝程式必須重新啟動您的電腦。您想要現在重新啟動電腦嗎? FinishedRestartMessage=要完成 [name] 的安裝,安裝程式必須重新啟動您的電腦。%n%n您想要現在重新啟動電腦嗎? ShowReadmeCheck=是,我要閱讀讀我檔案。 YesRadio=是,立即重新啟動電腦(&Y) NoRadio=否,我稍後重新啟動電腦(&N) ; used for example as 'Run MyProg.exe' RunEntryExec=執行 %1 ; used for example as 'View Readme.txt' RunEntryShellExec=檢視 %1 ; *** "Setup Needs the Next Disk" ChangeDiskTitle=安裝程式需要下一張磁片 SelectDiskLabel2=請插入磁片 %1,然後按 [確定]。%n%n如果檔案不在以下所顯示的資料夾之中,請輸入正確的資料夾名稱或按 [瀏覽] 選取。 PathLabel=路徑(&P): FileNotInDir2=檔案“%1”無法在“%2”找到。請插入正確的磁片或選擇其它的資料夾。 SelectDirectoryLabel=請指定下一張磁片的位置。 ; *** Installation phase messages SetupAborted=安裝沒有完成。%n%n請更正問題後重新安裝一次。 AbortRetryIgnoreSelectAction=選取動作 AbortRetryIgnoreRetry=請再試一次 (&T) AbortRetryIgnoreIgnore=略過錯誤並繼續 (&I) AbortRetryIgnoreCancel=取消安裝 ; *** Installation status messages StatusClosingApplications=正在關閉應用程式... StatusCreateDirs=正在建立資料夾... StatusExtractFiles=正在解壓縮檔案... StatusCreateIcons=正在建立程式集圖示... StatusCreateIniEntries=寫入 INI 檔案的項目... StatusCreateRegistryEntries=正在更新系統登錄... StatusRegisterFiles=正在登錄檔案... StatusSavingUninstall=儲存解除安裝資訊... StatusRunProgram=正在完成安裝... StatusRestartingApplications=正在重新開啟應用程式... StatusRollback=正在復原變更... ; *** Misc. errors ErrorInternal2=內部錯誤: %1 ErrorFunctionFailedNoCode=%1 失敗 ErrorFunctionFailed=%1 失敗;代碼 %2 ErrorFunctionFailedWithMessage=%1 失敗;代碼 %2.%n%3 ErrorExecutingProgram=無法執行檔案:%n%1 ; *** Registry errors ErrorRegOpenKey=無法開啟登錄鍵:%n%1\%2 ErrorRegCreateKey=無法建立登錄項目:%n%1\%2 ErrorRegWriteKey=無法變更登錄項目:%n%1\%2 ; *** INI errors ErrorIniEntry=在檔案“%1”建立 INI 項目錯誤。 ; *** File copying errors FileAbortRetryIgnoreSkipNotRecommended=略過這個檔案 (不建議) (&S) FileAbortRetryIgnoreIgnoreNotRecommended=略過錯誤並繼續 (不建議) (&I) SourceDoesntExist=來源檔案“%1”不存在。 SourceIsCorrupted=來源檔案已經損毀。 ExistingFileReadOnly2=無法取代現有檔案,因為檔案已標示為唯讀。 ExistingFileReadOnlyRetry=移除唯讀屬性並重試 (&R) ExistingFileReadOnlyKeepExisting=保留現有檔案 (&K) ErrorReadingExistingDest=讀取一個已存在的檔案時發生錯誤: FileExists=檔案已經存在。%n%n 要讓安裝程式加以覆寫嗎? ExistingFileNewer=存在的檔案版本比較新,建議您保留目前已存在的檔案。%n%n您要保留目前已存在的檔案嗎? ErrorChangingAttr=在變更檔案屬性時發生錯誤: ErrorCreatingTemp=在目的資料夾中建立檔案時發生錯誤: ErrorReadingSource=讀取原始檔案時發生錯誤: ErrorCopying=復制檔案時發生錯誤: ErrorReplacingExistingFile=取代檔案時發生錯誤: ErrorRestartReplace=重新啟動電腦後取代檔案失敗: ErrorRenamingTemp=在目的資料夾變更檔案名稱時發生錯誤: ErrorRegisterServer=無法注冊 DLL/OCX 檔案: %1。 ErrorRegSvr32Failed=RegSvr32 失敗;退出代碼 %1 ErrorRegisterTypeLib=無法注冊類型庫: %1。 ; *** Uninstall display name markings ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32-bit UninstallDisplayNameMark64Bit=64-bit UninstallDisplayNameMarkAllUsers=所有使用者 UninstallDisplayNameMarkCurrentUser=目前使用者 ; *** Post-installation errors ErrorOpeningReadme=開啟讀我檔案時發生錯誤。 ErrorRestartingComputer=安裝程式無法重新啟動電腦,請以手動方式自行重新啟動電腦。 ; *** Uninstaller messages UninstallNotFound=檔案“%1”不存在,無法移除程式。 UninstallOpenError=無法開啟檔案“%1”,無法移除程式。 UninstallUnsupportedVer=這個版本的解除安裝程式無法辨識記錄檔 “%1” 之格式,無法解除安裝。 UninstallUnknownEntry=解除安裝記錄檔中發現未知的記錄 (%1)。 ConfirmUninstall=您確定要完全移除 %1 及其相關的檔案嗎? UninstallOnlyOnWin64=這個程式只能在 64 位元的 Windows 上解除安裝。 OnlyAdminCanUninstall=這個程式要具備系統管理員權限的使用者方可解除安裝。 UninstallStatusLabel=正在從您的電腦移除 %1 中,請稍候... UninstalledAll=%1 已經成功從您的電腦中移除。 UninstalledMost=%1 解除安裝完成。%n%n某些檔案及元件無法移除,您可以自行刪除這些檔案。 UninstalledAndNeedsRestart=要完成 %1 的解除安裝程序,您必須重新啟動電腦。%n%n您想要現在重新啟動電腦嗎? UninstallDataCorrupted=檔案“%1”已經損毀,無法解除安裝。 ; *** Uninstallation phase messages ConfirmDeleteSharedFileTitle=移除共用檔案 ConfirmDeleteSharedFile2=系統顯示下列共用檔案已不再被任何程式所使用,您要移除這些檔案嗎?%n%n%1%n%n倘若您移除了以上檔案但仍有程式需要使用它們,將造成這些程式無法正常執行,因此您若無法確定請選擇 [否]。保留這些檔案在您的系統中不會造成任何損害。 SharedFileNameLabel=檔案名稱: SharedFileLocationLabel=位置: WizardUninstalling=解除安裝狀態 StatusUninstalling=正在解除安裝 %1... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=正在安裝 %1. ShutdownBlockReasonUninstallingApp=正在解除安裝 %1. ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1 版本 %2 AdditionalIcons=附加圖示: CreateDesktopIcon=建立桌面圖示(&D) CreateQuickLaunchIcon=建立快速啟動圖示(&Q) ProgramOnTheWeb=%1 的網站 UninstallProgram=解除安裝 %1 LaunchProgram=啟動 %1 AssocFileExtension=將 %1 與檔案副檔名 %2 產生關聯(&A) AssocingFileExtension=正在將 %1 與檔案副檔名 %2 產生關聯... AutoStartProgramGroupDescription=開啟: AutoStartProgram=自動開啟 %1 AddonHostProgramNotFound=%1 無法在您所選的資料夾中找到。%n%n您是否還要繼續? ================================================ FILE: build/win32/i18n/messages.de.isl ================================================ [CustomMessages] AddContextMenuFiles=Aktion "Mit %1 ffnen" dem Dateikontextmen von Windows-Explorer hinzufgen AddContextMenuFolders=Aktion "Mit %1 ffnen" dem Verzeichniskontextmen von Windows-Explorer hinzufgen AssociateWithFiles=%1 als Editor fr untersttzte Dateitypen registrieren AddToPath=Zu PATH hinzufgen (nach dem Neustart verfgbar) RunAfter=%1 nach der Installation ausfhren Other=Andere: SourceFile=%1-Quelldatei OpenWithCodeContextMenu=Mit %1 ffnen UpdatingVisualStudioCode=Visual Studio Code wird aktualisiert... ================================================ FILE: build/win32/i18n/messages.en.isl ================================================ [Messages] FinishedLabel=Setup has finished installing [name] on your computer. The application may be launched by selecting the installed shortcuts. ConfirmUninstall=Are you sure you want to completely remove %1 and all of its components? [CustomMessages] AdditionalIcons=Additional icons: CreateDesktopIcon=Create a &desktop icon CreateQuickLaunchIcon=Create a &Quick Launch icon AddContextMenuFiles=Add "Open with %1" action to Windows Explorer file context menu AddContextMenuFolders=Add "Open with %1" action to Windows Explorer directory context menu AssociateWithFiles=Register %1 as an editor for supported file types AddToPath=Add to PATH (requires shell restart) RunAfter=Run %1 after installation Other=Other: SourceFile=%1 Source File OpenWithCodeContextMenu=Open w&ith %1 UpdatingVisualStudioCode=Updating Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.es.isl ================================================ [CustomMessages] AddContextMenuFiles=Agregar la accin "Abrir con %1" al men contextual de archivo del Explorador de Windows AddContextMenuFolders=Agregar la accin "Abrir con %1" al men contextual de directorio del Explorador de Windows AssociateWithFiles=Registrar %1 como editor para tipos de archivo admitidos AddToPath=Agregar a PATH (disponible despus de reiniciar) RunAfter=Ejecutar %1 despus de la instalacin Other=Otros: SourceFile=Archivo de origen %1 OpenWithCodeContextMenu=Abrir &con %1 UpdatingVisualStudioCode=Actualizando Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.fr.isl ================================================ [CustomMessages] AddContextMenuFiles=Ajouter l'action "Ouvrir avec %1" au menu contextuel de fichier de l'Explorateur Windows AddContextMenuFolders=Ajouter l'action "Ouvrir avec %1" au menu contextuel de rpertoire de l'Explorateur Windows AssociateWithFiles=Inscrire %1 en tant qu'diteur pour les types de fichier pris en charge AddToPath=Ajouter PATH (disponible aprs le redmarrage) RunAfter=Excuter %1 aprs l'installation Other=Autre: SourceFile=Fichier source %1 OpenWithCodeContextMenu=Ouvrir avec %1 UpdatingVisualStudioCode=Mise jour de Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.hu.isl ================================================ [CustomMessages] AddContextMenuFiles="Megnyits a kvetkezvel: %1" parancs hozzadsa a fjlok helyi menjhez a Windows Intzben AddContextMenuFolders="Megnyits a kvetkezvel: %1" parancs hozzadsa a mappk helyi menjhez a Windows Intzben AssociateWithFiles=%1 regisztrlsa szerkesztknt a tmogatott fjltpusokhoz AddToPath=Hozzads a PATH-hoz (jraindts utn lesz elrhet) RunAfter=%1 indtsa a telepts utn Other=Egyb: SourceFile=%1 forrsfjl OpenWithCodeContextMenu=Megnyits a kvetkezvel: %1 UpdatingVisualStudioCode=A Visual Studio Code frisstse... ================================================ FILE: build/win32/i18n/messages.it.isl ================================================ [CustomMessages] AddContextMenuFiles=Aggiungi azione "Apri con %1" al menu di scelta rapida file di Esplora risorse AddContextMenuFolders=Aggiungi azione "Apri con %1" al menu di scelta rapida directory di Esplora risorse AssociateWithFiles=Registra %1 come editor per i tipi di file supportati AddToPath=Aggiungi a PATH (disponibile dopo il riavvio) RunAfter=Esegui %1 dopo l'installazione Other=Altro: SourceFile=File di origine %1 OpenWithCodeContextMenu=Apri con %1 UpdatingVisualStudioCode=Aggiornamento di Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.ja.isl ================================================ [CustomMessages] AddContextMenuFiles=GNXv[[̃t@C ReLXg j[ [%1 ŊJ] ANVlj AddContextMenuFolders=GNXv[[̃fBNg ReLXg j[ [%1 ŊJ] ANVlj AssociateWithFiles=T|[gĂt@C̎ނ̃GfB^[ƂāA%1 o^ AddToPath=PATH ւ̒ljiċNɎgp”\j RunAfter=CXg[ %1 s Other=̑: SourceFile=%1 \[X t@C OpenWithCodeContextMenu=%1 ŊJ UpdatingVisualStudioCode=Visual Studio Code XVĂ܂... ================================================ FILE: build/win32/i18n/messages.ko.isl ================================================ [CustomMessages] AddContextMenuFiles="%1() " ۾ Windows Ž Ȳ ´ ޴ ߰ AddContextMenuFolders="%1() " ۾ Windows Ž ͸ Ȳ ´ ޴ ߰ AssociateWithFiles=%1() Ǵ Ŀ մϴ. AddToPath=PATH ߰(ٽ ) RunAfter=ġ %1 Other=Ÿ: SourceFile=%1 OpenWithCodeContextMenu=%1() UpdatingVisualStudioCode=Visual Studio Code Ʈ ... ================================================ FILE: build/win32/i18n/messages.pt-br.isl ================================================ [CustomMessages] AddContextMenuFiles=Adicione a ao "Abrir com %1" ao menu de contexto de arquivo do Windows Explorer AddContextMenuFolders=Adicione a ao "Abrir com %1" ao menu de contexto de diretrio do Windows Explorer AssociateWithFiles=Registre %1 como um editor para tipos de arquivos suportados AddToPath=Adicione em PATH (disponvel aps reiniciar) RunAfter=Executar %1 aps a instalao Other=Outros: SourceFile=Arquivo Fonte %1 OpenWithCodeContextMenu=Abrir com %1 UpdatingVisualStudioCode=Atualizando o Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.ru.isl ================================================ [CustomMessages] AddContextMenuFiles= " %1" Windows AddContextMenuFolders= " %1" AssociateWithFiles= %1 AddToPath= PATH ( ) RunAfter= %1 Other=: SourceFile= %1 OpenWithCodeContextMenu= %1 UpdatingVisualStudioCode= Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.tr.isl ================================================ [CustomMessages] AddContextMenuFiles=Windows Gezgini balam mensne "%1 le A" eylemini ekle AddContextMenuFolders=Windows Gezgini dizin balam mensne "%1 le A" eylemini ekle AssociateWithFiles=%1 uygulamasn desteklenen dosya trleri iin bir dzenleyici olarak kayt et AddToPath=PATH'e ekle (yeniden balattktan sonra kullanlabilir) RunAfter=Kurulumdan sonra %1 uygulamasn altr. Other=Dier: SourceFile=%1 Kaynak Dosyas OpenWithCodeContextMenu=%1 le A UpdatingVisualStudioCode=Visual Studio Code gncelleniyor... ================================================ FILE: build/win32/i18n/messages.zh-cn.isl ================================================ [CustomMessages] AddContextMenuFiles=ͨ %1 򿪡ӵ Windows ԴļIJ˵ AddContextMenuFolders=ͨ %1 򿪡ӵ Windows ԴĿ¼IJ˵ AssociateWithFiles= %1 עΪֵ֧ļ͵ı༭ AddToPath=ӵ PATH (Ч) RunAfter=װ %1 Other=: SourceFile=%1 Դļ OpenWithCodeContextMenu=ͨ %1 UpdatingVisualStudioCode=ڸ Visual Studio Code... ================================================ FILE: build/win32/i18n/messages.zh-tw.isl ================================================ [CustomMessages] AddContextMenuFiles=N [H %1 }] ʧ@[J Windows ɮ`ɮתާ@\ AddContextMenuFolders=N [H %1 }] ʧ@[J Windows ɮ`ޥؿާ@\ AssociateWithFiles=w䴩ɮN %1 Us边 AddToPath=[J PATH (sҰʫͮ) RunAfter=w˫ %1 Other=L: SourceFile=%1 ӷɮ OpenWithCodeContextMenu=H %1 } UpdatingVisualStudioCode=bs Visual Studio Code... ================================================ FILE: cglicenses.json ================================================ // ----------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------- // This file overrides licenses only for OSS components which do not appear in `cgmanifest.json`. // i.e. for OSS components that are detected from `package-lock.json` or `Cargo.lock` files. // // DO NOT EDIT THIS FILE UNLESS THE OSS TOOL INDICATES THAT YOU SHOULD. // [ { // Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE // does not include a clear Copyright statement and does not credit authors. "name": "jschardet", "prependLicenseText": [ "Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained", " by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.", " JSChardet was ported from python to JavaScript by António Afonso ", " (https://github.com/aadsm/jschardet) and transformed into an npm package by ", "Markus Ast (https://github.com/brainafk)" ] }, { // Reason: The license at https://github.com/microsoft/TypeScript/blob/master/LICENSE.txt // does not include a clear Copyright statement. "name": "typescript", "prependLicenseText": [ "Copyright (c) Microsoft Corporation. All rights reserved." ] }, { "name": "tunnel-agent", "prependLicenseText": [ "Copyright (c) tunnel-agent authors" ] }, { // Reason: The license at https://github.com/rbuckton/reflect-metadata/blob/master/LICENSE // does not include a clear Copyright statement (it's in https://github.com/rbuckton/reflect-metadata/blob/master/CopyrightNotice.txt). "name": "reflect-metadata", "prependLicenseText": [ "Copyright (c) Microsoft Corporation. All rights reserved." ] }, { // Reason: The license cannot be found by the tool due to access controls on the repository "name": "vscode-tas-client", "fullLicenseText": [ "MIT License", "Copyright (c) 2020 - present Microsoft Corporation", "", "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." ] }, { // Reason: The license cannot be found by the tool due to access controls on the repository "name": "tas-client", "fullLicenseText": [ "MIT License", "Copyright (c) 2020 - present Microsoft Corporation", "", "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." ] }, { // Reason: The license cannot be found by the tool due to access controls on the repository "name": "tas-client-umd", "fullLicenseText": [ "MIT License", "Copyright (c) 2020 - present Microsoft Corporation", "", "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." ] }, { // Reason: Repository lacks license text. // https://github.com/tjwebb/fnv-plus/blob/master/package.json declares MIT. // https://github.com/tjwebb/fnv-plus/issues/14 "name": "@enonic/fnv-plus", "fullLicenseText": [ "MIT License", "Copyright (c) 2014 - present, Travis Webb ", "", "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." ] }, { "name": "@vscode/win32-app-container-tokens", "fullLicenseText": [ "MIT License", "", "Copyright (c) Microsoft Corporation.", "", "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" ] }, { // Reason: NPM package does not include repository URL https://github.com/microsoft/vscode-deviceid/issues/12 "name": "@vscode/deviceid", "fullLicenseText": [ "Copyright (c) Microsoft Corporation.", "", "MIT License", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { // Reason: Missing license file "name": "@tokenizer/token", "fullLicenseText": [ "(The MIT License)", "", "Copyright (c) 2020 Borewit", "", "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." ] }, { // Reason: Missing license file "name": "readable-web-to-node-stream", "fullLicenseText": [ "(The MIT License)", "", "Copyright (c) 2019 Borewit", "", "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." ] }, { // Reason: The substack org has been deleted on GH "name": "concat-map", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { // Reason: The substack org has been deleted on GH "name": "github-from-package", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { // Reason: The substack org has been deleted on GH "name": "minimist", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { // Reason: repo URI is wrong on crate, pending https://github.com/warp-tech/russh/pull/53 "name": "russh-cryptovec", "fullLicenseTextUri": "https://raw.githubusercontent.com/warp-tech/russh/1da80d0d599b6ee2d257c544c0d6af4f649c9029/LICENSE-2.0.txt" }, { // Reason: repo URI is wrong on crate, pending https://github.com/warp-tech/russh/pull/53 "name": "russh-keys", "fullLicenseTextUri": "https://raw.githubusercontent.com/warp-tech/russh/1da80d0d599b6ee2d257c544c0d6af4f649c9029/LICENSE-2.0.txt" }, { // Reason: license is in a subdirectory in repo "name": "dirs-next", "fullLicenseTextUri": "https://raw.githubusercontent.com/xdg-rs/dirs/af4aa39daba0ac68e222962a5aca17360158b7cc/dirs/LICENSE-MIT" }, { // Reason: license is in a subdirectory in repo "name": "openssl", "fullLicenseTextUri": "https://raw.githubusercontent.com/sfackler/rust-openssl/e43eb58540b27a17f8029c397e3edc12bbc9011f/openssl/LICENSE" }, { // Reason: license is in a subdirectory in repo "name": "openssl-sys", "fullLicenseTextUri": "https://raw.githubusercontent.com/sfackler/rust-openssl/e43eb58540b27a17f8029c397e3edc12bbc9011f/openssl-sys/LICENSE-MIT" }, { // Reason: Missing license file "name": "openssl-macros", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { // Reason: Missing license file "name": "const_format_proc_macros", "fullLicenseTextUri": "https://raw.githubusercontent.com/rodrimati1992/const_format_crates/b2207af46bfbd9f1a6bd12dbffd10feeea3d9fd7/LICENSE-ZLIB.md" }, { // Reason: Missing license file "name": "const_format", "fullLicenseTextUri": "https://raw.githubusercontent.com/rodrimati1992/const_format_crates/b2207af46bfbd9f1a6bd12dbffd10feeea3d9fd7/LICENSE-ZLIB.md" }, { // License is MIT/Apache and tool doesn't look in subfolders "name": "toml_edit", "fullLicenseTextUri": "https://raw.githubusercontent.com/toml-rs/toml/main/crates/toml_edit/LICENSE-MIT" }, { // License is MIT/Apache and tool doesn't look in subfolders "name": "toml_datetime", "fullLicenseTextUri": "https://raw.githubusercontent.com/toml-rs/toml/main/crates/toml_datetime/LICENSE-MIT" }, { // License is MIT/Apache and tool doesn't look in subfolders "name": "dirs-sys-next", "fullLicenseTextUri": "https://raw.githubusercontent.com/xdg-rs/dirs/master/dirs-sys/LICENSE-MIT" }, { // License is MIT/Apache and gitlab API doesn't find the project "name": "libredox", "fullLicenseTextUri": "https://gitlab.redox-os.org/redox-os/libredox/-/raw/master/LICENSE" }, { "name": "https-proxy-agent", "fullLicenseText": [ "(The MIT License)", "Copyright (c) 2013 Nathan Rajlich ", "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." ] }, { "name": "data-uri-to-buffer", "fullLicenseText": [ "(The MIT License)", "Copyright (c) 2014 Nathan Rajlich ", "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." ] }, { "name": "socks-proxy-agent", "fullLicenseText": [ "(The MIT License)", "Copyright (c) 2013 Nathan Rajlich ", "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." ] }, { "name": "http-proxy-agent", "fullLicenseText": [ "(The MIT License)", "Copyright (c) 2013 Nathan Rajlich ", "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." ] }, { "name": "agent-base", "fullLicenseText": [ "(The MIT License)", "Copyright (c) 2013 Nathan Rajlich ", "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." ] }, { "name": "anstyle", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "anstyle-query", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "anstyle-parse", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "anstyle-wincon", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "anstream", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "colorchoice", "fullLicenseText": [ "This software is released under the MIT license:", "", "Permission is hereby granted, free of charge, to any person obtaining a copy of", "this software and associated documentation files (the \"Software\"), to deal in", "the Software without restriction, including without limitation the rights to", "use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of", "the Software, and to permit persons to whom the Software is furnished to do so,", "subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in all", "copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS", "FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR", "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER", "IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN", "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "name": "cacheable-request", "prependLicenseText": [ "Copyright (c) cacheable-request authors" ] }, { "name": "@vscode/ts-package-manager", "fullLicenseText": [ "MIT License", "", "Copyright (c) Microsoft Corporation.", "", "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" ] }, { "name":"vscode-markdown-languageserver", "fullLicenseText": [ "MIT License", "", "Copyright (c) Microsoft Corporation.", "", "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" ] }, { // Reason: mono-repo where the individual packages are also dual-licensed under MIT and Apache-2.0 "name": "system-configuration", "fullLicenseTextUri": "https://raw.githubusercontent.com/mullvad/system-configuration-rs/v0.6.0/system-configuration/LICENSE-MIT" }, { // Reason: mono-repo where the individual packages are also dual-licensed under MIT and Apache-2.0 "name": "system-configuration-sys", "fullLicenseTextUri": "https://raw.githubusercontent.com/mullvad/system-configuration-rs/v0.6.0/system-configuration-sys/LICENSE-MIT" }, { // Reason: License missing from the repository https://github.com/isaacs/chownr/issues/35 "name": "chownr", "fullLicenseText": [ "The ISC License", "Copyright (c) Isaac Z. Schlueter and Contributors", "Permission to use, copy, modify, and/or distribute this software for any", "purpose with or without fee is hereby granted, provided that the above", "copyright notice and this permission notice appear in all copies.", "THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES", "WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF", "MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR", "ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES", "WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN", "ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR", "IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE." ] }, { "name": "@azure/msal-node-runtime", "fullLicenseText": [ "MIT License", "", "Copyright (c) Microsoft Corporation. All rights reserved.", "", "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" ] } ] ================================================ FILE: cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", "commitHash": "5c0cb964bca15fcf41718d54f4b8d70d6b9079de" } }, "licenseDetail": [ "BSD License", "", "Copyright 2015 The Chromium Authors. All rights reserved.", "", "Redistribution and use in source and binary forms, with or without modification,", "are permitted provided that the following conditions are met:", "", " * Redistributions of source code must retain the above copyright notice, this", " list of conditions and the following disclaimer.", "", " * Redistributions in binary form must reproduce the above copyright notice,", " this list of conditions and the following disclaimer in the documentation", " and/or other materials provided with the distribution.", "", " * Neither the name Google Inc. nor the names of its contributors may be used to", " endorse or promote products derived from this software without specific", " prior written permission.", "", "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND", "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED", "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR", "ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES", "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;", "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS", "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, "version": "132.0.6834.210" }, { "component": { "type": "git", "git": { "name": "ffmpeg", "repositoryUrl": "https://chromium.googlesource.com/chromium/third_party/ffmpeg", "commitHash": "092f84b6141055bfab609b6b2666b724eee2e130" } }, "isOnlyProductionDependency": true, "license": "LGPL-2.1+", "version": "5.1.git", "licenseDetail": [ " GNU LESSER GENERAL PUBLIC LICENSE", " Version 2.1, February 1999", " Copyright (C) 1991, 1999 Free Software Foundation, Inc.", " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA", " Everyone is permitted to copy and distribute verbatim copies", " of this license document, but changing it is not allowed.", "[This is the first released version of the Lesser GPL. It also counts", " as the successor of the GNU Library Public License, version 2, hence", " the version number 2.1.]", " Preamble", " The licenses for most software are designed to take away your", "freedom to share and change it. By contrast, the GNU General Public", "Licenses are intended to guarantee your freedom to share and change", "free software--to make sure the software is free for all its users.", " This license, the Lesser General Public License, applies to some", "specially designated software packages--typically libraries--of the", "Free Software Foundation and other authors who decide to use it. You", "can use it too, but we suggest you first think carefully about whether", "this license or the ordinary General Public License is the better", "strategy to use in any particular case, based on the explanations below.", " When we speak of free software, we are referring to freedom of use,", "not price. Our General Public Licenses are designed to make sure that", "you have the freedom to distribute copies of free software (and charge", "for this service if you wish); that you receive source code or can get", "it if you want it; that you can change the software and use pieces of", "it in new free programs; and that you are informed that you can do", "these things.", " To protect your rights, we need to make restrictions that forbid", "distributors to deny you these rights or to ask you to surrender these", "rights. These restrictions translate to certain responsibilities for", "you if you distribute copies of the library or if you modify it.", " For example, if you distribute copies of the library, whether gratis", "or for a fee, you must give the recipients all the rights that we gave", "you. You must make sure that they, too, receive or can get the source", "code. If you link other code with the library, you must provide", "complete object files to the recipients, so that they can relink them", "with the library after making changes to the library and recompiling", "it. And you must show them these terms so they know their rights.", " We protect your rights with a two-step method: (1) we copyright the", "library, and (2) we offer you this license, which gives you legal", "permission to copy, distribute and/or modify the library.", " To protect each distributor, we want to make it very clear that", "there is no warranty for the free library. Also, if the library is", "modified by someone else and passed on, the recipients should know", "that what they have is not the original version, so that the original", "author's reputation will not be affected by problems that might be", "introduced by others.", "", " Finally, software patents pose a constant threat to the existence of", "any free program. We wish to make sure that a company cannot", "effectively restrict the users of a free program by obtaining a", "restrictive license from a patent holder. Therefore, we insist that", "any patent license obtained for a version of the library must be", "consistent with the full freedom of use specified in this license.", " Most GNU software, including some libraries, is covered by the", "ordinary GNU General Public License. This license, the GNU Lesser", "General Public License, applies to certain designated libraries, and", "is quite different from the ordinary General Public License. We use", "this license for certain libraries in order to permit linking those", "libraries into non-free programs.", " When a program is linked with a library, whether statically or using", "a shared library, the combination of the two is legally speaking a", "combined work, a derivative of the original library. The ordinary", "General Public License therefore permits such linking only if the", "entire combination fits its criteria of freedom. The Lesser General", "Public License permits more lax criteria for linking other code with", "the library.", " We call this license the \"Lesser\" General Public License because it", "does Less to protect the user's freedom than the ordinary General", "Public License. It also provides other free software developers Less", "of an advantage over competing non-free programs. These disadvantages", "are the reason we use the ordinary General Public License for many", "libraries. However, the Lesser license provides advantages in certain", "special circumstances.", " For example, on rare occasions, there may be a special need to", "encourage the widest possible use of a certain library, so that it becomes", "a de-facto standard. To achieve this, non-free programs must be", "allowed to use the library. A more frequent case is that a free", "library does the same job as widely used non-free libraries. In this", "case, there is little to gain by limiting the free library to free", "software only, so we use the Lesser General Public License.", " In other cases, permission to use a particular library in non-free", "programs enables a greater number of people to use a large body of", "free software. For example, permission to use the GNU C Library in", "non-free programs enables many more people to use the whole GNU", "operating system, as well as its variant, the GNU/Linux operating", "system.", " Although the Lesser General Public License is Less protective of the", "users' freedom, it does ensure that the user of a program that is", "linked with the Library has the freedom and the wherewithal to run", "that program using a modified version of the Library.", " The precise terms and conditions for copying, distribution and", "modification follow. Pay close attention to the difference between a", "\"work based on the library\" and a \"work that uses the library\". The", "former contains code derived from the library, whereas the latter must", "be combined with the library in order to run.", "", " GNU LESSER GENERAL PUBLIC LICENSE", " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", " 0. This License Agreement applies to any software library or other", "program which contains a notice placed by the copyright holder or", "other authorized party saying it may be distributed under the terms of", "this Lesser General Public License (also called \"this License\").", "Each licensee is addressed as \"you\".", " A \"library\" means a collection of software functions and/or data", "prepared so as to be conveniently linked with application programs", "(which use some of those functions and data) to form executables.", " The \"Library\", below, refers to any such software library or work", "which has been distributed under these terms. A \"work based on the", "Library\" means either the Library or any derivative work under", "copyright law: that is to say, a work containing the Library or a", "portion of it, either verbatim or with modifications and/or translated", "straightforwardly into another language. (Hereinafter, translation is", "included without limitation in the term \"modification\".)", " \"Source code\" for a work means the preferred form of the work for", "making modifications to it. For a library, complete source code means", "all the source code for all modules it contains, plus any associated", "interface definition files, plus the scripts used to control compilation", "and installation of the library.", " Activities other than copying, distribution and modification are not", "covered by this License; they are outside its scope. The act of", "running a program using the Library is not restricted, and output from", "such a program is covered only if its contents constitute a work based", "on the Library (independent of the use of the Library in a tool for", "writing it). Whether that is true depends on what the Library does", "and what the program that uses the Library does.", " 1. You may copy and distribute verbatim copies of the Library's", "complete source code as you receive it, in any medium, provided that", "you conspicuously and appropriately publish on each copy an", "appropriate copyright notice and disclaimer of warranty; keep intact", "all the notices that refer to this License and to the absence of any", "warranty; and distribute a copy of this License along with the", "Library.", " You may charge a fee for the physical act of transferring a copy,", "and you may at your option offer warranty protection in exchange for a", "fee.", "", " 2. You may modify your copy or copies of the Library or any portion", "of it, thus forming a work based on the Library, and copy and", "distribute such modifications or work under the terms of Section 1", "above, provided that you also meet all of these conditions:", " a) The modified work must itself be a software library.", " b) You must cause the files modified to carry prominent notices", " stating that you changed the files and the date of any change.", " c) You must cause the whole of the work to be licensed at no", " charge to all third parties under the terms of this License.", " d) If a facility in the modified Library refers to a function or a", " table of data to be supplied by an application program that uses", " the facility, other than as an argument passed when the facility", " is invoked, then you must make a good faith effort to ensure that,", " in the event an application does not supply such function or", " table, the facility still operates, and performs whatever part of", " its purpose remains meaningful.", " (For example, a function in a library to compute square roots has", " a purpose that is entirely well-defined independent of the", " application. Therefore, Subsection 2d requires that any", " application-supplied function or table used by this function must", " be optional: if the application does not supply it, the square", " root function must still compute square roots.)", "These requirements apply to the modified work as a whole. If", "identifiable sections of that work are not derived from the Library,", "and can be reasonably considered independent and separate works in", "themselves, then this License, and its terms, do not apply to those", "sections when you distribute them as separate works. But when you", "distribute the same sections as part of a whole which is a work based", "on the Library, the distribution of the whole must be on the terms of", "this License, whose permissions for other licensees extend to the", "entire whole, and thus to each and every part regardless of who wrote", "it.", "Thus, it is not the intent of this section to claim rights or contest", "your rights to work written entirely by you; rather, the intent is to", "exercise the right to control the distribution of derivative or", "collective works based on the Library.", "In addition, mere aggregation of another work not based on the Library", "with the Library (or with a work based on the Library) on a volume of", "a storage or distribution medium does not bring the other work under", "the scope of this License.", " 3. You may opt to apply the terms of the ordinary GNU General Public", "License instead of this License to a given copy of the Library. To do", "this, you must alter all the notices that refer to this License, so", "that they refer to the ordinary GNU General Public License, version 2,", "instead of to this License. (If a newer version than version 2 of the", "ordinary GNU General Public License has appeared, then you can specify", "that version instead if you wish.) Do not make any other change in", "these notices.", "", " Once this change is made in a given copy, it is irreversible for", "that copy, so the ordinary GNU General Public License applies to all", "subsequent copies and derivative works made from that copy.", " This option is useful when you wish to copy part of the code of", "the Library into a program that is not a library.", " 4. You may copy and distribute the Library (or a portion or", "derivative of it, under Section 2) in object code or executable form", "under the terms of Sections 1 and 2 above provided that you accompany", "it with the complete corresponding machine-readable source code, which", "must be distributed under the terms of Sections 1 and 2 above on a", "medium customarily used for software interchange.", " If distribution of object code is made by offering access to copy", "from a designated place, then offering equivalent access to copy the", "source code from the same place satisfies the requirement to", "distribute the source code, even though third parties are not", "compelled to copy the source along with the object code.", " 5. A program that contains no derivative of any portion of the", "Library, but is designed to work with the Library by being compiled or", "linked with it, is called a \"work that uses the Library\". Such a", "work, in isolation, is not a derivative work of the Library, and", "therefore falls outside the scope of this License.", " However, linking a \"work that uses the Library\" with the Library", "creates an executable that is a derivative of the Library (because it", "contains portions of the Library), rather than a \"work that uses the", "library\". The executable is therefore covered by this License.", "Section 6 states terms for distribution of such executables.", " When a \"work that uses the Library\" uses material from a header file", "that is part of the Library, the object code for the work may be a", "derivative work of the Library even though the source code is not.", "Whether this is true is especially significant if the work can be", "linked without the Library, or if the work is itself a library. The", "threshold for this to be true is not precisely defined by law.", " If such an object file uses only numerical parameters, data", "structure layouts and accessors, and small macros and small inline", "functions (ten lines or less in length), then the use of the object", "file is unrestricted, regardless of whether it is legally a derivative", "work. (Executables containing this object code plus portions of the", "Library will still fall under Section 6.)", " Otherwise, if the work is a derivative of the Library, you may", "distribute the object code for the work under the terms of Section 6.", "Any executables containing that work also fall under Section 6,", "whether or not they are linked directly with the Library itself.", "", " 6. As an exception to the Sections above, you may also combine or", "link a \"work that uses the Library\" with the Library to produce a", "work containing portions of the Library, and distribute that work", "under terms of your choice, provided that the terms permit", "modification of the work for the customer's own use and reverse", "engineering for debugging such modifications.", " You must give prominent notice with each copy of the work that the", "Library is used in it and that the Library and its use are covered by", "this License. You must supply a copy of this License. If the work", "during execution displays copyright notices, you must include the", "copyright notice for the Library among them, as well as a reference", "directing the user to the copy of this License. Also, you must do one", "of these things:", " a) Accompany the work with the complete corresponding", " machine-readable source code for the Library including whatever", " changes were used in the work (which must be distributed under", " Sections 1 and 2 above); and, if the work is an executable linked", " with the Library, with the complete machine-readable \"work that", " uses the Library\", as object code and/or source code, so that the", " user can modify the Library and then relink to produce a modified", " executable containing the modified Library. (It is understood", " that the user who changes the contents of definitions files in the", " Library will not necessarily be able to recompile the application", " to use the modified definitions.)", " b) Use a suitable shared library mechanism for linking with the", " Library. A suitable mechanism is one that (1) uses at run time a", " copy of the library already present on the user's computer system,", " rather than copying library functions into the executable, and (2)", " will operate properly with a modified version of the library, if", " the user installs one, as long as the modified version is", " interface-compatible with the version that the work was made with.", " c) Accompany the work with a written offer, valid for at", " least three years, to give the same user the materials", " specified in Subsection 6a, above, for a charge no more", " than the cost of performing this distribution.", " d) If distribution of the work is made by offering access to copy", " from a designated place, offer equivalent access to copy the above", " specified materials from the same place.", " e) Verify that the user has already received a copy of these", " materials or that you have already sent this user a copy.", " For an executable, the required form of the \"work that uses the", "Library\" must include any data and utility programs needed for", "reproducing the executable from it. However, as a special exception,", "the materials to be distributed need not include anything that is", "normally distributed (in either source or binary form) with the major", "components (compiler, kernel, and so on) of the operating system on", "which the executable runs, unless that component itself accompanies", "the executable.", " It may happen that this requirement contradicts the license", "restrictions of other proprietary libraries that do not normally", "accompany the operating system. Such a contradiction means you cannot", "use both them and the Library together in an executable that you", "distribute.", "", " 7. You may place library facilities that are a work based on the", "Library side-by-side in a single library together with other library", "facilities not covered by this License, and distribute such a combined", "library, provided that the separate distribution of the work based on", "the Library and of the other library facilities is otherwise", "permitted, and provided that you do these two things:", " a) Accompany the combined library with a copy of the same work", " based on the Library, uncombined with any other library", " facilities. This must be distributed under the terms of the", " Sections above.", " b) Give prominent notice with the combined library of the fact", " that part of it is a work based on the Library, and explaining", " where to find the accompanying uncombined form of the same work.", " 8. You may not copy, modify, sublicense, link with, or distribute", "the Library except as expressly provided under this License. Any", "attempt otherwise to copy, modify, sublicense, link with, or", "distribute the Library is void, and will automatically terminate your", "rights under this License. However, parties who have received copies,", "or rights, from you under this License will not have their licenses", "terminated so long as such parties remain in full compliance.", " 9. You are not required to accept this License, since you have not", "signed it. However, nothing else grants you permission to modify or", "distribute the Library or its derivative works. These actions are", "prohibited by law if you do not accept this License. Therefore, by", "modifying or distributing the Library (or any work based on the", "Library), you indicate your acceptance of this License to do so, and", "all its terms and conditions for copying, distributing or modifying", "the Library or works based on it.", " 10. Each time you redistribute the Library (or any work based on the", "Library), the recipient automatically receives a license from the", "original licensor to copy, distribute, link with or modify the Library", "subject to these terms and conditions. You may not impose any further", "restrictions on the recipients' exercise of the rights granted herein.", "You are not responsible for enforcing compliance by third parties with", "this License.", "", " 11. If, as a consequence of a court judgment or allegation of patent", "infringement or for any other reason (not limited to patent issues),", "conditions are imposed on you (whether by court order, agreement or", "otherwise) that contradict the conditions of this License, they do not", "excuse you from the conditions of this License. If you cannot", "distribute so as to satisfy simultaneously your obligations under this", "License and any other pertinent obligations, then as a consequence you", "may not distribute the Library at all. For example, if a patent", "license would not permit royalty-free redistribution of the Library by", "all those who receive copies directly or indirectly through you, then", "the only way you could satisfy both it and this License would be to", "refrain entirely from distribution of the Library.", "If any portion of this section is held invalid or unenforceable under any", "particular circumstance, the balance of the section is intended to apply,", "and the section as a whole is intended to apply in other circumstances.", "It is not the purpose of this section to induce you to infringe any", "patents or other property right claims or to contest validity of any", "such claims; this section has the sole purpose of protecting the", "integrity of the free software distribution system which is", "implemented by public license practices. Many people have made", "generous contributions to the wide range of software distributed", "through that system in reliance on consistent application of that", "system; it is up to the author/donor to decide if he or she is willing", "to distribute software through any other system and a licensee cannot", "impose that choice.", "This section is intended to make thoroughly clear what is believed to", "be a consequence of the rest of this License.", " 12. If the distribution and/or use of the Library is restricted in", "certain countries either by patents or by copyrighted interfaces, the", "original copyright holder who places the Library under this License may add", "an explicit geographical distribution limitation excluding those countries,", "so that distribution is permitted only in or among countries not thus", "excluded. In such case, this License incorporates the limitation as if", "written in the body of this License.", " 13. The Free Software Foundation may publish revised and/or new", "versions of the Lesser General Public License from time to time.", "Such new versions will be similar in spirit to the present version,", "but may differ in detail to address new problems or concerns.", "Each version is given a distinguishing version number. If the Library", "specifies a version number of this License which applies to it and", "\"any later version\", you have the option of following the terms and", "conditions either of that version or of any later version published by", "the Free Software Foundation. If the Library does not specify a", "license version number, you may choose any version ever published by", "the Free Software Foundation.", "", " 14. If you wish to incorporate parts of the Library into other free", "programs whose distribution conditions are incompatible with these,", "write to the author to ask for permission. For software which is", "copyrighted by the Free Software Foundation, write to the Free", "Software Foundation; we sometimes make exceptions for this. Our", "decision will be guided by the two goals of preserving the free status", "of all derivatives of our free software and of promoting the sharing", "and reuse of software generally.", " NO WARRANTY", " 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO", "WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.", "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR", "OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY", "KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE", "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE", "LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME", "THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", " 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN", "WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY", "AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU", "FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR", "CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE", "LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING", "RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A", "FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF", "SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH", "DAMAGES.", " END OF TERMS AND CONDITIONS", "", " How to Apply These Terms to Your New Libraries", " If you develop a new library, and you want it to be of the greatest", "possible use to the public, we recommend making it free software that", "everyone can redistribute and change. You can do so by permitting", "redistribution under these terms (or, alternatively, under the terms of the", "ordinary General Public License).", " To apply these terms, attach the following notices to the library. It is", "safest to attach them to the start of each source file to most effectively", "convey the exclusion of warranty; and each file should have at least the", "\"copyright\" line and a pointer to where the full notice is found.", " ", " Copyright (C) ", " This library is free software; you can redistribute it and/or", " modify it under the terms of the GNU Lesser General Public", " License as published by the Free Software Foundation; either", " version 2.1 of the License, or (at your option) any later version.", " This library is distributed in the hope that it will be useful,", " but WITHOUT ANY WARRANTY; without even the implied warranty of", " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU", " Lesser General Public License for more details.", " You should have received a copy of the GNU Lesser General Public", " License along with this library; if not, write to the Free Software", " Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA", "Also add information on how to contact you by electronic and paper mail.", "You should also get your employer (if you work as a programmer) or your", "school, if any, to sign a \"copyright disclaimer\" for the library, if", "necessary. Here is a sample; alter the names:", " Yoyodyne, Inc., hereby disclaims all copyright interest in the", " library `Frob' (a library for tweaking knobs) written by James Random Hacker.", " , 1 April 1990", " Ty Coon, President of Vice", "That's all there is to it!" ] }, { "component": { "type": "other", "other": { "name": "H.264/AVC Video Standard", "downloadUrl": "https://chromium.googlesource.com/chromium/third_party/ffmpeg", "version": "5.1.git" } }, "licenseDetail": [ "This product is licensed under the AVC patent portfolio license for the personal", "and non-commercial use of a consumer to (i) encode video in compliance with the AVC standard (\"AVC VIDEO\")", "and/or (ii) decode AVC video that was encoded by a consumer", "engaged in a personal and non-commercial activity and/or was obtained from a video provider", "licensed to provide AVC video. No license is granted or shall be implied for any other use.", "Additional information may be obtained from MPEG LA LLC. See http://www.MPEGLA.COM.", "", "For clarification purposes, this notice does not limit or inhibit the use of the product", "for normal business uses that are personal to that business which do not include", "(i) redistribution of the product to third parties, or", "(ii) creation of content with AVC Standard compliant technologies for distribution to third parties." ], "version": "H.264 (08/21)", "isOnlyProductionDependency": true, "license": "OTHER" }, { "component": { "type": "git", "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", "commitHash": "4819c99baa28bf2c1baf411ba100c467fec3d486" } }, "isOnlyProductionDependency": true, "version": "20.18.3" }, { "component": { "type": "git", "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", "commitHash": "f98501308a973e0aee2414315b426e5de2c03a60" } }, "isOnlyProductionDependency": true, "license": "MIT", "version": "34.3.2" }, { "component": { "type": "git", "git": { "name": "inno setup", "repositoryUrl": "https://github.com/jrsoftware/issrc", "commitHash": "03fe8f4edb3e96c7835c9483052625bbedb160f2" } }, "isOnlyProductionDependency": true, "licenseDetail": [ "Inno Setup License", "==================", "", "Except where otherwise noted, all of the documentation and software included in the Inno Setup", "package is copyrighted by Jordan Russell.", "", "Copyright (C) 1997-2020 Jordan Russell. All rights reserved.", "Portions Copyright (C) 2000-2020 Martijn Laan. All rights reserved.", "", "This software is provided \"as-is,\" without any express or implied warranty. In no event shall the", "author be held liable for any damages arising from the use of this software.", "", "Permission is granted to anyone to use this software for any purpose, including commercial", "applications, and to alter and redistribute it, provided that the following conditions are met:", "", "1. All redistributions of source code files must retain all copyright notices that are currently in", " place, and this list of conditions without modification.", "", "2. All redistributions in binary form must retain all occurrences of the above copyright notice and", " web site addresses that are currently in place (for example, in the About boxes).", "", "3. The origin of this software must not be misrepresented; you must not claim that you wrote the", " original software. If you use this software to distribute a product, an acknowledgment in the", " product documentation would be appreciated but is not required.", "", "4. Modified versions in source or binary form must be plainly marked as such, and must not be", " misrepresented as being the original software.", "", "", "Jordan Russell", "jr-2010 AT jrsoftware.org", "https://jrsoftware.org/" ], "version": "5.5.6" }, { "component": { "type": "git", "git": { "name": "spdlog original", "repositoryUrl": "https://github.com/gabime/spdlog", "commitHash": "4fba14c79f356ae48d6141c561bf9fd7ba33fabd" } }, "isOnlyProductionDependency": true, "license": "MIT", "version": "0.14.0" }, { "component": { "type": "git", "git": { "name": "vscode-codicons", "repositoryUrl": "https://github.com/microsoft/vscode-codicons", "commitHash": "ccdcf91d57d3a5a1d6b620d95d518bab4d75984d" } }, "license": "MIT and Creative Commons Attribution 4.0", "version": "0.0.14" }, { "component": { "type": "npm", "npm": { "name": "mdn-data", "version": "2.0.31" } }, "isOnlyProductionDependency": true, "repositoryUrl": "https://github.com/mdn/data" }, { "component": { "type": "npm", "npm": { "name": "@mdn/browser-compat-data", "version": "5.2.45" } }, "isOnlyProductionDependency": true, "repositoryUrl": "https://github.com/mdn/browser-compat-data" }, { "component": { "type": "git", "git": { "name": "ripgrep", "repositoryUrl": "https://github.com/BurntSushi/ripgrep", "commitHash": "973de50c9ef451da2cfcdfa86f2b2711d8d6ff48" } }, "isOnlyProductionDependency": true, "license": "MIT", "version": "0.10.0" }, { "name": "@vscode/win32-app-container-tokens", "component": { "type": "git", "git": { "name": "vscode-win32-app-container-tokens", "repositoryUrl": "https://github.com/microsoft/vscode-win32-app-container-tokens", "commitHash": "5b871f95fd9cb8efa8ee9a80600510d5e5339137" } }, "licenseDetail": [ "MIT License", "", "Copyright (c) Microsoft Corporation.", "", "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" ] }, { "component": { "type": "npm", "npm": { "name": "@iktakahiro/markdown-it-katex", "version": "4.0.2" } }, "repositoryUrl": "https://github.com/mjbvz/markdown-it-katex", "licenseDetail": [ "The MIT License (MIT)", "", "Copyright (c) 2016 Waylon Flinn", "", "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.", "", "---", "", "The MIT License (MIT)", "", "Copyright (c) 2018 Takahiro Ethan Ikeuchi @iktakahiro", "", "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." ], "license": "MIT" }, { "component": { "type": "npm", "npm": { "name": "cacheable-request", "version": "7.0.4" } }, "licenseDetail": [ "Copyright (c) cacheable-request authors", "", "MIT License", "", "Permission is hereby granted, free of charge, to any person obtaining a copy", "of this software and associated documentation files (the \"Software\"), to", "deal in the Software without restriction, including without limitation the", "rights to use, copy, modify, merge, publish, distribute, sublicense, and/or", "sell copies of the Software, and to permit persons to whom the Software is", "furnished to do so, subject to the following conditions:", "", "The above copyright notice and this permission notice shall be included in", "all copies or substantial portions of the Software.", "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", "FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER", "DEALINGS IN THE SOFTWARE." ], "license": "MIT" } ], "version": 1 } ================================================ FILE: cli/.cargo/config.toml ================================================ [target.'cfg(all(target_os = "windows", any(target_arch = "i686", target_arch = "x86_64", target_arch = "x86")))'] rustflags = ["-Ctarget-feature=+crt-static", "-Clink-args=/guard:cf", "-Clink-args=/CETCOMPAT"] # CETCOMPAT is not supported on ARM binaries [target.'cfg(all(target_os = "windows", not(any(target_arch = "i686", target_arch = "x86_64", target_arch = "x86"))))'] rustflags = ["-Ctarget-feature=+crt-static", "-Clink-args=/guard:cf"] ================================================ FILE: cli/CONTRIBUTING.md ================================================ # Setup 0. Clone, and then run `git submodule update --init --recursive` 1. Get the extensions: [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) and [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) 2. Ensure your workspace is set to the `launcher` folder being the root. ## Building the CLI on Windows For the moment, we require OpenSSL on Windows, where it is not usually installed by default. To install it: 1. Follow steps 1 and 2 of [Set up vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started-msbuild?pivots=shell-powershell#1---set-up-vcpkg) to obtain the executable. 1. Add the location of the `vcpkg` directory to your system or user PATH. 1. Run`vcpkg install openssl:x64-windows-static-md` (after restarting your terminal for PATH changes to apply) 1. You should be able to then `cargo build` successfully OpenSSL is needed for the key exchange we do when forwarding Basis tunnels. When all interested Basis clients support ED25519, we would be able to solely use libsodium. At the time of writing however, there is [no active development](https://chromestatus.com/feature/4913922408710144) on this in Chromium. # Debug 1. You can use the Debug tasks already configured to run the launcher. ================================================ FILE: cli/Cargo.toml ================================================ [package] name = "code-cli" version = "0.1.0" edition = "2021" default-run = "code" [lib] name = "cli" path = "src/lib.rs" [[bin]] name = "code" [dependencies] futures = "0.3.28" clap = { version = "4.3.0", features = ["derive", "env"] } open = "4.1.0" reqwest = { version = "0.11.22", default-features = false, features = ["json", "stream", "native-tls"] } tokio = { version = "1.28.2", features = ["full"] } tokio-util = { version = "0.7.8", features = ["compat", "codec"] } flate2 = { version = "1.0.26", default-features = false, features = ["zlib"] } zip = { version = "0.6.6", default-features = false, features = ["time", "deflate-zlib"] } regex = "1.8.3" lazy_static = "1.4.0" sysinfo = { version = "0.29.0", default-features = false } serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.96" rmp-serde = "1.1.1" uuid = { version = "1.4", features = ["serde", "v4"] } dirs = "5.0.1" rand = "0.8.5" opentelemetry = { version = "0.19.0", features = ["rt-tokio"] } serde_bytes = "0.11.9" chrono = { version = "0.4.26", features = ["serde", "std", "clock"], default-features = false } gethostname = "0.4.3" libc = "0.2.144" tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "8cae9b2a24c65c6c1958f5a0e77d72b23b5c6c30", default-features = false, features = ["connections"] } keyring = { version = "2.0.3", default-features = false, features = ["linux-secret-service-rt-tokio-crypto-openssl", "platform-windows", "platform-macos", "linux-keyutils"] } dialoguer = "0.10.4" hyper = { version = "0.14.26", features = ["server", "http1", "runtime"] } indicatif = "0.17.4" tempfile = "3.5.0" clap_lex = "0.7.0" url = "2.5.4" async-trait = "0.1.68" log = "0.4.18" const_format = "0.2.31" sha2 = "0.10.6" base64 = "0.21.2" shell-escape = "0.1.5" thiserror = "1.0.40" cfg-if = "1.0.0" pin-project = "1.1.0" console = "0.15.7" bytes = "1.4.0" tar = "0.4.38" [build-dependencies] serde = { version="1.0.163", features = ["derive"] } serde_json = "1.0.96" [target.'cfg(windows)'.dependencies] winreg = "0.50.0" winapi = "0.3.9" [target.'cfg(target_os = "macos")'.dependencies] core-foundation = "0.9.3" [target.'cfg(target_os = "linux")'.dependencies] zbus = { version = "3.13.1", default-features = false, features = ["tokio"] } [patch.crates-io] russh = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } russh-cryptovec = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } russh-keys = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } [profile.release] strip = true lto = true codegen-units = 1 [features] default = [] vsda = [] vscode-encrypt = [] ================================================ FILE: cli/ThirdPartyNotices.txt ================================================ NOTICES AND INFORMATION Do Not Translate or Localize This software incorporates material from third parties. Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com, or you may send a check or money order for US $5.00, including the product name, the open source component name, platform, and version number, to: Source Code Compliance Team Microsoft Corporation One Microsoft Way Redmond, WA 98052 USA Notwithstanding any other terms, you may reverse engineer this software to the extent required to debug changes to any libraries licensed under the GNU Lesser General Public License. --------------------------------------------------------- addr2line 0.21.0 - Apache-2.0 OR MIT https://github.com/gimli-rs/addr2line Licensed under either of * Apache License, Version 2.0 ([`LICENSE-APACHE`](./LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) * MIT license ([`LICENSE-MIT`](./LICENSE-MIT) or https://opensource.org/licenses/MIT) at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- adler 1.0.2 - 0BSD OR MIT OR Apache-2.0 https://github.com/jonas-schievink/adler 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. --------------------------------------------------------- --------------------------------------------------------- aho-corasick 1.1.3 - Unlicense OR MIT https://github.com/BurntSushi/aho-corasick The MIT License (MIT) Copyright (c) 2015 Andrew Gallant 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. --------------------------------------------------------- --------------------------------------------------------- android-tzdata 0.1.1 - MIT OR Apache-2.0 https://github.com/RumovZ/android-tzdata MIT License Copyright (c) [year] [fullname] 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. --------------------------------------------------------- --------------------------------------------------------- android_system_properties 0.1.5 - MIT/Apache-2.0 https://github.com/nical/android_system_properties The MIT License (MIT) Copyright (c) 2013 Nicolas Silva 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. --------------------------------------------------------- --------------------------------------------------------- anstream 0.6.14 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- anstyle 1.0.7 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- anstyle-parse 0.2.4 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- anstyle-query 1.0.3 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- anstyle-wincon 3.0.3 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- async-broadcast 0.5.1 - MIT OR Apache-2.0 https://github.com/smol-rs/async-broadcast Licensed under either of Apache License, Version 2.0 (LICENSE-APACHE) or MIT license (LICENSE-MIT) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- async-channel 2.3.1 - Apache-2.0 OR MIT https://github.com/smol-rs/async-channel Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. #### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- async-io 1.13.0 - Apache-2.0 OR MIT async-io 2.3.2 - Apache-2.0 OR MIT https://github.com/smol-rs/async-io 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. --------------------------------------------------------- --------------------------------------------------------- async-lock 2.8.0 - Apache-2.0 OR MIT async-lock 3.3.0 - Apache-2.0 OR MIT https://github.com/smol-rs/async-lock Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. #### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- async-process 1.8.1 - Apache-2.0 OR MIT https://github.com/smol-rs/async-process Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. #### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- async-recursion 1.1.1 - MIT OR Apache-2.0 https://github.com/dcchut/async-recursion Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) * MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option. --------------------------------------------------------- --------------------------------------------------------- async-signal 0.2.6 - Apache-2.0 OR MIT https://github.com/smol-rs/async-signal 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. --------------------------------------------------------- --------------------------------------------------------- async-task 4.7.1 - Apache-2.0 OR MIT https://github.com/smol-rs/async-task Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. #### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- async-trait 0.1.80 - MIT OR Apache-2.0 https://github.com/dtolnay/async-trait 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. --------------------------------------------------------- --------------------------------------------------------- atomic-waker 1.1.2 - Apache-2.0 OR MIT https://github.com/smol-rs/atomic-waker 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. --------------------------------------------------------- --------------------------------------------------------- autocfg 1.3.0 - Apache-2.0 OR MIT https://github.com/cuviper/autocfg Copyright (c) 2018 Josh Stone 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. --------------------------------------------------------- --------------------------------------------------------- backtrace 0.3.71 - MIT OR Apache-2.0 https://github.com/rust-lang/backtrace-rs Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- base64 0.21.7 - MIT OR Apache-2.0 https://github.com/marshallpierce/rust-base64 The MIT License (MIT) Copyright (c) 2015 Alice Maz 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. --------------------------------------------------------- --------------------------------------------------------- bit-vec 0.6.3 - MIT/Apache-2.0 https://github.com/contain-rs/bit-vec Copyright (c) 2023 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- bitflags 1.3.2 - MIT/Apache-2.0 bitflags 2.5.0 - MIT OR Apache-2.0 https://github.com/bitflags/bitflags Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- block-buffer 0.10.4 - MIT OR Apache-2.0 https://github.com/RustCrypto/utils All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- block-padding 0.3.3 - MIT OR Apache-2.0 https://github.com/RustCrypto/utils All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- blocking 1.6.0 - Apache-2.0 OR MIT https://github.com/smol-rs/blocking 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. --------------------------------------------------------- --------------------------------------------------------- bumpalo 3.16.0 - MIT OR Apache-2.0 https://github.com/fitzgen/bumpalo Copyright (c) 2019 Nick Fitzgerald 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. --------------------------------------------------------- --------------------------------------------------------- byteorder 1.5.0 - Unlicense OR MIT https://github.com/BurntSushi/byteorder The MIT License (MIT) Copyright (c) 2015 Andrew Gallant 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. --------------------------------------------------------- --------------------------------------------------------- bytes 1.6.0 - MIT https://github.com/tokio-rs/bytes The MIT License (MIT) Copyright (c) 2018 Carl Lerche 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. --------------------------------------------------------- --------------------------------------------------------- cc 1.0.98 - MIT OR Apache-2.0 https://github.com/rust-lang/cc-rs Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- cfg-if 1.0.0 - MIT/Apache-2.0 https://github.com/alexcrichton/cfg-if Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- chrono 0.4.38 - MIT OR Apache-2.0 https://github.com/chronotope/chrono Rust-chrono is dual-licensed under The MIT License [1] and Apache 2.0 License [2]. Copyright (c) 2014--2025, Kang Seonghoon and contributors. Nota Bene: This is same as the Rust Project's own license. [1]: , which is reproduced below: ~~~~ The MIT License (MIT) Copyright (c) 2014, Kang Seonghoon. 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. ~~~~ [2]: , which is reproduced below: ~~~~ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ~~~~ --------------------------------------------------------- --------------------------------------------------------- clap 4.5.4 - MIT OR Apache-2.0 https://github.com/clap-rs/clap Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- clap_builder 4.5.2 - MIT OR Apache-2.0 https://github.com/clap-rs/clap Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- clap_derive 4.5.4 - MIT OR Apache-2.0 https://github.com/clap-rs/clap Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- clap_lex 0.7.0 - MIT OR Apache-2.0 https://github.com/clap-rs/clap Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- colorchoice 1.0.1 - MIT OR Apache-2.0 https://github.com/rust-cli/anstyle This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- concurrent-queue 2.5.0 - Apache-2.0 OR MIT https://github.com/smol-rs/concurrent-queue 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. --------------------------------------------------------- --------------------------------------------------------- console 0.15.8 - MIT https://github.com/console-rs/console The MIT License (MIT) Copyright (c) 2017 Armin Ronacher 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. --------------------------------------------------------- --------------------------------------------------------- const_format 0.2.32 - Zlib https://github.com/rodrimati1992/const_format_crates/ Copyright (c) 2020 Matias Rodriguez. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------- --------------------------------------------------------- const_format_proc_macros 0.2.32 - Zlib https://github.com/rodrimati1992/const_format_crates/ Copyright (c) 2020 Matias Rodriguez. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------- --------------------------------------------------------- core-foundation 0.9.4 - MIT OR Apache-2.0 https://github.com/servo/core-foundation-rs Copyright (c) 2012-2013 Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- core-foundation-sys 0.8.6 - MIT OR Apache-2.0 https://github.com/servo/core-foundation-rs Copyright (c) 2012-2013 Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- cpufeatures 0.2.12 - MIT OR Apache-2.0 https://github.com/RustCrypto/utils All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- crc32fast 1.4.1 - MIT OR Apache-2.0 https://github.com/srijs/rust-crc32fast MIT License Copyright (c) 2018 Sam Rijs, Alex Crichton and contributors 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. --------------------------------------------------------- --------------------------------------------------------- crossbeam-channel 0.5.13 - MIT OR Apache-2.0 https://github.com/crossbeam-rs/crossbeam The MIT License (MIT) Copyright (c) 2019 The Crossbeam Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- crossbeam-utils 0.8.20 - MIT OR Apache-2.0 https://github.com/crossbeam-rs/crossbeam The MIT License (MIT) Copyright (c) 2019 The Crossbeam Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- crypto-common 0.1.6 - MIT OR Apache-2.0 https://github.com/RustCrypto/traits All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits [msrv-1.85]: https://img.shields.io/badge/rustc-1.85.0+-blue.svg [//]: # (crates) [`aead`]: ./aead [`async‑signature`]: ./signature/async [`cipher`]: ./cipher [`crypto‑common`]: ./crypto-common [`crypto`]: ./crypto [`digest`]: ./digest [`elliptic‑curve`]: ./elliptic-curve [`kem`]: ./kem [`password-hash`]: ./password-hash [`signature`]: ./signature [`universal‑hash`]: ./universal-hash [//]: # (algorithms) [Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption [Block]: https://en.wikipedia.org/wiki/Block_cipher [Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature [Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography [Key encapsulation mechanism]: https://en.wikipedia.org/wiki/Key_encapsulation [Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing --------------------------------------------------------- --------------------------------------------------------- data-encoding 2.6.0 - MIT https://github.com/ia0/data-encoding The MIT License (MIT) Copyright (c) 2015-2020 Julien Cretin Copyright (c) 2017-2020 Google Inc. 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. --------------------------------------------------------- --------------------------------------------------------- deranged 0.3.11 - MIT OR Apache-2.0 https://github.com/jhpratt/deranged Copyright (c) 2024 Jacob Pratt et al. 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. --------------------------------------------------------- --------------------------------------------------------- derivative 2.2.0 - MIT/Apache-2.0 https://github.com/mcarton/rust-derivative Copyright (c) 2016 Martin Carton 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. --------------------------------------------------------- --------------------------------------------------------- dialoguer 0.10.4 - MIT https://github.com/console-rs/dialoguer The MIT License (MIT) Copyright (c) 2017 Armin Ronacher 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. --------------------------------------------------------- --------------------------------------------------------- digest 0.10.7 - MIT OR Apache-2.0 https://github.com/RustCrypto/traits All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits [msrv-1.85]: https://img.shields.io/badge/rustc-1.85.0+-blue.svg [//]: # (crates) [`aead`]: ./aead [`async‑signature`]: ./signature/async [`cipher`]: ./cipher [`crypto‑common`]: ./crypto-common [`crypto`]: ./crypto [`digest`]: ./digest [`elliptic‑curve`]: ./elliptic-curve [`kem`]: ./kem [`password-hash`]: ./password-hash [`signature`]: ./signature [`universal‑hash`]: ./universal-hash [//]: # (algorithms) [Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption [Block]: https://en.wikipedia.org/wiki/Block_cipher [Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature [Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography [Key encapsulation mechanism]: https://en.wikipedia.org/wiki/Key_encapsulation [Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing --------------------------------------------------------- --------------------------------------------------------- dirs 4.0.0 - MIT OR Apache-2.0 dirs 5.0.1 - MIT OR Apache-2.0 https://github.com/dirs-dev/dirs-rs Copyright (c) 2018-2019 dirs-rs contributors 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. --------------------------------------------------------- --------------------------------------------------------- dirs-sys 0.3.7 - MIT OR Apache-2.0 dirs-sys 0.4.1 - MIT OR Apache-2.0 https://github.com/dirs-dev/dirs-sys-rs Copyright (c) 2018-2019 dirs-rs contributors 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. --------------------------------------------------------- --------------------------------------------------------- displaydoc 0.2.5 - MIT OR Apache-2.0 https://github.com/yaahc/displaydoc 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. --------------------------------------------------------- --------------------------------------------------------- encode_unicode 0.3.6 - MIT/Apache-2.0 https://github.com/tormol/encode_unicode 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 --------------------------------------------------------- --------------------------------------------------------- encoding_rs 0.8.34 - (Apache-2.0 OR MIT) AND BSD-3-Clause https://github.com/hsivonen/encoding_rs Copyright Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- enumflags2 0.7.9 - MIT OR Apache-2.0 https://github.com/meithecatte/enumflags2 Copyright (c) 2017-2023 Maik Klein, Maja Kądziołka 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. --------------------------------------------------------- --------------------------------------------------------- enumflags2_derive 0.7.9 - MIT OR Apache-2.0 https://github.com/meithecatte/enumflags2 Copyright (c) 2017-2023 Maik Klein, Maja Kądziołka 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. --------------------------------------------------------- --------------------------------------------------------- equivalent 1.0.1 - Apache-2.0 OR MIT https://github.com/indexmap-rs/equivalent Copyright (c) 2016--2023 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. --------------------------------------------------------- --------------------------------------------------------- errno 0.3.9 - MIT OR Apache-2.0 https://github.com/lambda-fairy/rust-errno Copyright (c) 2014 Chris Wong 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. --------------------------------------------------------- --------------------------------------------------------- event-listener 2.5.3 - Apache-2.0 OR MIT event-listener 3.1.0 - Apache-2.0 OR MIT event-listener 4.0.3 - Apache-2.0 OR MIT event-listener 5.3.0 - Apache-2.0 OR MIT https://github.com/smol-rs/event-listener 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. --------------------------------------------------------- --------------------------------------------------------- event-listener-strategy 0.4.0 - Apache-2.0 OR MIT event-listener-strategy 0.5.2 - Apache-2.0 OR MIT https://github.com/smol-rs/event-listener-strategy 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. --------------------------------------------------------- --------------------------------------------------------- fastrand 1.9.0 - Apache-2.0 OR MIT fastrand 2.1.0 - Apache-2.0 OR MIT https://github.com/smol-rs/fastrand 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. --------------------------------------------------------- --------------------------------------------------------- filetime 0.2.23 - MIT/Apache-2.0 https://github.com/alexcrichton/filetime Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- flate2 1.0.30 - MIT OR Apache-2.0 https://github.com/rust-lang/flate2-rs Copyright (c) 2014-2025 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- fnv 1.0.7 - Apache-2.0 / MIT https://github.com/servo/rust-fnv Copyright (c) 2017 Contributors 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. --------------------------------------------------------- --------------------------------------------------------- foreign-types 0.3.2 - MIT/Apache-2.0 https://github.com/sfackler/foreign-types Copyright (c) 2017 The foreign-types Developers 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. --------------------------------------------------------- --------------------------------------------------------- foreign-types-shared 0.1.1 - MIT/Apache-2.0 https://github.com/sfackler/foreign-types Copyright (c) 2017 The foreign-types Developers 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. --------------------------------------------------------- --------------------------------------------------------- form_urlencoded 1.2.1 - MIT OR Apache-2.0 https://github.com/servo/rust-url Copyright (c) 2013-2025 The rust-url developers 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. --------------------------------------------------------- --------------------------------------------------------- futures 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-channel 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-core 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-executor 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-io 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-lite 1.13.0 - Apache-2.0 OR MIT futures-lite 2.3.0 - Apache-2.0 OR MIT https://github.com/smol-rs/futures-lite 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. --------------------------------------------------------- --------------------------------------------------------- futures-macro 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-sink 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-task 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- futures-util 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/futures-rs Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors 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. --------------------------------------------------------- --------------------------------------------------------- generic-array 0.14.7 - MIT https://github.com/fizyk20/generic-array The MIT License (MIT) Copyright (c) 2015 Bartłomiej Kamiński 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. --------------------------------------------------------- --------------------------------------------------------- gethostname 0.4.3 - Apache-2.0 https://github.com/swsnr/gethostname.rs Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- getrandom 0.1.16 - MIT OR Apache-2.0 getrandom 0.2.15 - MIT OR Apache-2.0 https://github.com/rust-random/getrandom Copyright (c) 2018-2025 The rust-random Project Developers Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- gimli 0.28.1 - MIT OR Apache-2.0 https://github.com/gimli-rs/gimli Copyright (c) 2015 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- h2 0.3.26 - MIT https://github.com/hyperium/h2 The MIT License (MIT) Copyright (c) 2017 h2 authors 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. --------------------------------------------------------- --------------------------------------------------------- hashbrown 0.12.3 - MIT OR Apache-2.0 hashbrown 0.14.5 - MIT OR Apache-2.0 https://github.com/rust-lang/hashbrown Copyright (c) 2016 Amanieu d'Antras 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. --------------------------------------------------------- --------------------------------------------------------- heck 0.5.0 - MIT OR Apache-2.0 https://github.com/withoutboats/heck Copyright (c) 2015 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- hermit-abi 0.3.9 - MIT OR Apache-2.0 https://github.com/hermit-os/hermit-rs 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. --------------------------------------------------------- --------------------------------------------------------- hex 0.4.3 - MIT OR Apache-2.0 https://github.com/KokaKiwi/rust-hex Copyright (c) 2013-2014 The Rust Project Developers. Copyright (c) 2015-2020 The rust-hex Developers 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. --------------------------------------------------------- --------------------------------------------------------- hex-literal 0.3.4 - MIT OR Apache-2.0 https://github.com/RustCrypto/utils All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- hmac 0.12.1 - MIT OR Apache-2.0 https://github.com/RustCrypto/MACs All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/MACs/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/MACs [msrv-1.85]: https://img.shields.io/badge/rustc-1.85.0+-blue.svg [//]: # (crates) [`belt-mac`]: ./belt-mac [`cbc-mac`]: ./cbc-mac [`cmac`]: ./cmac [`hmac`]: ./hmac [`pmac`]: ./pmac [`retail-mac`]: ./retail-mac [//]: # (footnotes) [1]: https://en.wikipedia.org/wiki/Message_authentication_code [//]: # (algorithms) [BelT MAC]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC [CMAC]: https://en.wikipedia.org/wiki/One-key_MAC [HMAC]: https://en.wikipedia.org/wiki/HMAC [PMAC]: https://en.wikipedia.org/wiki/PMAC_(cryptography) [Retail MAC]: https://en.wikipedia.org/wiki/ISO/IEC_9797-1#MAC_algorithm_3 --------------------------------------------------------- --------------------------------------------------------- http 0.2.12 - MIT OR Apache-2.0 https://github.com/hyperium/http Copyright (c) 2017 http-rs authors 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. --------------------------------------------------------- --------------------------------------------------------- http-body 0.4.6 - MIT https://github.com/hyperium/http-body The MIT License (MIT) Copyright (c) 2019-2025 Sean McArthur & Hyper Contributors 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. --------------------------------------------------------- --------------------------------------------------------- httparse 1.8.0 - MIT/Apache-2.0 https://github.com/seanmonstar/httparse Copyright (c) 2015-2025 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- httpdate 1.0.3 - MIT OR Apache-2.0 https://github.com/pyfisch/httpdate Copyright (c) 2016 Pyfisch 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. --------------------------------------------------------- --------------------------------------------------------- hyper 0.14.28 - MIT https://github.com/hyperium/hyper The MIT License (MIT) Copyright (c) 2014-2025 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- hyper-tls 0.5.0 - MIT/Apache-2.0 https://github.com/hyperium/hyper-tls Copyright (c) 2017 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- iana-time-zone 0.1.60 - MIT OR Apache-2.0 https://github.com/strawlab/iana-time-zone Copyright (c) 2020 Andrew D. Straw 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. --------------------------------------------------------- --------------------------------------------------------- iana-time-zone-haiku 0.1.2 - MIT OR Apache-2.0 https://github.com/strawlab/iana-time-zone Copyright (c) 2020 Andrew D. Straw 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. --------------------------------------------------------- --------------------------------------------------------- icu_collections 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_locid 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_locid_transform 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_locid_transform_data 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_normalizer 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_normalizer_data 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_properties 1.5.1 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_properties_data 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_provider 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- icu_provider_macros 1.5.0 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- idna 1.0.3 - MIT OR Apache-2.0 https://github.com/servo/rust-url/ Copyright (c) 2013-2025 The rust-url developers 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. --------------------------------------------------------- --------------------------------------------------------- idna_adapter 1.2.0 - Apache-2.0 OR MIT https://github.com/hsivonen/idna_adapter Copyright (c) The rust-url developers 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. --------------------------------------------------------- --------------------------------------------------------- indexmap 1.9.3 - Apache-2.0 OR MIT indexmap 2.2.6 - Apache-2.0 OR MIT https://github.com/indexmap-rs/indexmap Copyright (c) 2016--2017 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. --------------------------------------------------------- --------------------------------------------------------- indicatif 0.17.8 - MIT https://github.com/console-rs/indicatif The MIT License (MIT) Copyright (c) 2017 Armin Ronacher 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. --------------------------------------------------------- --------------------------------------------------------- inout 0.1.3 - MIT OR Apache-2.0 https://github.com/RustCrypto/utils All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- instant 0.1.13 - BSD-3-Clause https://github.com/sebcrozet/instant Copyright (c) 2019, Sébastien Crozet All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------- --------------------------------------------------------- io-lifetimes 1.0.11 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT https://github.com/sunfishcode/io-lifetimes 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. --------------------------------------------------------- --------------------------------------------------------- ipnet 2.9.0 - MIT OR Apache-2.0 https://github.com/krisprice/ipnet Copyright 2017 Juniper Networks, Inc. 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. --------------------------------------------------------- --------------------------------------------------------- is-docker 0.2.0 - MIT https://github.com/TheLarkInn/is-docker MIT License Copyright (c) 2023 Sean Larkin 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. --------------------------------------------------------- --------------------------------------------------------- is-wsl 0.4.0 - MIT https://github.com/TheLarkInn/is-wsl MIT License Copyright (c) 2023 Sean Larkin 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. --------------------------------------------------------- --------------------------------------------------------- is_terminal_polyfill 1.70.0 - MIT OR Apache-2.0 https://github.com/polyfill-rs/is_terminal_polyfill Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- itoa 1.0.11 - MIT OR Apache-2.0 https://github.com/dtolnay/itoa 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. --------------------------------------------------------- --------------------------------------------------------- js-sys 0.3.69 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/js-sys Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- keyring 2.3.3 - MIT OR Apache-2.0 https://github.com/hwchen/keyring-rs Copyright (c) 2016 keyring Developers 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. --------------------------------------------------------- --------------------------------------------------------- lazy_static 1.4.0 - MIT/Apache-2.0 https://github.com/rust-lang-nursery/lazy-static.rs 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. --------------------------------------------------------- --------------------------------------------------------- libc 0.2.155 - MIT OR Apache-2.0 https://github.com/rust-lang/libc Copyright (c) 2014-2020 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- libredox 0.1.3 - MIT https://gitlab.redox-os.org/redox-os/libredox.git MIT License Copyright (c) 2023 4lDO2 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. --------------------------------------------------------- --------------------------------------------------------- libz-sys 1.1.16 - MIT OR Apache-2.0 https://github.com/rust-lang/libz-sys Copyright (c) 2014 Alex Crichton Copyright (c) 2020 Josh Triplett 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. --------------------------------------------------------- --------------------------------------------------------- linux-keyutils 0.2.4 - Apache-2.0 OR MIT https://github.com/landhb/linux-keyutils Licensed under either of the following at your discretion: * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [license-badge]: https://img.shields.io/badge/license-MIT/Apache--2.0-lightgray.svg?style=flat-square [license]: #license [rust-version-badge]: https://img.shields.io/badge/rust-latest%20stable-blue.svg?style=flat-square [rust-version]: #rust-version-policy [cargo-badge-lib]: https://img.shields.io/crates/v/linux-keyutils.svg?style=flat-square&label=linux-keyutils [cargo-lib]: https://crates.io/crates/linux-keyutils [docs-badge-lib]: https://img.shields.io/docsrs/linux-keyutils/latest?style=flat-square [docs-lib]: https://docs.rs/linux-keyutils [codecov]: https://img.shields.io/codecov/c/github/landhb/linux-keyutils?style=flat-square [codecov-url]: https://codecov.io/gh/landhb/linux-keyutils [build]: https://img.shields.io/github/actions/workflow/status/landhb/linux-keyutils/checks.yml?branch=main&style=flat-square [build-url]: https://github.com/landhb/linux-keyutils/actions?query=workflow%3Achecks --------------------------------------------------------- --------------------------------------------------------- linux-raw-sys 0.3.8 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT linux-raw-sys 0.4.14 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT https://github.com/sunfishcode/linux-raw-sys 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. --------------------------------------------------------- --------------------------------------------------------- litemap 0.7.4 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- lock_api 0.4.12 - MIT OR Apache-2.0 https://github.com/Amanieu/parking_lot Copyright (c) 2016 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- log 0.4.21 - MIT OR Apache-2.0 https://github.com/rust-lang/log Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- md5 0.7.0 - Apache-2.0/MIT https://github.com/stainless-steel/md5 The project is dual licensed under the terms of the Apache License, Version 2.0, and the MIT License. You may obtain copies of the two licenses at * https://www.apache.org/licenses/LICENSE-2.0 and * https://opensource.org/licenses/MIT, respectively. The following two notices apply to every file of the project. ## The Apache License ``` Copyright 2015–2024 The md5 Developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ## The MIT License ``` Copyright 2015–2024 The md5 Developers 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. ``` --------------------------------------------------------- --------------------------------------------------------- memchr 2.7.2 - Unlicense OR MIT https://github.com/BurntSushi/memchr The MIT License (MIT) Copyright (c) 2015 Andrew Gallant 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. --------------------------------------------------------- --------------------------------------------------------- memoffset 0.7.1 - MIT memoffset 0.9.1 - MIT https://github.com/Gilnaa/memoffset The MIT License (MIT) Copyright (c) 2017 Gilad Naaman 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. --------------------------------------------------------- --------------------------------------------------------- mime 0.3.17 - MIT OR Apache-2.0 https://github.com/hyperium/mime Copyright (c) 2014-2019 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- miniz_oxide 0.7.3 - MIT OR Zlib OR Apache-2.0 https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide This library (excluding the miniz C code used for tests) is licensed under the MIT license. The library is based on the miniz C library, of which the parts used are dual-licensed under the [MIT license](https://github.com/Frommi/miniz_oxide/blob/master/miniz/miniz.c#L1) and also the [unlicense](https://github.com/Frommi/miniz_oxide/blob/master/miniz/miniz.c#L577). The parts of miniz that are not covered by the unlicense is [some Zip64 code](https://github.com/richgel999/miniz/commit/224d207ce8fffb908e156d27478be3afb5d83e6a#diff-edc0e9ccfae3b5324b85b3ec0a53dc74) which is only MIT licensed. This and other Zip functionality in miniz is not part of the miniz_oxidde and miniz_oxide_c_api rust libraries. --------------------------------------------------------- --------------------------------------------------------- mio 0.8.11 - MIT https://github.com/tokio-rs/mio The MIT License (MIT) Copyright (c) 2014 Carl Lerche and other MIO contributors 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. --------------------------------------------------------- --------------------------------------------------------- native-tls 0.2.11 - MIT/Apache-2.0 https://github.com/sfackler/rust-native-tls Copyright (c) 2016 The rust-native-tls Developers 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. --------------------------------------------------------- --------------------------------------------------------- nix 0.26.4 - MIT https://github.com/nix-rust/nix The MIT License (MIT) Copyright (c) 2015 Carl Lerche + nix-rust Authors 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. --------------------------------------------------------- --------------------------------------------------------- ntapi 0.4.1 - Apache-2.0 OR MIT https://github.com/MSxDOS/ntapi 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. --------------------------------------------------------- --------------------------------------------------------- num 0.4.3 - MIT OR Apache-2.0 https://github.com/rust-num/num Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-bigint 0.4.5 - MIT OR Apache-2.0 https://github.com/rust-num/num-bigint Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-complex 0.4.6 - MIT OR Apache-2.0 https://github.com/rust-num/num-complex Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-conv 0.1.0 - MIT OR Apache-2.0 https://github.com/jhpratt/num-conv Copyright (c) 2023 Jacob Pratt 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. --------------------------------------------------------- --------------------------------------------------------- num-integer 0.1.46 - MIT OR Apache-2.0 https://github.com/rust-num/num-integer Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-iter 0.1.45 - MIT OR Apache-2.0 https://github.com/rust-num/num-iter Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-rational 0.4.2 - MIT OR Apache-2.0 https://github.com/rust-num/num-rational Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num-traits 0.2.19 - MIT OR Apache-2.0 https://github.com/rust-num/num-traits Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- num_cpus 1.16.0 - MIT OR Apache-2.0 https://github.com/seanmonstar/num_cpus Copyright (c) 2015-2025 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- number_prefix 0.4.0 - MIT https://github.com/ogham/rust-number-prefix MIT License Copyright (c) 2018 Benjamin Sago 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. --------------------------------------------------------- --------------------------------------------------------- object 0.32.2 - Apache-2.0 OR MIT https://github.com/gimli-rs/object Copyright (c) 2015 The Gimli Developers 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. --------------------------------------------------------- --------------------------------------------------------- once_cell 1.19.0 - MIT OR Apache-2.0 https://github.com/matklad/once_cell 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. --------------------------------------------------------- --------------------------------------------------------- open 4.2.0 - MIT https://github.com/Byron/open-rs The MIT License (MIT) Copyright © `2015` `Sebastian Thiel` 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. --------------------------------------------------------- --------------------------------------------------------- openssl 0.10.70 - Apache-2.0 https://github.com/sfackler/rust-openssl Copyright 2011-2017 Google Inc. 2013 Jack Lloyd 2013-2014 Steven Fackler Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- openssl-macros 0.1.1 - MIT/Apache-2.0 This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- openssl-probe 0.1.5 - MIT/Apache-2.0 https://github.com/alexcrichton/openssl-probe Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- openssl-sys 0.9.105 - MIT https://github.com/sfackler/rust-openssl The MIT License (MIT) Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- opentelemetry 0.19.0 - Apache-2.0 https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- opentelemetry_api 0.19.0 - Apache-2.0 https://github.com/open-telemetry/opentelemetry-rust Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- opentelemetry_sdk 0.19.0 - Apache-2.0 https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-sdk Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- option-ext 0.2.0 - MPL-2.0 https://github.com/soc/option-ext Mozilla Public License Version 2.0 ================================== 1. Definitions -------------- 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means (a) that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or (b) that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: (a) any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or (b) any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions -------------------------------- 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and (b) under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: (a) for any code that a Contributor has removed from Covered Software; or (b) for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or (c) under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities ------------------- 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: (a) such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and (b) You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation --------------------------------------------------- If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination -------------- 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. ************************************************************************ * * * 6. Disclaimer of Warranty * * ------------------------- * * * * Covered Software is provided under this License on an "as is" * * basis, without warranty of any kind, either expressed, implied, or * * statutory, including, without limitation, warranties that the * * Covered Software is free of defects, merchantable, fit for a * * particular purpose or non-infringing. The entire risk as to the * * quality and performance of the Covered Software is with You. * * Should any Covered Software prove defective in any respect, You * * (not any Contributor) assume the cost of any necessary servicing, * * repair, or correction. This disclaimer of warranty constitutes an * * essential part of this License. No use of any Covered Software is * * authorized under this License except under this disclaimer. * * * ************************************************************************ ************************************************************************ * * * 7. Limitation of Liability * * -------------------------- * * * * Under no circumstances and under no legal theory, whether tort * * (including negligence), contract, or otherwise, shall any * * Contributor, or anyone who distributes Covered Software as * * permitted above, be liable to You for any direct, indirect, * * special, incidental, or consequential damages of any character * * including, without limitation, damages for lost profits, loss of * * goodwill, work stoppage, computer failure or malfunction, or any * * and all other commercial damages or losses, even if such party * * shall have been informed of the possibility of such damages. This * * limitation of liability shall not apply to liability for death or * * personal injury resulting from such party's negligence to the * * extent applicable law prohibits such limitation. Some * * jurisdictions do not allow the exclusion or limitation of * * incidental or consequential damages, so this exclusion and * * limitation may not apply to You. * * * ************************************************************************ 8. Litigation ------------- Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous ---------------- This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License --------------------------- 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice ------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice --------------------------------------------------------- This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. --------------------------------------------------------- --------------------------------------------------------- ordered-stream 0.2.0 - MIT OR Apache-2.0 https://github.com/danieldg/ordered-stream 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. --------------------------------------------------------- --------------------------------------------------------- os_info 3.8.2 - MIT https://github.com/stanislav-tkach/os_info The MIT License (MIT) Copyright (c) 2017 Stanislav Tkach 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. --------------------------------------------------------- --------------------------------------------------------- parking 2.2.0 - Apache-2.0 OR MIT https://github.com/smol-rs/parking 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. --------------------------------------------------------- --------------------------------------------------------- parking_lot 0.12.2 - MIT OR Apache-2.0 https://github.com/Amanieu/parking_lot Copyright (c) 2016 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- parking_lot_core 0.9.10 - MIT OR Apache-2.0 https://github.com/Amanieu/parking_lot Copyright (c) 2016 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- paste 1.0.15 - MIT OR Apache-2.0 https://github.com/dtolnay/paste 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. --------------------------------------------------------- --------------------------------------------------------- pathdiff 0.2.1 - MIT/Apache-2.0 https://github.com/Manishearth/pathdiff 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. --------------------------------------------------------- --------------------------------------------------------- percent-encoding 2.3.1 - MIT OR Apache-2.0 https://github.com/servo/rust-url/ Copyright (c) 2013-2025 The rust-url developers 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. --------------------------------------------------------- --------------------------------------------------------- pin-project 1.1.5 - Apache-2.0 OR MIT https://github.com/taiki-e/pin-project 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. --------------------------------------------------------- --------------------------------------------------------- pin-project-internal 1.1.5 - Apache-2.0 OR MIT https://github.com/taiki-e/pin-project 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. --------------------------------------------------------- --------------------------------------------------------- pin-project-lite 0.2.14 - Apache-2.0 OR MIT https://github.com/taiki-e/pin-project-lite 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. --------------------------------------------------------- --------------------------------------------------------- pin-utils 0.1.0 - MIT OR Apache-2.0 https://github.com/rust-lang/pin-utils Copyright (c) 2018 The pin-utils authors 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. --------------------------------------------------------- --------------------------------------------------------- piper 0.2.2 - MIT OR Apache-2.0 https://github.com/smol-rs/piper 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. --------------------------------------------------------- --------------------------------------------------------- pkg-config 0.3.30 - MIT OR Apache-2.0 https://github.com/rust-lang/pkg-config-rs Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- polling 2.8.0 - Apache-2.0 OR MIT polling 3.7.0 - Apache-2.0 OR MIT https://github.com/smol-rs/polling 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. --------------------------------------------------------- --------------------------------------------------------- portable-atomic 1.6.0 - Apache-2.0 OR MIT https://github.com/taiki-e/portable-atomic 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. --------------------------------------------------------- --------------------------------------------------------- powerfmt 0.2.0 - MIT OR Apache-2.0 https://github.com/jhpratt/powerfmt Copyright (c) 2023 Jacob Pratt et al. 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. --------------------------------------------------------- --------------------------------------------------------- ppv-lite86 0.2.17 - MIT/Apache-2.0 https://github.com/cryptocorrosion/cryptocorrosion Copyright (c) 2019 The CryptoCorrosion Contributors 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. --------------------------------------------------------- --------------------------------------------------------- proc-macro-crate 1.3.1 - MIT OR Apache-2.0 https://github.com/bkchr/proc-macro-crate 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. --------------------------------------------------------- --------------------------------------------------------- proc-macro2 1.0.83 - MIT OR Apache-2.0 https://github.com/dtolnay/proc-macro2 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. --------------------------------------------------------- --------------------------------------------------------- quote 1.0.36 - MIT OR Apache-2.0 https://github.com/dtolnay/quote 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. --------------------------------------------------------- --------------------------------------------------------- rand 0.7.3 - MIT OR Apache-2.0 rand 0.8.5 - MIT OR Apache-2.0 https://github.com/rust-random/rand Copyright 2018 Developers of the Rand project Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- rand_chacha 0.2.2 - MIT OR Apache-2.0 rand_chacha 0.3.1 - MIT OR Apache-2.0 https://github.com/rust-random/rand Copyright 2018 Developers of the Rand project Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- rand_core 0.5.1 - MIT OR Apache-2.0 rand_core 0.6.4 - MIT OR Apache-2.0 https://github.com/rust-random/rand Copyright 2018 Developers of the Rand project Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- rand_hc 0.2.0 - MIT/Apache-2.0 https://github.com/rust-random/rngs Copyright 2018 Developers of the Rand project Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- redox_syscall 0.4.1 - MIT redox_syscall 0.5.1 - MIT https://github.com/redox-os/syscall Copyright (c) 2017 Redox OS Developers MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- redox_users 0.4.5 - MIT https://gitlab.redox-os.org/redox-os/users The MIT License (MIT) Copyright (c) 2017 Jose Narvaez 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. --------------------------------------------------------- --------------------------------------------------------- regex 1.10.4 - MIT OR Apache-2.0 https://github.com/rust-lang/regex Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- regex-automata 0.4.6 - MIT OR Apache-2.0 https://github.com/rust-lang/regex/tree/master/regex-automata Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- regex-syntax 0.8.3 - MIT OR Apache-2.0 https://github.com/rust-lang/regex/tree/master/regex-syntax Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- reqwest 0.11.27 - MIT OR Apache-2.0 https://github.com/seanmonstar/reqwest Copyright (c) 2016-2025 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- rmp 0.8.14 - MIT https://github.com/3Hren/msgpack-rust MIT License Copyright (c) 2017 Evgeny Safronov 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. --------------------------------------------------------- --------------------------------------------------------- rmp-serde 1.3.0 - MIT https://github.com/3Hren/msgpack-rust MIT License Copyright (c) 2017 Evgeny Safronov 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. --------------------------------------------------------- --------------------------------------------------------- russh fd4f608a83753f9f3e137f95600faffede71cf65 https://github.com/microsoft/vscode-russh Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- russh-cryptovec fd4f608a83753f9f3e137f95600faffede71cf65 https://github.com/microsoft/vscode-russh Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- russh-keys fd4f608a83753f9f3e137f95600faffede71cf65 https://github.com/microsoft/vscode-russh Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------------- --------------------------------------------------------- rustc-demangle 0.1.24 - MIT/Apache-2.0 https://github.com/rust-lang/rustc-demangle Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- rustix 0.37.27 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT rustix 0.38.34 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT https://github.com/bytecodealliance/rustix 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. --------------------------------------------------------- --------------------------------------------------------- rustls-pemfile 1.0.4 - Apache-2.0 OR ISC OR MIT https://github.com/rustls/pemfile rustls-pemfile is distributed under the following three licenses: - Apache License version 2.0. - MIT license. - ISC license. These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this software under the terms of any of these licenses, at your option. --------------------------------------------------------- --------------------------------------------------------- ryu 1.0.18 - Apache-2.0 OR BSL-1.0 https://github.com/dtolnay/ryu Licensed under either of Apache License, Version 2.0 (LICENSE-APACHE) or Boost Software License 1.0 (LICENSE-BOOST) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. --------------------------------------------------------- --------------------------------------------------------- schannel 0.1.23 - MIT https://github.com/steffengy/schannel-rs The MIT License (MIT) Copyright (c) 2015 steffengy 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. --------------------------------------------------------- --------------------------------------------------------- scopeguard 1.2.0 - MIT OR Apache-2.0 https://github.com/bluss/scopeguard Copyright (c) 2016-2019 Ulrik Sverdrup "bluss" and scopeguard developers 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. --------------------------------------------------------- --------------------------------------------------------- secret-service 3.0.1 - MIT OR Apache-2.0 https://github.com/hwchen/secret-service-rs Copyright (c) 2025 secret-service Developers 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. --------------------------------------------------------- --------------------------------------------------------- security-framework 2.11.0 - MIT OR Apache-2.0 https://github.com/kornelski/rust-security-framework The MIT License (MIT) Copyright (c) 2015 Steven Fackler 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. --------------------------------------------------------- --------------------------------------------------------- security-framework-sys 2.11.0 - MIT OR Apache-2.0 https://github.com/kornelski/rust-security-framework The MIT License (MIT) Copyright (c) 2015 Steven Fackler 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. --------------------------------------------------------- --------------------------------------------------------- serde 1.0.202 - MIT OR Apache-2.0 https://github.com/serde-rs/serde 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. --------------------------------------------------------- --------------------------------------------------------- serde_bytes 0.11.14 - MIT OR Apache-2.0 https://github.com/serde-rs/bytes 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. --------------------------------------------------------- --------------------------------------------------------- serde_derive 1.0.202 - MIT OR Apache-2.0 https://github.com/serde-rs/serde 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. --------------------------------------------------------- --------------------------------------------------------- serde_json 1.0.117 - MIT OR Apache-2.0 https://github.com/serde-rs/json 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. --------------------------------------------------------- --------------------------------------------------------- serde_repr 0.1.19 - MIT OR Apache-2.0 https://github.com/dtolnay/serde-repr 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. --------------------------------------------------------- --------------------------------------------------------- serde_urlencoded 0.7.1 - MIT/Apache-2.0 https://github.com/nox/serde_urlencoded Copyright (c) 2016 Anthony Ramine 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. --------------------------------------------------------- --------------------------------------------------------- sha1 0.10.6 - MIT OR Apache-2.0 https://github.com/RustCrypto/hashes All crates in this repository are licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/hashes [//]: # (crates) [`ascon‑hash`]: ./ascon-hash [`belt‑hash`]: ./belt-hash [`blake2`]: ./blake2 [`fsb`]: ./fsb [`gost94`]: ./gost94 [`groestl`]: ./groestl [`jh`]: ./jh [`k12`]: ./k12 [`kupyna`]: ./kupyna [`md2`]: ./md2 [`md4`]: ./md4 [`md5`]: ./md5 [`ripemd`]: ./ripemd [`sha1`]: ./sha1 [`sha1-checked`]: ./sha1-checked [`sha2`]: ./sha2 [`sha3`]: ./sha3 [`shabal`]: ./shabal [`skein`]: ./skein [`sm3`]: ./sm3 [`streebog`]: ./streebog [`tiger`]: ./tiger [`whirlpool`]: ./whirlpool [//]: # (footnotes) [1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [`blake3`]: https://github.com/BLAKE3-team/BLAKE3 [`base16ct`]: https://docs.rs/base16ct [`base64ct`]: https://docs.rs/base64ct [`digest`]: https://docs.rs/digest [`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html [`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest [`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html [`generic-array`]: https://docs.rs/generic-array [HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [`hmac`]: https://docs.rs/hmac [RustCrypto/MACs]: https://github.com/RustCrypto/MACs [//]: # (algorithms) [Ascon]: https://ascon.iaik.tugraz.at [BelT]: https://ru.wikipedia.org/wiki/BelT [BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 [FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash [GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function) [Grøstl]: https://en.wikipedia.org/wiki/Grøstl [JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh [KangarooTwelve]: https://keccak.team/kangarootwelve.html [Kupyna]: https://eprint.iacr.org/2015/885.pdf [MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) [MD4]: https://en.wikipedia.org/wiki/MD4 [MD5]: https://en.wikipedia.org/wiki/MD5 [RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD [SHA-1]: https://en.wikipedia.org/wiki/SHA-1 [SHA-1 Checked]: https://github.com/cr-marcstevens/sha1collisiondetection [SHA-2]: https://en.wikipedia.org/wiki/SHA-2 [SHA-3]: https://en.wikipedia.org/wiki/SHA-3 [SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf [Skein]: https://schneier.com/academic/skein [SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function) [Streebog]: https://en.wikipedia.org/wiki/Streebog [Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography) [Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html --------------------------------------------------------- --------------------------------------------------------- sha2 0.10.8 - MIT OR Apache-2.0 https://github.com/RustCrypto/hashes All crates in this repository are licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/hashes [//]: # (crates) [`ascon‑hash`]: ./ascon-hash [`belt‑hash`]: ./belt-hash [`blake2`]: ./blake2 [`fsb`]: ./fsb [`gost94`]: ./gost94 [`groestl`]: ./groestl [`jh`]: ./jh [`k12`]: ./k12 [`kupyna`]: ./kupyna [`md2`]: ./md2 [`md4`]: ./md4 [`md5`]: ./md5 [`ripemd`]: ./ripemd [`sha1`]: ./sha1 [`sha1-checked`]: ./sha1-checked [`sha2`]: ./sha2 [`sha3`]: ./sha3 [`shabal`]: ./shabal [`skein`]: ./skein [`sm3`]: ./sm3 [`streebog`]: ./streebog [`tiger`]: ./tiger [`whirlpool`]: ./whirlpool [//]: # (footnotes) [1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [`blake3`]: https://github.com/BLAKE3-team/BLAKE3 [`base16ct`]: https://docs.rs/base16ct [`base64ct`]: https://docs.rs/base64ct [`digest`]: https://docs.rs/digest [`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html [`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest [`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html [`generic-array`]: https://docs.rs/generic-array [HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [`hmac`]: https://docs.rs/hmac [RustCrypto/MACs]: https://github.com/RustCrypto/MACs [//]: # (algorithms) [Ascon]: https://ascon.iaik.tugraz.at [BelT]: https://ru.wikipedia.org/wiki/BelT [BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 [FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash [GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function) [Grøstl]: https://en.wikipedia.org/wiki/Grøstl [JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh [KangarooTwelve]: https://keccak.team/kangarootwelve.html [Kupyna]: https://eprint.iacr.org/2015/885.pdf [MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) [MD4]: https://en.wikipedia.org/wiki/MD4 [MD5]: https://en.wikipedia.org/wiki/MD5 [RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD [SHA-1]: https://en.wikipedia.org/wiki/SHA-1 [SHA-1 Checked]: https://github.com/cr-marcstevens/sha1collisiondetection [SHA-2]: https://en.wikipedia.org/wiki/SHA-2 [SHA-3]: https://en.wikipedia.org/wiki/SHA-3 [SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf [Skein]: https://schneier.com/academic/skein [SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function) [Streebog]: https://en.wikipedia.org/wiki/Streebog [Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography) [Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html --------------------------------------------------------- --------------------------------------------------------- shell-escape 0.1.5 - MIT/Apache-2.0 https://github.com/sfackler/shell-escape Copyright (c) 2014 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- shell-words 1.1.0 - MIT/Apache-2.0 https://github.com/tmiasko/shell-words Copyright (c) 2016 Tomasz Miąsko 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. --------------------------------------------------------- --------------------------------------------------------- signal-hook-registry 1.4.2 - Apache-2.0/MIT https://github.com/vorner/signal-hook Copyright (c) 2017 tokio-jsonrpc developers 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. --------------------------------------------------------- --------------------------------------------------------- slab 0.4.9 - MIT https://github.com/tokio-rs/slab The MIT License (MIT) Copyright (c) 2019 Carl Lerche 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. --------------------------------------------------------- --------------------------------------------------------- smallvec 1.13.2 - MIT OR Apache-2.0 https://github.com/servo/rust-smallvec Copyright (c) 2018 The Servo Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- socket2 0.4.10 - MIT OR Apache-2.0 socket2 0.5.7 - MIT OR Apache-2.0 https://github.com/rust-lang/socket2 Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- stable_deref_trait 1.2.0 - MIT/Apache-2.0 https://github.com/storyyeller/stable_deref_trait Copyright (c) 2017 Robert Grosse 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. --------------------------------------------------------- --------------------------------------------------------- static_assertions 1.1.0 - MIT OR Apache-2.0 https://github.com/nvzqz/static-assertions-rs MIT License Copyright (c) 2017 Nikolai Vazquez 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. --------------------------------------------------------- --------------------------------------------------------- strsim 0.11.1 - MIT https://github.com/rapidfuzz/strsim-rs The MIT License (MIT) Copyright (c) 2015 Danny Guo Copyright (c) 2016 Titus Wormer Copyright (c) 2018 Akash Kurdekar 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. --------------------------------------------------------- --------------------------------------------------------- subtle 2.5.0 - BSD-3-Clause https://github.com/dalek-cryptography/subtle Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved. Copyright (c) 2016-2024 Isis Agora Lovecruft. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------- --------------------------------------------------------- syn 1.0.109 - MIT OR Apache-2.0 syn 2.0.65 - MIT OR Apache-2.0 https://github.com/dtolnay/syn 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. --------------------------------------------------------- --------------------------------------------------------- sync_wrapper 0.1.2 - Apache-2.0 https://github.com/Actyx/sync_wrapper Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS --------------------------------------------------------- --------------------------------------------------------- synstructure 0.13.1 - MIT https://github.com/mystor/synstructure The MIT License (MIT) Copyright 2016 Nika Layzell 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. --------------------------------------------------------- --------------------------------------------------------- sysinfo 0.29.11 - MIT https://github.com/GuillaumeGomez/sysinfo The MIT License (MIT) Copyright (c) 2015 Guillaume Gomez 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. --------------------------------------------------------- --------------------------------------------------------- system-configuration 0.5.1 - MIT OR Apache-2.0 https://github.com/mullvad/system-configuration-rs Copyright (c) 2024 Mullvad VPN AB 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. --------------------------------------------------------- --------------------------------------------------------- system-configuration-sys 0.5.0 - MIT OR Apache-2.0 https://github.com/mullvad/system-configuration-rs Copyright (c) 2024 Mullvad VPN AB 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. --------------------------------------------------------- --------------------------------------------------------- tar 0.4.40 - MIT/Apache-2.0 https://github.com/alexcrichton/tar-rs Copyright (c) The tar-rs Project Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tempfile 3.10.1 - MIT OR Apache-2.0 https://github.com/Stebalien/tempfile Copyright (c) 2015 Steven Allen 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. --------------------------------------------------------- --------------------------------------------------------- thiserror 1.0.61 - MIT OR Apache-2.0 https://github.com/dtolnay/thiserror 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. --------------------------------------------------------- --------------------------------------------------------- thiserror-impl 1.0.61 - MIT OR Apache-2.0 https://github.com/dtolnay/thiserror 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. --------------------------------------------------------- --------------------------------------------------------- time 0.3.36 - MIT OR Apache-2.0 https://github.com/time-rs/time Copyright (c) Jacob Pratt et al. 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. --------------------------------------------------------- --------------------------------------------------------- time-core 0.1.2 - MIT OR Apache-2.0 https://github.com/time-rs/time Copyright (c) Jacob Pratt et al. 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. --------------------------------------------------------- --------------------------------------------------------- tinystr 0.7.6 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- tokio 1.37.0 - MIT https://github.com/tokio-rs/tokio MIT License Copyright (c) Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tokio-macros 2.2.0 - MIT https://github.com/tokio-rs/tokio MIT License Copyright (c) Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tokio-native-tls 0.3.1 - MIT https://github.com/tokio-rs/tls The MIT License (MIT) Copyright (c) 2019 Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tokio-stream 0.1.15 - MIT https://github.com/tokio-rs/tokio MIT License Copyright (c) Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tokio-tungstenite 0.20.1 - MIT https://github.com/snapview/tokio-tungstenite The MIT License (MIT) Copyright (c) 2017 Daniel Abramov Copyright (c) 2017 Alexey Galakhov 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. --------------------------------------------------------- --------------------------------------------------------- tokio-util 0.7.11 - MIT https://github.com/tokio-rs/tokio MIT License Copyright (c) Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- toml_datetime 0.6.6 - MIT OR Apache-2.0 https://github.com/toml-rs/toml Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- toml_edit 0.19.15 - MIT OR Apache-2.0 https://github.com/toml-rs/toml Copyright (c) Individual contributors 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. --------------------------------------------------------- --------------------------------------------------------- tower-service 0.3.2 - MIT https://github.com/tower-rs/tower The MIT License (MIT) Copyright (c) 2019 Tower Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tracing 0.1.40 - MIT https://github.com/tokio-rs/tracing The MIT License (MIT) Copyright (c) 2019 Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tracing-attributes 0.1.27 - MIT https://github.com/tokio-rs/tracing The MIT License (MIT) Copyright (c) 2019 Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- tracing-core 0.1.32 - MIT https://github.com/tokio-rs/tracing The MIT License (MIT) Copyright (c) 2019 Tokio Contributors 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. --------------------------------------------------------- --------------------------------------------------------- try-lock 0.2.5 - MIT https://github.com/seanmonstar/try-lock The MIT License (MIT) Copyright (c) 2018-2025 Sean McArthur Copyright (c) 2016 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- tungstenite 0.20.1 - MIT OR Apache-2.0 https://github.com/snapview/tungstenite-rs Copyright (c) 2017 Alexey Galakhov Copyright (c) 2016 Jason Housley 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. --------------------------------------------------------- --------------------------------------------------------- tunnels 8cae9b2a24c65c6c1958f5a0e77d72b23b5c6c30 https://github.com/microsoft/dev-tunnels MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- typenum 1.17.0 - MIT OR Apache-2.0 https://github.com/paholg/typenum MIT OR Apache-2.0 --------------------------------------------------------- --------------------------------------------------------- uds_windows 1.1.0 - MIT https://github.com/haraldh/rust_uds_windows MIT License Copyright (c) Microsoft Corporation. All rights reserved. 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 --------------------------------------------------------- --------------------------------------------------------- unicode-ident 1.0.12 - (MIT OR Apache-2.0) AND Unicode-DFS-2016 https://github.com/dtolnay/unicode-ident 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. --------------------------------------------------------- --------------------------------------------------------- unicode-width 0.1.12 - MIT OR Apache-2.0 https://github.com/unicode-rs/unicode-width Copyright (c) 2015 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- unicode-xid 0.2.4 - MIT OR Apache-2.0 https://github.com/unicode-rs/unicode-xid Copyright (c) 2015 The Rust Project Developers 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. --------------------------------------------------------- --------------------------------------------------------- url 2.5.4 - MIT OR Apache-2.0 https://github.com/servo/rust-url Copyright (c) 2013-2025 The rust-url developers 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. --------------------------------------------------------- --------------------------------------------------------- urlencoding 2.1.3 - MIT https://github.com/kornelski/rust_urlencoding The MIT License (MIT) © 2016 Bertram Truong © 2021 Kornel Lesiński 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. --------------------------------------------------------- --------------------------------------------------------- utf-8 0.7.6 - MIT OR Apache-2.0 https://github.com/SimonSapin/rust-utf8 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. --------------------------------------------------------- --------------------------------------------------------- utf16_iter 1.0.5 - Apache-2.0 OR MIT https://github.com/hsivonen/utf16_iter Copyright Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- utf8_iter 1.0.4 - Apache-2.0 OR MIT https://github.com/hsivonen/utf8_iter Copyright Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- utf8parse 0.2.1 - Apache-2.0 OR MIT https://github.com/alacritty/vte Copyright (c) 2016 Joe Wilm 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. --------------------------------------------------------- --------------------------------------------------------- uuid 1.8.0 - Apache-2.0 OR MIT https://github.com/uuid-rs/uuid Copyright (c) 2014 The Rust Project Developers Copyright (c) 2018 Ashley Mannix, Christopher Armstrong, Dylan DPC, Hunar Roop Kahlon 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. --------------------------------------------------------- --------------------------------------------------------- vcpkg 0.2.15 - MIT/Apache-2.0 https://github.com/mcgoo/vcpkg-rs Copyright (c) 2017 Jim McGrath 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. --------------------------------------------------------- --------------------------------------------------------- version_check 0.9.4 - MIT/Apache-2.0 https://github.com/SergioBenitez/version_check The MIT License (MIT) Copyright (c) 2017-2018 Sergio Benitez 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. --------------------------------------------------------- --------------------------------------------------------- waker-fn 1.2.0 - Apache-2.0 OR MIT https://github.com/smol-rs/waker-fn 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. --------------------------------------------------------- --------------------------------------------------------- want 0.3.1 - MIT https://github.com/seanmonstar/want The MIT License (MIT) Copyright (c) 2018-2019 Sean McArthur 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. --------------------------------------------------------- --------------------------------------------------------- wasi 0.11.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT wasi 0.9.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT https://github.com/bytecodealliance/wasi-rs 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen 0.2.92 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen-backend 0.2.92 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/backend Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen-futures 0.4.42 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/futures Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen-macro 0.2.92 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen-macro-support 0.2.92 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro-support Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-bindgen-shared 0.2.92 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/shared Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- wasm-streams 0.4.0 - MIT OR Apache-2.0 https://github.com/MattiasBuelens/wasm-streams/ 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. --------------------------------------------------------- --------------------------------------------------------- web-sys 0.3.69 - MIT OR Apache-2.0 https://github.com/rustwasm/wasm-bindgen/tree/master/crates/web-sys Copyright (c) 2014 Alex Crichton 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. --------------------------------------------------------- --------------------------------------------------------- winapi 0.3.9 - MIT/Apache-2.0 https://github.com/retep998/winapi-rs Copyright (c) 2015-2018 The winapi-rs Developers 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. --------------------------------------------------------- --------------------------------------------------------- winapi-i686-pc-windows-gnu 0.4.0 - MIT/Apache-2.0 https://github.com/retep998/winapi-rs Copyright (c) 2015-2018 The winapi-rs Developers 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. --------------------------------------------------------- --------------------------------------------------------- winapi-x86_64-pc-windows-gnu 0.4.0 - MIT/Apache-2.0 https://github.com/retep998/winapi-rs Copyright (c) 2015-2018 The winapi-rs Developers 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. --------------------------------------------------------- --------------------------------------------------------- windows-core 0.52.0 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows-sys 0.48.0 - MIT OR Apache-2.0 windows-sys 0.52.0 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows-targets 0.48.5 - MIT OR Apache-2.0 windows-targets 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_aarch64_gnullvm 0.48.5 - MIT OR Apache-2.0 windows_aarch64_gnullvm 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_aarch64_msvc 0.48.5 - MIT OR Apache-2.0 windows_aarch64_msvc 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_i686_gnu 0.48.5 - MIT OR Apache-2.0 windows_i686_gnu 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_i686_gnullvm 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_i686_msvc 0.48.5 - MIT OR Apache-2.0 windows_i686_msvc 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_x86_64_gnu 0.48.5 - MIT OR Apache-2.0 windows_x86_64_gnu 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_x86_64_gnullvm 0.48.5 - MIT OR Apache-2.0 windows_x86_64_gnullvm 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- windows_x86_64_msvc 0.48.5 - MIT OR Apache-2.0 windows_x86_64_msvc 0.52.5 - MIT OR Apache-2.0 https://github.com/microsoft/windows-rs MIT License Copyright (c) Microsoft Corporation. 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 --------------------------------------------------------- --------------------------------------------------------- winnow 0.5.40 - MIT https://github.com/winnow-rs/winnow The MIT License (MIT) 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. --------------------------------------------------------- --------------------------------------------------------- winreg 0.50.0 - MIT winreg 0.8.0 - MIT https://github.com/gentoo90/winreg-rs The MIT License (MIT) Copyright (c) 2015 Igor Shaula 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. --------------------------------------------------------- --------------------------------------------------------- write16 1.0.0 - Apache-2.0 OR MIT https://github.com/hsivonen/write16 Copyright Mozilla Foundation 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. --------------------------------------------------------- --------------------------------------------------------- writeable 0.5.5 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- xattr 1.3.1 - MIT/Apache-2.0 https://github.com/Stebalien/xattr Copyright (c) 2015 Steven Allen 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. --------------------------------------------------------- --------------------------------------------------------- xdg-home 1.1.0 - MIT https://github.com/zeenix/xdg-home The MIT License (MIT) 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. --------------------------------------------------------- --------------------------------------------------------- yasna 0.5.2 - MIT OR Apache-2.0 https://github.com/qnighy/yasna.rs Copyright (c) 2016 Masaki Hara 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. --------------------------------------------------------- --------------------------------------------------------- yoke 0.7.5 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- yoke-derive 0.7.5 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- zbus 3.15.2 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- --------------------------------------------------------- zbus_macros 3.15.2 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- --------------------------------------------------------- zbus_names 2.6.1 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- --------------------------------------------------------- zerofrom 0.1.5 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- zerofrom-derive 0.1.5 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- zeroize 1.7.0 - Apache-2.0 OR MIT https://github.com/RustCrypto/utils/tree/master/zeroize All crates licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/utils/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/utils [//]: # (crates) [`blobby`]: ./blobby [`block-buffer`]: ./block-buffer [`block‑padding`]: ./block-padding [`cmov`]: ./cmov [`collectable`]: ./collectable [`cpufeatures`]: ./cpufeatures [`dbl`]: ./dbl [`hex-literal`]: ./hex-literal [`inout`]: ./inout [`opaque-debug`]: ./opaque-debug [`wycheproof2blb`]: ./wycheproof2blb [`zeroize`]: ./zeroize [//]: # (misc) [Wycheproof]: https://github.com/google/wycheproof --------------------------------------------------------- --------------------------------------------------------- zerovec 0.10.4 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- zerovec-derive 0.10.3 - Unicode-3.0 https://github.com/unicode-org/icu4x UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE Copyright © 2020-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. Permission is hereby granted, free of charge, to any person obtaining a copy of data files and any associated documentation (the "Data Files") or software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either (a) this copyright and permission notice appear with all copies of the Data Files or Software, or (b) this copyright and permission notice appear in associated Documentation. THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. SPDX-License-Identifier: Unicode-3.0 — Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. --------------------------------------------------------- --------------------------------------------------------- zip 0.6.6 - MIT https://github.com/zip-rs/zip2 The MIT License (MIT) Copyright (c) 2014 Mathijs van de Nes 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. Some files in the "tests/data" subdirectory of this repository are under other licences; see files named LICENSE.*.txt for details. --------------------------------------------------------- --------------------------------------------------------- zvariant 3.15.2 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- --------------------------------------------------------- zvariant_derive 3.15.2 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- --------------------------------------------------------- zvariant_utils 1.0.1 - MIT https://github.com/dbus2/zbus/ The MIT License (MIT) Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors 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. --------------------------------------------------------- ================================================ FILE: cli/build.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const FILE_HEADER: &str = "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/"; use std::{ collections::HashMap, env, fs, io, path::{Path, PathBuf}, process::{self}, str::FromStr, }; use serde::{de::DeserializeOwned, Deserialize}; use serde_json::Value; fn main() { let files = enumerate_source_files().expect("expected to enumerate files"); ensure_file_headers(&files).expect("expected to ensure file headers"); apply_build_environment_variables(); } fn camel_case_to_constant_case(key: &str) -> String { let mut output = String::new(); let mut prev_upper = false; for c in key.chars() { if c.is_uppercase() { if prev_upper { output.push(c.to_ascii_lowercase()); } else { output.push('_'); output.push(c.to_ascii_uppercase()); } prev_upper = true; } else if c.is_lowercase() { output.push(c.to_ascii_uppercase()); prev_upper = false; } else { output.push(c); prev_upper = false; } } output } fn set_env_vars_from_map_keys(prefix: &str, map: impl IntoIterator) { let mut win32_app_ids = vec![]; for (key, value) in map { //#region special handling let value = match key.as_str() { "tunnelServerQualities" | "serverLicense" => { Value::String(serde_json::to_string(&value).unwrap()) } "nameLong" => { if let Value::String(s) = &value { let idx = s.find(" - "); println!( "cargo:rustc-env=VSCODE_CLI_QUALITYLESS_PRODUCT_NAME={}", idx.map(|i| &s[..i]).unwrap_or(s) ); } value } "tunnelApplicationConfig" => { if let Value::Object(v) = value { set_env_vars_from_map_keys(&format!("{}_{}", prefix, "TUNNEL"), v); } continue; } _ => value, }; if key.contains("win32") && key.contains("AppId") { if let Value::String(s) = value { win32_app_ids.push(s); continue; } } //#endregion if let Value::String(s) = value { println!( "cargo:rustc-env={}_{}={}", prefix, camel_case_to_constant_case(&key), s ); } } if !win32_app_ids.is_empty() { println!( "cargo:rustc-env=VSCODE_CLI_WIN32_APP_IDS={}", win32_app_ids.join(",") ); } } fn read_json_from_path(path: &Path) -> T where T: DeserializeOwned, { let mut file = fs::File::open(path).expect("failed to open file"); serde_json::from_reader(&mut file).expect("failed to deserialize JSON") } fn apply_build_from_product_json(path: &Path) { let json: HashMap = read_json_from_path(path); set_env_vars_from_map_keys("VSCODE_CLI", json); } #[derive(Deserialize)] struct PackageJson { pub version: String, } fn apply_build_environment_variables() { let repo_dir = env::current_dir().unwrap().join(".."); let package_json = read_json_from_path::(&repo_dir.join("package.json")); println!( "cargo:rustc-env=VSCODE_CLI_VERSION={}", package_json.version ); match env::var("VSCODE_CLI_PRODUCT_JSON") { Ok(v) => { let path = if cfg!(windows) { PathBuf::from_str(&v.replace('/', "\\")).unwrap() } else { PathBuf::from_str(&v).unwrap() }; println!("cargo:warning=loading product.json from <{path:?}>"); apply_build_from_product_json(&path); } Err(_) => { apply_build_from_product_json(&repo_dir.join("product.json")); let overrides = repo_dir.join("product.overrides.json"); if overrides.exists() { apply_build_from_product_json(&overrides); } } }; } fn ensure_file_headers(files: &[PathBuf]) -> Result<(), io::Error> { let mut ok = true; let crlf_header_str = str::replace(FILE_HEADER, "\n", "\r\n"); let crlf_header = crlf_header_str.as_bytes(); let lf_header = FILE_HEADER.as_bytes(); for file in files { let contents = fs::read(file)?; if !(contents.starts_with(lf_header) || contents.starts_with(crlf_header)) { eprintln!("File missing copyright header: {}", file.display()); ok = false; } } if !ok { process::exit(1); } Ok(()) } /// Gets all "rs" files in the source directory fn enumerate_source_files() -> Result, io::Error> { let mut files = vec![]; let mut queue = vec![]; let current_dir = env::current_dir()?.join("src"); queue.push(current_dir); while !queue.is_empty() { for entry in fs::read_dir(queue.pop().unwrap())? { let entry = entry?; let ftype = entry.file_type()?; if ftype.is_dir() { queue.push(entry.path()); } else if ftype.is_file() && entry.file_name().to_string_lossy().ends_with(".rs") { files.push(entry.path()); } } } Ok(files) } ================================================ FILE: cli/rustfmt.toml ================================================ hard_tabs = true ================================================ FILE: cli/src/async_pipe.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::{constants::APPLICATION_NAME, util::errors::CodeError}; use async_trait::async_trait; use std::path::{Path, PathBuf}; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::TcpListener; use uuid::Uuid; // todo: we could probably abstract this into some crate, if one doesn't already exist cfg_if::cfg_if! { if #[cfg(unix)] { pub type AsyncPipe = tokio::net::UnixStream; pub type AsyncPipeWriteHalf = tokio::net::unix::OwnedWriteHalf; pub type AsyncPipeReadHalf = tokio::net::unix::OwnedReadHalf; pub async fn get_socket_rw_stream(path: &Path) -> Result { tokio::net::UnixStream::connect(path) .await .map_err(CodeError::AsyncPipeFailed) } pub async fn listen_socket_rw_stream(path: &Path) -> Result { tokio::net::UnixListener::bind(path) .map(AsyncPipeListener) .map_err(CodeError::AsyncPipeListenerFailed) } pub struct AsyncPipeListener(tokio::net::UnixListener); impl AsyncPipeListener { pub async fn accept(&mut self) -> Result { self.0.accept().await.map_err(CodeError::AsyncPipeListenerFailed).map(|(s, _)| s) } } pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) { pipe.into_split() } } else { use tokio::{time::sleep, io::ReadBuf}; use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer}; use std::{time::Duration, io}; use pin_project::pin_project; #[pin_project(project = AsyncPipeProj)] pub enum AsyncPipe { PipeClient(#[pin] NamedPipeClient), PipeServer(#[pin] NamedPipeServer), } impl AsyncRead for AsyncPipe { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { match self.project() { AsyncPipeProj::PipeClient(c) => c.poll_read(cx, buf), AsyncPipeProj::PipeServer(c) => c.poll_read(cx, buf), } } } impl AsyncWrite for AsyncPipe { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { match self.project() { AsyncPipeProj::PipeClient(c) => c.poll_write(cx, buf), AsyncPipeProj::PipeServer(c) => c.poll_write(cx, buf), } } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[io::IoSlice<'_>], ) -> Poll> { match self.project() { AsyncPipeProj::PipeClient(c) => c.poll_write_vectored(cx, bufs), AsyncPipeProj::PipeServer(c) => c.poll_write_vectored(cx, bufs), } } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.project() { AsyncPipeProj::PipeClient(c) => c.poll_flush(cx), AsyncPipeProj::PipeServer(c) => c.poll_flush(cx), } } fn is_write_vectored(&self) -> bool { match self { AsyncPipe::PipeClient(c) => c.is_write_vectored(), AsyncPipe::PipeServer(c) => c.is_write_vectored(), } } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.project() { AsyncPipeProj::PipeClient(c) => c.poll_shutdown(cx), AsyncPipeProj::PipeServer(c) => c.poll_shutdown(cx), } } } pub type AsyncPipeWriteHalf = tokio::io::WriteHalf; pub type AsyncPipeReadHalf = tokio::io::ReadHalf; pub async fn get_socket_rw_stream(path: &Path) -> Result { // Tokio says we can need to try in a loop. Do so. // https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeClient.html let client = loop { match ClientOptions::new().open(path) { Ok(client) => break client, // ERROR_PIPE_BUSY https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- Err(e) if e.raw_os_error() == Some(231) => sleep(Duration::from_millis(100)).await, Err(e) => return Err(CodeError::AsyncPipeFailed(e)), } }; Ok(AsyncPipe::PipeClient(client)) } pub struct AsyncPipeListener { path: PathBuf, server: NamedPipeServer } impl AsyncPipeListener { pub async fn accept(&mut self) -> Result { // see https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeServer.html // this is a bit weird in that the server becomes the client once // they get a connection, and we create a new client. self.server .connect() .await .map_err(CodeError::AsyncPipeListenerFailed)?; // Construct the next server to be connected before sending the one // we already have of onto a task. This ensures that the server // isn't closed (after it's done in the task) before a new one is // available. Otherwise the client might error with // `io::ErrorKind::NotFound`. let next_server = ServerOptions::new() .create(&self.path) .map_err(CodeError::AsyncPipeListenerFailed)?; Ok(AsyncPipe::PipeServer(std::mem::replace(&mut self.server, next_server))) } } pub async fn listen_socket_rw_stream(path: &Path) -> Result { let server = ServerOptions::new() .first_pipe_instance(true) .create(path) .map_err(CodeError::AsyncPipeListenerFailed)?; Ok(AsyncPipeListener { path: path.to_owned(), server }) } pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) { tokio::io::split(pipe) } } } impl AsyncPipeListener { pub fn into_pollable(self) -> PollableAsyncListener { PollableAsyncListener { listener: Some(self), write_fut: tokio_util::sync::ReusableBoxFuture::new(make_accept_fut(None)), } } } pub struct PollableAsyncListener { listener: Option, write_fut: tokio_util::sync::ReusableBoxFuture< 'static, (AsyncPipeListener, Result), >, } async fn make_accept_fut( data: Option, ) -> (AsyncPipeListener, Result) { match data { Some(mut l) => { let c = l.accept().await; (l, c) } None => unreachable!("this future should not be pollable in this state"), } } impl hyper::server::accept::Accept for PollableAsyncListener { type Conn = AsyncPipe; type Error = CodeError; fn poll_accept( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { if let Some(l) = self.listener.take() { self.write_fut.set(make_accept_fut(Some(l))) } match self.write_fut.poll(cx) { Poll::Ready((l, cnx)) => { self.listener = Some(l); Poll::Ready(Some(cnx)) } Poll::Pending => Poll::Pending, } } } /// Gets a random name for a pipe/socket on the platform pub fn get_socket_name() -> PathBuf { cfg_if::cfg_if! { if #[cfg(unix)] { std::env::temp_dir().join(format!("{}-{}", APPLICATION_NAME, Uuid::new_v4())) } else { PathBuf::from(format!(r"\\.\pipe\{}-{}", APPLICATION_NAME, Uuid::new_v4())) } } } pub type AcceptedRW = ( Box, Box, ); #[async_trait] pub trait AsyncRWAccepter { async fn accept_rw(&mut self) -> Result; } #[async_trait] impl AsyncRWAccepter for AsyncPipeListener { async fn accept_rw(&mut self) -> Result { let pipe = self.accept().await?; let (read, write) = socket_stream_split(pipe); Ok((Box::new(read), Box::new(write))) } } #[async_trait] impl AsyncRWAccepter for TcpListener { async fn accept_rw(&mut self) -> Result { let (stream, _) = self .accept() .await .map_err(CodeError::AsyncPipeListenerFailed)?; let (read, write) = tokio::io::split(stream); Ok((Box::new(read), Box::new(write))) } } ================================================ FILE: cli/src/auth.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::{ constants::{get_default_user_agent, APPLICATION_NAME, IS_INTERACTIVE_CLI, PRODUCT_NAME_LONG}, debug, error, info, log, state::{LauncherPaths, PersistedState}, trace, util::{ errors::{ wrap, AnyError, CodeError, OAuthError, RefreshTokenNotAvailableError, StatusError, WrappedError, }, input::prompt_options, }, warning, }; use async_trait::async_trait; use chrono::{DateTime, Utc}; use gethostname::gethostname; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{cell::Cell, fmt::Display, path::PathBuf, sync::Arc, thread}; use tokio::time::sleep; use tunnels::{ contracts::PROD_FIRST_PARTY_APP_ID, management::{Authorization, AuthorizationProvider, HttpError}, }; #[derive(Deserialize)] struct DeviceCodeResponse { device_code: String, user_code: String, message: Option, verification_uri: String, expires_in: i64, } #[derive(Deserialize, Debug)] struct AuthenticationResponse { access_token: String, refresh_token: Option, expires_in: Option, } #[derive(Deserialize)] struct AuthenticationError { error: String, error_description: Option, } #[derive(clap::ValueEnum, Serialize, Deserialize, Debug, Clone, Copy)] pub enum AuthProvider { Microsoft, Github, } impl Display for AuthProvider { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AuthProvider::Microsoft => write!(f, "Microsoft Account"), AuthProvider::Github => write!(f, "GitHub Account"), } } } impl AuthProvider { pub fn client_id(&self) -> &'static str { match self { AuthProvider::Microsoft => "aebc6443-996d-45c2-90f0-388ff96faa56", AuthProvider::Github => "01ab8ac9400c4e429b23", } } pub fn code_uri(&self) -> &'static str { match self { AuthProvider::Microsoft => { "https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode" } AuthProvider::Github => "https://github.com/login/device/code", } } pub fn grant_uri(&self) -> &'static str { match self { AuthProvider::Microsoft => { "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" } AuthProvider::Github => "https://github.com/login/oauth/access_token", } } pub fn get_default_scopes(&self) -> String { match self { AuthProvider::Microsoft => { format!("{PROD_FIRST_PARTY_APP_ID}/.default+offline_access+profile+openid") } AuthProvider::Github => "read:user+read:org".to_string(), } } } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct StoredCredential { #[serde(rename = "p")] pub(crate) provider: AuthProvider, #[serde(rename = "a")] access_token: String, #[serde(rename = "r")] refresh_token: Option, #[serde(rename = "e")] expires_at: Option>, } const GH_USER_ENDPOINT: &str = "https://api.github.com/user"; async fn get_github_user( client: &reqwest::Client, access_token: &str, ) -> Result { client .get(GH_USER_ENDPOINT) .header("Authorization", format!("token {access_token}")) .header("User-Agent", get_default_user_agent()) .send() .await } impl StoredCredential { pub async fn is_expired(&self, log: &log::Logger, client: &reqwest::Client) -> bool { match self.provider { AuthProvider::Microsoft => self .expires_at .map(|e| Utc::now() + chrono::Duration::minutes(5) > e) .unwrap_or(false), // Make an auth request to Github. Mark the credential as expired // only on a verifiable 4xx code. We don't error on any failed // request since then a drop in connection could "require" a refresh AuthProvider::Github => { let res = get_github_user(client, &self.access_token).await; let res = match res { Ok(r) => r, Err(e) => { warning!(log, "failed to check GitHub token: {}", e); return false; } }; if res.status().is_success() { return false; } let err = StatusError::from_res(res).await; debug!(log, "GitHub token looks expired: {:?}", err); true } } } fn from_response(auth: AuthenticationResponse, provider: AuthProvider) -> Self { StoredCredential { provider, access_token: auth.access_token, refresh_token: auth.refresh_token, expires_at: auth .expires_in .map(|e| Utc::now() + chrono::Duration::seconds(e)), } } } struct StorageWithLastRead { storage: Box, fallback_storage: Option, last_read: Cell, WrappedError>>, } #[derive(Clone)] pub struct Auth { client: reqwest::Client, log: log::Logger, file_storage_path: PathBuf, storage: Arc>>, } trait StorageImplementation: Send + Sync { fn read(&mut self) -> Result, AnyError>; fn store(&mut self, value: StoredCredential) -> Result<(), AnyError>; fn clear(&mut self) -> Result<(), AnyError>; } // unseal decrypts and deserializes the value fn seal(value: &T) -> String where T: Serialize + ?Sized, { let dec = serde_json::to_string(value).expect("expected to serialize"); if std::env::var("VSCODE_CLI_DISABLE_KEYCHAIN_ENCRYPT").is_ok() { return dec; } encrypt(&dec) } // unseal decrypts and deserializes the value fn unseal(value: &str) -> Option where T: DeserializeOwned, { // small back-compat for old unencrypted values, or if VSCODE_CLI_DISABLE_KEYCHAIN_ENCRYPT set if let Ok(v) = serde_json::from_str::(value) { return Some(v); } let dec = decrypt(value)?; serde_json::from_str::(&dec).ok() } #[cfg(target_os = "windows")] const KEYCHAIN_ENTRY_LIMIT: usize = 1024; #[cfg(not(target_os = "windows"))] const KEYCHAIN_ENTRY_LIMIT: usize = 128 * 1024; const CONTINUE_MARKER: &str = ""; /// Implementation that wraps the KeyringStorage on Linux to avoid /// https://github.com/hwchen/keyring-rs/issues/132 struct ThreadKeyringStorage { s: Option, } impl ThreadKeyringStorage { fn thread_op(&mut self, f: Fn) -> Result where Fn: 'static + Send + FnOnce(&mut KeyringStorage) -> Result, R: 'static + Send, { let mut s = match self.s.take() { Some(s) => s, None => return Err(CodeError::KeyringTimeout.into()), }; // It seems like on Linux communication to the keyring can block indefinitely. // Fall back after a 5 second timeout. let (sender, receiver) = std::sync::mpsc::channel(); let tsender = sender.clone(); thread::spawn(move || sender.send(Some((f(&mut s), s)))); thread::spawn(move || { thread::sleep(std::time::Duration::from_secs(5)); let _ = tsender.send(None); }); match receiver.recv().unwrap() { Some((r, s)) => { self.s = Some(s); r } None => Err(CodeError::KeyringTimeout.into()), } } } impl Default for ThreadKeyringStorage { fn default() -> Self { Self { s: Some(KeyringStorage::default()), } } } impl StorageImplementation for ThreadKeyringStorage { fn read(&mut self) -> Result, AnyError> { self.thread_op(|s| s.read()) } fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { self.thread_op(move |s| s.store(value)) } fn clear(&mut self) -> Result<(), AnyError> { self.thread_op(|s| s.clear()) } } #[derive(Default)] struct KeyringStorage { // keyring storage can be split into multiple entries due to entry length limits // on Windows https://github.com/microsoft/vscode-cli/issues/358 entries: Vec, } macro_rules! get_next_entry { ($self: expr, $i: expr) => { match $self.entries.get($i) { Some(e) => e, None => { let e = keyring::Entry::new("vscode-cli", &format!("vscode-cli-{}", $i)).unwrap(); $self.entries.push(e); $self.entries.last().unwrap() } } }; } impl StorageImplementation for KeyringStorage { fn read(&mut self) -> Result, AnyError> { let mut str = String::new(); for i in 0.. { let entry = get_next_entry!(self, i); let next_chunk = match entry.get_password() { Ok(value) => value, Err(keyring::Error::NoEntry) => return Ok(None), // missing entries? Err(e) => return Err(wrap(e, "error reading keyring").into()), }; if next_chunk.ends_with(CONTINUE_MARKER) { str.push_str(&next_chunk[..next_chunk.len() - CONTINUE_MARKER.len()]); } else { str.push_str(&next_chunk); break; } } Ok(unseal(&str)) } fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { let sealed = seal(&value); let step_size = KEYCHAIN_ENTRY_LIMIT - CONTINUE_MARKER.len(); for i in (0..sealed.len()).step_by(step_size) { let entry = get_next_entry!(self, i / step_size); let cutoff = i + step_size; let stored = if cutoff <= sealed.len() { let mut part = sealed[i..cutoff].to_string(); part.push_str(CONTINUE_MARKER); entry.set_password(&part) } else { entry.set_password(&sealed[i..]) }; if let Err(e) = stored { return Err(wrap(e, "error updating keyring").into()); } } Ok(()) } fn clear(&mut self) -> Result<(), AnyError> { self.read().ok(); // make sure component parts are available for entry in self.entries.iter() { entry .delete_password() .map_err(|e| wrap(e, "error updating keyring"))?; } self.entries.clear(); Ok(()) } } struct FileStorage(PersistedState>); impl StorageImplementation for FileStorage { fn read(&mut self) -> Result, AnyError> { Ok(self.0.load().and_then(|s| unseal(&s))) } fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { self.0.save(Some(seal(&value))).map_err(|e| e.into()) } fn clear(&mut self) -> Result<(), AnyError> { self.0.save(None).map_err(|e| e.into()) } } impl Auth { pub fn new(paths: &LauncherPaths, log: log::Logger) -> Auth { Auth { log, client: reqwest::Client::new(), file_storage_path: paths.root().join("token.json"), storage: Arc::new(std::sync::Mutex::new(None)), } } fn with_storage(&self, op: F) -> T where F: FnOnce(&mut StorageWithLastRead) -> T, { let mut opt = self.storage.lock().unwrap(); if let Some(s) = opt.as_mut() { return op(s); } #[cfg(not(target_os = "linux"))] let mut keyring_storage = KeyringStorage::default(); #[cfg(target_os = "linux")] let mut keyring_storage = ThreadKeyringStorage::default(); let mut file_storage = FileStorage(PersistedState::new_with_mode( self.file_storage_path.clone(), 0o600, )); let native_storage_result = if std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN").is_ok() || self.file_storage_path.exists() { Err(wrap("", "user prefers file storage").into()) } else { keyring_storage.read() }; let mut storage = match native_storage_result { Ok(v) => StorageWithLastRead { last_read: Cell::new(Ok(v)), fallback_storage: Some(file_storage), storage: Box::new(keyring_storage), }, Err(e) => { debug!(self.log, "Using file keychain storage due to: {}", e); StorageWithLastRead { last_read: Cell::new( file_storage .read() .map_err(|e| wrap(e, "could not read from file storage")), ), fallback_storage: None, storage: Box::new(file_storage), } } }; let out = op(&mut storage); *opt = Some(storage); out } /// Gets a tunnel Authentication for use in the tunnel management API. pub async fn get_tunnel_authentication(&self) -> Result { let cred = self.get_credential().await?; let auth = match cred.provider { AuthProvider::Microsoft => Authorization::Bearer(cred.access_token), AuthProvider::Github => Authorization::Github(format!( "client_id={} {}", cred.provider.client_id(), cred.access_token )), }; Ok(auth) } /// Reads the current details from the keyring. pub fn get_current_credential(&self) -> Result, WrappedError> { self.with_storage(|storage| { let value = storage.last_read.replace(Ok(None)); storage.last_read.set(value.clone()); value }) } /// Clears login info from the keyring. pub fn clear_credentials(&self) -> Result<(), AnyError> { self.with_storage(|storage| { storage.storage.clear()?; storage.last_read.set(Ok(None)); Ok(()) }) } /// Runs the login flow, optionally pre-filling a provider and/or access token. pub async fn login( &self, provider: Option, access_token: Option, refresh_token: Option, ) -> Result { let provider = match provider { Some(p) => p, None => self.prompt_for_provider().await?, }; let credentials = match access_token { Some(t) => StoredCredential { provider, access_token: t, // if a refresh token is given, assume it's valid now but refresh it // soon in order to get the real expiry time. expires_at: refresh_token .as_ref() .map(|_| Utc::now() + chrono::Duration::minutes(5)), refresh_token, }, None => self.do_device_code_flow_with_provider(provider).await?, }; self.store_credentials(credentials.clone()); Ok(credentials) } /// Gets the currently stored credentials, or asks the user to log in. pub async fn get_credential(&self) -> Result { let entry = match self.get_current_credential() { Ok(Some(old_creds)) => { trace!(self.log, "Found token in keyring"); match self.maybe_refresh_token(&old_creds).await { Ok(Some(new_creds)) => { self.store_credentials(new_creds.clone()); new_creds } Ok(None) => old_creds, Err(e) => { info!(self.log, "error refreshing token: {}", e); let new_creds = self .do_device_code_flow_with_provider(old_creds.provider) .await?; self.store_credentials(new_creds.clone()); new_creds } } } Ok(None) => { trace!(self.log, "No token in keyring, getting a new one"); let creds = self.do_device_code_flow().await?; self.store_credentials(creds.clone()); creds } Err(e) => { warning!( self.log, "Error reading token from keyring, getting a new one: {}", e ); let creds = self.do_device_code_flow().await?; self.store_credentials(creds.clone()); creds } }; Ok(entry) } /// Stores credentials, logging a warning if it fails. fn store_credentials(&self, creds: StoredCredential) { self.with_storage(|storage| { if let Err(e) = storage.storage.store(creds.clone()) { warning!( self.log, "Failed to update keyring with new credentials: {}", e ); if let Some(fb) = storage.fallback_storage.take() { storage.storage = Box::new(fb); match storage.storage.store(creds.clone()) { Err(e) => { warning!(self.log, "Also failed to update fallback storage: {}", e) } Ok(_) => debug!(self.log, "Updated fallback storage successfully"), } } } storage.last_read.set(Ok(Some(creds))); }) } /// Refreshes the token in the credentials if necessary. Returns None if /// the token is up to date, or Some new token otherwise. async fn maybe_refresh_token( &self, creds: &StoredCredential, ) -> Result, AnyError> { if !creds.is_expired(&self.log, &self.client).await { return Ok(None); } self.do_refresh_token(creds).await } /// Refreshes the token in the credentials. Returns an error if the process failed. /// Returns None if the token didn't change. async fn do_refresh_token( &self, creds: &StoredCredential, ) -> Result, AnyError> { match &creds.refresh_token { Some(t) => self .do_grant( creds.provider, format!( "client_id={}&grant_type=refresh_token&refresh_token={}", creds.provider.client_id(), t ), ) .await .map(Some), None => match creds.provider { AuthProvider::Github => self.touch_github_token(creds).await.map(|_| None), _ => Err(RefreshTokenNotAvailableError().into()), }, } } /// Does a "grant token" request. async fn do_grant( &self, provider: AuthProvider, body: String, ) -> Result { let response = self .client .post(provider.grant_uri()) .body(body) .header("Accept", "application/json") .send() .await?; let status_code = response.status().as_u16(); let body = response.bytes().await?; if let Ok(body) = serde_json::from_slice::(&body) { return Ok(StoredCredential::from_response(body, provider)); } Err(Auth::handle_grant_error( provider.grant_uri(), status_code, body, )) } /// GH doesn't have a refresh token, but does limit to the 10 most recently /// used tokens per user (#9052), so for the github "refresh" just request /// the current user. async fn touch_github_token(&self, credential: &StoredCredential) -> Result<(), AnyError> { let response = get_github_user(&self.client, &credential.access_token).await?; if response.status().is_success() { return Ok(()); } let status_code = response.status().as_u16(); let body = response.bytes().await?; Err(Auth::handle_grant_error( GH_USER_ENDPOINT, status_code, body, )) } fn handle_grant_error(url: &str, status_code: u16, body: bytes::Bytes) -> AnyError { if let Ok(res) = serde_json::from_slice::(&body) { return OAuthError { error: res.error, error_description: res.error_description, } .into(); } StatusError { body: String::from_utf8_lossy(&body).to_string(), status_code, url: url.to_string(), } .into() } /// Implements the device code flow, returning the credentials upon success. async fn do_device_code_flow(&self) -> Result { let provider = self.prompt_for_provider().await?; self.do_device_code_flow_with_provider(provider).await } async fn prompt_for_provider(&self) -> Result { if !*IS_INTERACTIVE_CLI { info!( self.log, "Using GitHub for authentication, run `{} tunnel user login --provider ` option to change this.", APPLICATION_NAME ); return Ok(AuthProvider::Github); } let provider = prompt_options( format!("How would you like to log in to {PRODUCT_NAME_LONG}?"), &[AuthProvider::Microsoft, AuthProvider::Github], )?; Ok(provider) } async fn do_device_code_flow_with_provider( &self, provider: AuthProvider, ) -> Result { loop { let init_code = self .client .post(provider.code_uri()) .header("Accept", "application/json") .body(format!( "client_id={}&scope={}", provider.client_id(), provider.get_default_scopes(), )) .send() .await?; if !init_code.status().is_success() { return Err(StatusError::from_res(init_code).await?.into()); } let init_code_json = init_code.json::().await?; let expires_at = Utc::now() + chrono::Duration::seconds(init_code_json.expires_in); match &init_code_json.message { Some(m) => self.log.result(m), None => self.log.result(format!( "To grant access to the server, please log into {} and use code {}", init_code_json.verification_uri, init_code_json.user_code )), }; let body = format!( "client_id={}&grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code={}", provider.client_id(), init_code_json.device_code ); let mut interval_s = 5; while Utc::now() < expires_at { sleep(std::time::Duration::from_secs(interval_s)).await; match self.do_grant(provider, body.clone()).await { Ok(creds) => return Ok(creds), Err(AnyError::OAuthError(e)) if e.error == "slow_down" => { interval_s += 5; // https://www.rfc-editor.org/rfc/rfc8628#section-3.5 trace!(self.log, "refresh poll failed, slowing down"); } // Github returns a non-standard 429 to slow down Err(AnyError::StatusError(e)) if e.status_code == 429 => { interval_s += 5; // https://www.rfc-editor.org/rfc/rfc8628#section-3.5 trace!(self.log, "refresh poll failed, slowing down"); } Err(e) => { trace!(self.log, "refresh poll failed, retrying: {}", e); } } } } } /// Maintains the stored credential by refreshing it against the service /// to ensure its stays current. Returns a future that should be polled and /// only errors if a refresh fails in a consistent way. pub async fn keep_token_alive(self) -> Result<(), AnyError> { let this = self.clone(); let default_refresh = std::time::Duration::from_secs(60 * 60); let min_refresh = std::time::Duration::from_secs(10); let mut credential = this.get_credential().await?; let mut last_did_error = false; loop { let sleep_time = if last_did_error { min_refresh } else { match credential.expires_at { Some(d) => ((d - Utc::now()) * 2 / 3).to_std().unwrap_or(min_refresh), None => default_refresh, } }; // to_std errors on negative duration, fall back to a 60s refresh tokio::time::sleep(sleep_time.max(min_refresh)).await; match this.do_refresh_token(&credential).await { // 4xx error means this token is probably not good any mode Err(AnyError::StatusError(e)) if e.status_code >= 400 && e.status_code < 500 => { error!(this.log, "failed to keep token alive: {:?}", e); return Err(e.into()); } Err(AnyError::RefreshTokenNotAvailableError(_)) => { return Ok(()); } Err(e) => { warning!(this.log, "error refreshing token: {:?}", e); last_did_error = true; continue; } Ok(c) => { trace!(this.log, "token was successfully refreshed in keepalive"); last_did_error = false; if let Some(c) = c { this.store_credentials(c.clone()); credential = c; } } } } } } #[async_trait] impl AuthorizationProvider for Auth { async fn get_authorization(&self) -> Result { self.get_tunnel_authentication() .await .map_err(|e| HttpError::AuthorizationError(e.to_string())) } } lazy_static::lazy_static! { static ref HOSTNAME: Vec = gethostname().to_string_lossy().bytes().collect(); } #[cfg(feature = "vscode-encrypt")] fn encrypt(value: &str) -> String { vscode_encrypt::encrypt(&HOSTNAME, value.as_bytes()).expect("expected to encrypt") } #[cfg(feature = "vscode-encrypt")] fn decrypt(value: &str) -> Option { let b = vscode_encrypt::decrypt(&HOSTNAME, value).ok()?; String::from_utf8(b).ok() } #[cfg(not(feature = "vscode-encrypt"))] fn encrypt(value: &str) -> String { value.to_owned() } #[cfg(not(feature = "vscode-encrypt"))] fn decrypt(value: &str) -> Option { Some(value.to_owned()) } ================================================ FILE: cli/src/bin/code/legacy_args.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::collections::HashMap; use cli::commands::args::{ CliCore, Commands, DesktopCodeOptions, ExtensionArgs, ExtensionSubcommand, InstallExtensionArgs, ListExtensionArgs, UninstallExtensionArgs, }; /// Tries to parse the argv using the legacy CLI interface, looking for its /// flags and generating a CLI with subcommands if those don't exist. pub fn try_parse_legacy( iter: impl IntoIterator>, ) -> Option { let raw = clap_lex::RawArgs::new(iter); let mut cursor = raw.cursor(); raw.next(&mut cursor); // Skip the bin // First make a hashmap of all flags and capture positional arguments. let mut args: HashMap> = HashMap::new(); let mut last_arg = None; while let Some(arg) = raw.next(&mut cursor) { if let Some((long, value)) = arg.to_long() { if let Ok(long) = long { last_arg = Some(long.to_string()); match args.get_mut(long) { Some(prev) => { if let Some(v) = value { prev.push(v.to_string_lossy().to_string()); } } None => { if let Some(v) = value { args.insert(long.to_string(), vec![v.to_string_lossy().to_string()]); } else { args.insert(long.to_string(), vec![]); } } } } } else if let Ok(value) = arg.to_value() { if value == "tunnel" { return None; } if let Some(last_arg) = &last_arg { args.get_mut(last_arg) .expect("expected to have last arg") .push(value.to_string()); } } } let get_first_arg_value = |key: &str| args.get(key).and_then(|v| v.first()).map(|s| s.to_string()); let desktop_code_options = DesktopCodeOptions { extensions_dir: get_first_arg_value("extensions-dir"), user_data_dir: get_first_arg_value("user-data-dir"), use_version: None, }; // Now translate them to subcommands. // --list-extensions -> ext list // --update-extensions -> update // --install-extension=id -> ext install // --uninstall-extension=id -> ext uninstall // --status -> status if args.contains_key("list-extensions") { Some(CliCore { subcommand: Some(Commands::Extension(ExtensionArgs { subcommand: ExtensionSubcommand::List(ListExtensionArgs { category: get_first_arg_value("category"), show_versions: args.contains_key("show-versions"), }), desktop_code_options, })), ..Default::default() }) } else if let Some(exts) = args.remove("install-extension") { Some(CliCore { subcommand: Some(Commands::Extension(ExtensionArgs { subcommand: ExtensionSubcommand::Install(InstallExtensionArgs { id_or_path: exts, pre_release: args.contains_key("pre-release"), donot_include_pack_and_dependencies: args .contains_key("do-not-include-pack-dependencies"), force: args.contains_key("force"), }), desktop_code_options, })), ..Default::default() }) } else if let Some(_exts) = args.remove("update-extensions") { Some(CliCore { subcommand: Some(Commands::Extension(ExtensionArgs { subcommand: ExtensionSubcommand::Update, desktop_code_options, })), ..Default::default() }) } else if let Some(exts) = args.remove("uninstall-extension") { Some(CliCore { subcommand: Some(Commands::Extension(ExtensionArgs { subcommand: ExtensionSubcommand::Uninstall(UninstallExtensionArgs { id: exts }), desktop_code_options, })), ..Default::default() }) } else if args.contains_key("status") { Some(CliCore { subcommand: Some(Commands::Status), ..Default::default() }) } else { None } } #[cfg(test)] mod tests { use super::*; #[test] fn test_parses_list_extensions() { let args = vec![ "code", "--list-extensions", "--category", "themes", "--show-versions", ]; let cli = try_parse_legacy(args).unwrap(); if let Some(Commands::Extension(extension_args)) = cli.subcommand { if let ExtensionSubcommand::List(list_args) = extension_args.subcommand { assert_eq!(list_args.category, Some("themes".to_string())); assert!(list_args.show_versions); } else { panic!( "Expected list subcommand, got {:?}", extension_args.subcommand ); } } else { panic!("Expected extension subcommand, got {:?}", cli.subcommand); } } #[test] fn test_parses_install_extension() { let args = vec![ "code", "--install-extension", "connor4312.codesong", "connor4312.hello-world", "--pre-release", "--force", ]; let cli = try_parse_legacy(args).unwrap(); if let Some(Commands::Extension(extension_args)) = cli.subcommand { if let ExtensionSubcommand::Install(install_args) = extension_args.subcommand { assert_eq!( install_args.id_or_path, vec!["connor4312.codesong", "connor4312.hello-world"] ); assert!(install_args.pre_release); assert!(install_args.force); } else { panic!( "Expected install subcommand, got {:?}", extension_args.subcommand ); } } else { panic!("Expected extension subcommand, got {:?}", cli.subcommand); } } #[test] fn test_parses_uninstall_extension() { let args = vec!["code", "--uninstall-extension", "connor4312.codesong"]; let cli = try_parse_legacy(args).unwrap(); if let Some(Commands::Extension(extension_args)) = cli.subcommand { if let ExtensionSubcommand::Uninstall(uninstall_args) = extension_args.subcommand { assert_eq!(uninstall_args.id, vec!["connor4312.codesong"]); } else { panic!( "Expected uninstall subcommand, got {:?}", extension_args.subcommand ); } } else { panic!("Expected extension subcommand, got {:?}", cli.subcommand); } } #[test] fn test_parses_user_data_dir_and_extensions_dir() { let args = vec![ "code", "--uninstall-extension", "connor4312.codesong", "--user-data-dir", "foo", "--extensions-dir", "bar", ]; let cli = try_parse_legacy(args).unwrap(); if let Some(Commands::Extension(extension_args)) = cli.subcommand { assert_eq!( extension_args.desktop_code_options.user_data_dir, Some("foo".to_string()) ); assert_eq!( extension_args.desktop_code_options.extensions_dir, Some("bar".to_string()) ); if let ExtensionSubcommand::Uninstall(uninstall_args) = extension_args.subcommand { assert_eq!(uninstall_args.id, vec!["connor4312.codesong"]); } else { panic!( "Expected uninstall subcommand, got {:?}", extension_args.subcommand ); } } else { panic!("Expected extension subcommand, got {:?}", cli.subcommand); } } #[test] fn test_status() { let args = vec!["code", "--status"]; let cli = try_parse_legacy(args).unwrap(); if let Some(Commands::Status) = cli.subcommand { // no-op } else { panic!("Expected extension subcommand, got {:?}", cli.subcommand); } } } ================================================ FILE: cli/src/bin/code/main.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ mod legacy_args; use std::process::Command; use clap::Parser; use cli::{ commands::{args, serve_web, tunnels, update, version, CommandContext}, constants::get_default_user_agent, desktop, log, state::LauncherPaths, util::{ errors::{wrap, AnyError}, is_integrated_cli, prereqs::PreReqChecker, }, }; use legacy_args::try_parse_legacy; use opentelemetry::sdk::trace::TracerProvider as SdkTracerProvider; use opentelemetry::trace::TracerProvider; #[tokio::main] async fn main() -> Result<(), std::convert::Infallible> { let raw_args = std::env::args_os().collect::>(); let parsed = try_parse_legacy(&raw_args) .map(|core| args::AnyCli::Integrated(args::IntegratedCli { core })) .unwrap_or_else(|| { if let Ok(true) = is_integrated_cli() { args::AnyCli::Integrated(args::IntegratedCli::parse_from(&raw_args)) } else { args::AnyCli::Standalone(args::StandaloneCli::parse_from(&raw_args)) } }); let core = parsed.core(); let context_paths = LauncherPaths::migrate(core.global_options.cli_data_dir.clone()).unwrap(); let context_args = core.clone(); // gets a command context without installing the global logger let context_no_logger = || CommandContext { http: reqwest::ClientBuilder::new() .user_agent(get_default_user_agent()) .build() .unwrap(), paths: context_paths, log: make_logger(&context_args), args: context_args, }; // gets a command context with the global logger installer. Usually what most commands want. macro_rules! context { () => {{ let context = context_no_logger(); log::install_global_logger(context.log.clone()); context }}; } let result = match parsed { args::AnyCli::Standalone(args::StandaloneCli { subcommand: Some(cmd), .. }) => match cmd { args::StandaloneCommands::Update(args) => update::update(context!(), args).await, }, args::AnyCli::Standalone(args::StandaloneCli { core: c, .. }) | args::AnyCli::Integrated(args::IntegratedCli { core: c, .. }) => match c.subcommand { None => { let context = context!(); let ca = context.args.get_base_code_args(); start_code(context, ca).await } Some(args::Commands::Extension(extension_args)) => { let context = context!(); let mut ca = context.args.get_base_code_args(); extension_args.add_code_args(&mut ca); start_code(context, ca).await } Some(args::Commands::Status) => { let context = context!(); let mut ca = context.args.get_base_code_args(); ca.push("--status".to_string()); start_code(context, ca).await } Some(args::Commands::Version(version_args)) => match version_args.subcommand { args::VersionSubcommand::Use(use_version_args) => { version::switch_to(context!(), use_version_args).await } args::VersionSubcommand::Show => version::show(context!()).await, }, Some(args::Commands::CommandShell(cs_args)) => { tunnels::command_shell(context!(), cs_args).await } Some(args::Commands::ServeWeb(sw_args)) => { serve_web::serve_web(context!(), sw_args).await } Some(args::Commands::Tunnel(mut tunnel_args)) => match tunnel_args.subcommand.take() { Some(args::TunnelSubcommand::Prune) => tunnels::prune(context!()).await, Some(args::TunnelSubcommand::Unregister) => tunnels::unregister(context!()).await, Some(args::TunnelSubcommand::Kill) => tunnels::kill(context!()).await, Some(args::TunnelSubcommand::Restart) => tunnels::restart(context!()).await, Some(args::TunnelSubcommand::Status) => tunnels::status(context!()).await, Some(args::TunnelSubcommand::Rename(rename_args)) => { tunnels::rename(context!(), rename_args).await } Some(args::TunnelSubcommand::User(user_command)) => { tunnels::user(context!(), user_command).await } Some(args::TunnelSubcommand::Service(service_args)) => { tunnels::service(context_no_logger(), tunnel_args, service_args).await } Some(args::TunnelSubcommand::ForwardInternal(forward_args)) => { tunnels::forward(context_no_logger(), forward_args).await } None => tunnels::serve(context_no_logger(), tunnel_args.serve_args).await, }, }, }; match result { Err(e) => print_and_exit(e), Ok(code) => std::process::exit(code), } } fn make_logger(core: &args::CliCore) -> log::Logger { let log_level = if core.global_options.verbose { log::Level::Trace } else { core.global_options.log.unwrap_or(log::Level::Info) }; let tracer = SdkTracerProvider::builder().build().tracer("codecli"); let mut log = log::Logger::new(tracer, log_level); if let Some(f) = &core.global_options.log_to_file { log = log .with_sink(log::FileLogSink::new(log_level, f).expect("expected to make file logger")) } log } fn print_and_exit(err: E) -> ! where E: std::fmt::Display, { log::emit(log::Level::Error, "", &format!("{err}")); std::process::exit(1); } async fn start_code(context: CommandContext, args: Vec) -> Result { // todo: once the integrated CLI takes the place of the Node.js CLI, this should // redirect to the current installation without using the CodeVersionManager. let platform = PreReqChecker::new().verify().await?; let version_manager = desktop::CodeVersionManager::new(context.log.clone(), &context.paths, platform); let version = match &context.args.editor_options.code_options.use_version { Some(v) => desktop::RequestedVersion::try_from(v.as_str())?, None => version_manager.get_preferred_version(), }; let binary = match version_manager.try_get_entrypoint(&version).await { Some(ep) => ep, None => { desktop::prompt_to_install(&version); return Ok(1); } }; let code = Command::new(&binary) .args(args) .status() .map(|s| s.code().unwrap_or(1)) .map_err(|e| wrap(e, format!("error running editor from {}", binary.display())))?; Ok(code) } ================================================ FILE: cli/src/commands/args.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{fmt, path::PathBuf}; use crate::{constants, log, options, tunnels::code_server::CodeServerArgs}; use clap::{Args, Parser, Subcommand, ValueEnum}; use const_format::concatcp; const CLI_NAME: &str = concatcp!(constants::PRODUCT_NAME_LONG, " CLI"); const HELP_COMMANDS: &str = concatcp!( "Usage: ", constants::APPLICATION_NAME, " [options][paths...] To read output from another program, append '-' (e.g. 'echo Hello World | {name} -')" ); const STANDALONE_TEMPLATE: &str = concatcp!( CLI_NAME, " Standalone - {version} ", HELP_COMMANDS, " Running editor commands requires installing ", constants::QUALITYLESS_PRODUCT_NAME, ", and may differ slightly. {all-args}" ); const INTEGRATED_TEMPLATE: &str = concatcp!( CLI_NAME, " - {version} ", HELP_COMMANDS, " {all-args}" ); const COMMIT_IN_VERSION: &str = match constants::VSCODE_CLI_COMMIT { Some(c) => c, None => "unknown", }; const NUMBER_IN_VERSION: &str = match constants::VSCODE_CLI_VERSION { Some(c) => c, None => "dev", }; const VERSION: &str = concatcp!(NUMBER_IN_VERSION, " (commit ", COMMIT_IN_VERSION, ")"); #[derive(Parser, Debug, Default)] #[clap( help_template = INTEGRATED_TEMPLATE, long_about = None, name = constants::APPLICATION_NAME, version = VERSION, )] pub struct IntegratedCli { #[clap(flatten)] pub core: CliCore, } /// Common CLI shared between integrated and standalone interfaces. #[derive(Args, Debug, Default, Clone)] pub struct CliCore { /// One or more files, folders, or URIs to open. #[clap(name = "paths")] pub open_paths: Vec, #[clap(flatten, next_help_heading = Some("EDITOR OPTIONS"))] pub editor_options: EditorOptions, #[clap(flatten, next_help_heading = Some("EDITOR TROUBLESHOOTING"))] pub troubleshooting: EditorTroubleshooting, #[clap(flatten, next_help_heading = Some("GLOBAL OPTIONS"))] pub global_options: GlobalOptions, #[clap(subcommand)] pub subcommand: Option, } #[derive(Parser, Debug, Default)] #[clap( help_template = STANDALONE_TEMPLATE, long_about = None, version = VERSION, name = constants::APPLICATION_NAME, )] pub struct StandaloneCli { #[clap(flatten)] pub core: CliCore, #[clap(subcommand)] pub subcommand: Option, } pub enum AnyCli { Integrated(IntegratedCli), Standalone(StandaloneCli), } impl AnyCli { pub fn core(&self) -> &CliCore { match self { AnyCli::Integrated(cli) => &cli.core, AnyCli::Standalone(cli) => &cli.core, } } } impl CliCore { pub fn get_base_code_args(&self) -> Vec { let mut args = self.open_paths.clone(); self.editor_options.add_code_args(&mut args); self.troubleshooting.add_code_args(&mut args); self.global_options.add_code_args(&mut args); args } } impl<'a> From<&'a CliCore> for CodeServerArgs { fn from(cli: &'a CliCore) -> Self { let mut args = CodeServerArgs { log: cli.global_options.log, accept_server_license_terms: true, ..Default::default() }; args.log = cli.global_options.log; args.accept_server_license_terms = true; if cli.global_options.verbose { args.verbose = true; } if cli.global_options.disable_telemetry { args.telemetry_level = Some(options::TelemetryLevel::Off); } else if cli.global_options.telemetry_level.is_some() { args.telemetry_level = cli.global_options.telemetry_level; } args } } #[derive(Subcommand, Debug, Clone)] pub enum StandaloneCommands { /// Updates the CLI. Update(StandaloneUpdateArgs), } #[derive(Args, Debug, Clone)] pub struct StandaloneUpdateArgs { /// Only check for updates, without actually updating the CLI. #[clap(long)] pub check: bool, } #[derive(Subcommand, Debug, Clone)] pub enum Commands { /// Create a tunnel that's accessible on vscode.dev from anywhere. /// Run `code tunnel --help` for more usage info. Tunnel(TunnelArgs), /// Manage editor extensions. #[clap(name = "ext")] Extension(ExtensionArgs), /// Print process usage and diagnostics information. Status, /// Changes the version of the editor you're using. Version(VersionArgs), /// Runs a local web version of VS Code. #[clap(about = concatcp!("Runs a local web version of ", constants::PRODUCT_NAME_LONG))] ServeWeb(ServeWebArgs), /// Runs the control server on process stdin/stdout #[clap(hide = true)] CommandShell(CommandShellArgs), } #[derive(Args, Debug, Clone)] pub struct ServeWebArgs { /// Host to listen on, defaults to 'localhost' #[clap(long)] pub host: Option, // The path to a socket file for the server to listen to. #[clap(long)] pub socket_path: Option, /// Port to listen on. If 0 is passed a random free port is picked. #[clap(long, default_value_t = 8000)] pub port: u16, /// A secret that must be included with all requests. #[clap(long)] pub connection_token: Option, /// A file containing a secret that must be included with all requests. #[clap(long)] pub connection_token_file: Option, /// Run without a connection token. Only use this if the connection is secured by other means. #[clap(long)] pub without_connection_token: bool, /// If set, the user accepts the server license terms and the server will be started without a user prompt. #[clap(long)] pub accept_server_license_terms: bool, /// Specifies the path under which the web UI and the code server is provided. #[clap(long)] pub server_base_path: Option, /// Specifies the directory that server data is kept in. #[clap(long)] pub server_data_dir: Option, } #[derive(Args, Debug, Clone)] pub struct CommandShellArgs { #[clap(flatten)] pub server_args: BaseServerArgs, /// Listen on a socket instead of stdin/stdout. #[clap(long)] pub on_socket: bool, /// Listen on a host/port instead of stdin/stdout. #[clap(long, num_args = 0..=2, default_missing_value = "0")] pub on_port: Vec, /// Listen on a host/port instead of stdin/stdout. #[clap[long]] pub on_host: Option, /// Require the given token string to be given in the handshake. #[clap(long, env = "VSCODE_CLI_REQUIRE_TOKEN")] pub require_token: Option, /// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists #[clap(long, hide = true)] pub parent_process_id: Option, } #[derive(Args, Debug, Clone)] pub struct ExtensionArgs { #[clap(subcommand)] pub subcommand: ExtensionSubcommand, #[clap(flatten)] pub desktop_code_options: DesktopCodeOptions, } impl ExtensionArgs { pub fn add_code_args(&self, target: &mut Vec) { self.desktop_code_options.add_code_args(target); self.subcommand.add_code_args(target); } } #[derive(Subcommand, Debug, Clone)] pub enum ExtensionSubcommand { /// List installed extensions. List(ListExtensionArgs), /// Install an extension. Install(InstallExtensionArgs), /// Uninstall an extension. Uninstall(UninstallExtensionArgs), /// Update the installed extensions. Update, } impl ExtensionSubcommand { pub fn add_code_args(&self, target: &mut Vec) { match self { ExtensionSubcommand::List(args) => { target.push("--list-extensions".to_string()); if args.show_versions { target.push("--show-versions".to_string()); } if let Some(category) = &args.category { target.push(format!("--category={category}")); } } ExtensionSubcommand::Install(args) => { for id in args.id_or_path.iter() { target.push(format!("--install-extension={id}")); } if args.pre_release { target.push("--pre-release".to_string()); } if args.donot_include_pack_and_dependencies { target.push("do-not-include-pack-dependencies".to_string()); } if args.force { target.push("--force".to_string()); } } ExtensionSubcommand::Uninstall(args) => { for id in args.id.iter() { target.push(format!("--uninstall-extension={id}")); } } ExtensionSubcommand::Update => { target.push("--update-extensions".to_string()); } } } } #[derive(Args, Debug, Clone)] pub struct ListExtensionArgs { /// Filters installed extensions by provided category, when using --list-extensions. #[clap(long, value_name = "category")] pub category: Option, /// Show versions of installed extensions, when using --list-extensions. #[clap(long)] pub show_versions: bool, } #[derive(Args, Debug, Clone)] pub struct InstallExtensionArgs { /// Either an extension id or a path to a VSIX. The identifier of an /// extension is '${publisher}.${name}'. Use '--force' argument to update /// to latest version. To install a specific version provide '@${version}'. /// For example: 'vscode.csharp@1.2.3'. #[clap(name = "ext-id | id")] pub id_or_path: Vec, /// Installs the pre-release version of the extension #[clap(long)] pub pre_release: bool, /// Don't include installing pack and dependencies of the extension #[clap(long)] pub donot_include_pack_and_dependencies: bool, /// Update to the latest version of the extension if it's already installed. #[clap(long)] pub force: bool, } #[derive(Args, Debug, Clone)] pub struct UninstallExtensionArgs { /// One or more extension identifiers to uninstall. The identifier of an /// extension is '${publisher}.${name}'. Use '--force' argument to update /// to latest version. #[clap(name = "ext-id")] pub id: Vec, } #[derive(Args, Debug, Clone)] pub struct VersionArgs { #[clap(subcommand)] pub subcommand: VersionSubcommand, } #[derive(Subcommand, Debug, Clone)] pub enum VersionSubcommand { /// Switches the version of the editor in use. Use(UseVersionArgs), /// Shows the currently configured editor version. Show, } #[derive(Args, Debug, Clone)] pub struct UseVersionArgs { /// The version of the editor you want to use. Can be "stable", "insiders", /// or an absolute path to an existing install. #[clap(value_name = "stable | insiders | x.y.z | path")] pub name: String, /// The directory where the version can be found. #[clap(long, value_name = "path")] pub install_dir: Option, } #[derive(Args, Debug, Default, Clone)] pub struct EditorOptions { /// Compare two files with each other. #[clap(short, long, value_names = &["file", "file"])] pub diff: Vec, /// Add folder(s) to the last active window. #[clap(short, long, value_name = "folder")] pub add: Option, /// Open a file at the path on the specified line and character position. #[clap(short, long, value_name = "file:line[:character]")] pub goto: Option, /// Force to open a new window. #[clap(short, long)] pub new_window: bool, /// Force to open a file or folder in an #[clap(short, long)] pub reuse_window: bool, /// Wait for the files to be closed before returning. #[clap(short, long)] pub wait: bool, /// The locale to use (e.g. en-US or zh-TW). #[clap(long, value_name = "locale")] pub locale: Option, /// Enables proposed API features for extensions. Can receive one or /// more extension IDs to enable individually. #[clap(long, value_name = "ext-id")] pub enable_proposed_api: Vec, #[clap(flatten)] pub code_options: DesktopCodeOptions, } impl EditorOptions { pub fn add_code_args(&self, target: &mut Vec) { if !self.diff.is_empty() { target.push("--diff".to_string()); for file in self.diff.iter() { target.push(file.clone()); } } if let Some(add) = &self.add { target.push("--add".to_string()); target.push(add.clone()); } if let Some(goto) = &self.goto { target.push("--goto".to_string()); target.push(goto.clone()); } if self.new_window { target.push("--new-window".to_string()); } if self.reuse_window { target.push("--reuse-window".to_string()); } if self.wait { target.push("--wait".to_string()); } if let Some(locale) = &self.locale { target.push(format!("--locale={locale}")); } if !self.enable_proposed_api.is_empty() { for id in self.enable_proposed_api.iter() { target.push(format!("--enable-proposed-api={id}")); } } self.code_options.add_code_args(target); } } /// Arguments applicable whenever the desktop editor is launched #[derive(Args, Debug, Default, Clone)] pub struct DesktopCodeOptions { /// Set the root path for extensions. #[clap(long, value_name = "dir")] pub extensions_dir: Option, /// Specifies the directory that user data is kept in. Can be used to /// open multiple distinct instances of the editor. #[clap(long, value_name = "dir")] pub user_data_dir: Option, /// Sets the editor version to use for this command. The preferred version /// can be persisted with `code version use `. Can be "stable", /// "insiders", a version number, or an absolute path to an existing install. #[clap(long, value_name = "stable | insiders | x.y.z | path")] pub use_version: Option, } /// Argument specifying the output format. #[derive(Args, Debug, Clone)] pub struct OutputFormatOptions { /// Set the data output formats. #[clap(value_enum, long, value_name = "format", default_value_t = OutputFormat::Text)] pub format: OutputFormat, } impl DesktopCodeOptions { pub fn add_code_args(&self, target: &mut Vec) { if let Some(extensions_dir) = &self.extensions_dir { target.push(format!("--extensions-dir={extensions_dir}")); } if let Some(user_data_dir) = &self.user_data_dir { target.push(format!("--user-data-dir={user_data_dir}")); } } } #[derive(Args, Debug, Default, Clone)] pub struct GlobalOptions { /// Directory where CLI metadata should be stored. #[clap(long, env = "VSCODE_CLI_DATA_DIR", global = true)] pub cli_data_dir: Option, /// Print verbose output (implies --wait). #[clap(long, global = true)] pub verbose: bool, /// Log to a file in addition to stdout. Used when running as a service. #[clap(long, global = true, hide = true)] pub log_to_file: Option, /// Log level to use. #[clap(long, value_enum, value_name = "level", global = true)] pub log: Option, /// Disable telemetry for the current command, even if it was previously /// accepted as part of the license prompt or specified in '--telemetry-level' #[clap(long, global = true, hide = true)] pub disable_telemetry: bool, /// Sets the initial telemetry level #[clap(value_enum, long, global = true, hide = true)] pub telemetry_level: Option, } impl GlobalOptions { pub fn add_code_args(&self, target: &mut Vec) { if self.verbose { target.push("--verbose".to_string()); } if let Some(log) = self.log { target.push(format!("--log={log}")); } if self.disable_telemetry { target.push("--disable-telemetry".to_string()); } if let Some(telemetry_level) = &self.telemetry_level { target.push(format!("--telemetry-level={telemetry_level}")); } } } #[derive(Args, Debug, Default, Clone)] pub struct EditorTroubleshooting { /// Run CPU profiler during startup. #[clap(long)] pub prof_startup: bool, /// Disable all installed extensions. #[clap(long)] pub disable_extensions: bool, /// Disable an extension. #[clap(long, value_name = "ext-id")] pub disable_extension: Vec, /// Turn sync on or off. #[clap(value_enum, long, value_name = "on | off")] pub sync: Option, /// Allow debugging and profiling of extensions. Check the developer tools for the connection URI. #[clap(long, value_name = "port")] pub inspect_extensions: Option, /// Allow debugging and profiling of extensions with the extension host /// being paused after start. Check the developer tools for the connection URI. #[clap(long, value_name = "port")] pub inspect_brk_extensions: Option, /// Disable GPU hardware acceleration. #[clap(long)] pub disable_gpu: bool, /// Shows all telemetry events which the editor collects. #[clap(long)] pub telemetry: bool, } impl EditorTroubleshooting { pub fn add_code_args(&self, target: &mut Vec) { if self.prof_startup { target.push("--prof-startup".to_string()); } if self.disable_extensions { target.push("--disable-extensions".to_string()); } for id in self.disable_extension.iter() { target.push(format!("--disable-extension={id}")); } if let Some(sync) = &self.sync { target.push(format!("--sync={sync}")); } if let Some(port) = &self.inspect_extensions { target.push(format!("--inspect-extensions={port}")); } if let Some(port) = &self.inspect_brk_extensions { target.push(format!("--inspect-brk-extensions={port}")); } if self.disable_gpu { target.push("--disable-gpu".to_string()); } if self.telemetry { target.push("--telemetry".to_string()); } } } #[derive(ValueEnum, Clone, Copy, Debug)] pub enum SyncState { On, Off, } impl fmt::Display for SyncState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { SyncState::Off => write!(f, "off"), SyncState::On => write!(f, "on"), } } } #[derive(ValueEnum, Clone, Copy, Debug)] pub enum OutputFormat { Json, Text, } #[derive(Args, Clone, Debug, Default)] pub struct ExistingTunnelArgs { /// Name you'd like to assign preexisting tunnel to use to connect the tunnel /// Old option, new code should just use `--name`. #[clap(long, hide = true)] pub tunnel_name: Option, /// Token to authenticate and use preexisting tunnel #[clap(long, hide = true)] pub host_token: Option, /// ID of preexisting tunnel to use to connect the tunnel #[clap(long, hide = true)] pub tunnel_id: Option, /// Cluster of preexisting tunnel to use to connect the tunnel #[clap(long, hide = true)] pub cluster: Option, } #[derive(Args, Debug, Clone, Default)] pub struct TunnelServeArgs { #[clap(flatten)] pub server_args: BaseServerArgs, /// Optional details to connect to an existing tunnel #[clap(flatten, next_help_heading = Some("ADVANCED OPTIONS"))] pub tunnel: ExistingTunnelArgs, /// Randomly name machine for port forwarding service #[clap(long)] pub random_name: bool, /// Prevents the machine going to sleep while this command runs. #[clap(long)] pub no_sleep: bool, /// Sets the machine name for port forwarding service #[clap(long)] pub name: Option, /// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists #[clap(long, hide = true)] pub parent_process_id: Option, /// If set, the user accepts the server license terms and the server will be started without a user prompt. #[clap(long)] pub accept_server_license_terms: bool, } #[derive(Args, Debug, Clone, Default)] pub struct BaseServerArgs { /// Requests that extensions be preloaded and installed on connecting servers. #[clap(long)] pub install_extension: Vec, /// Specifies the directory that server data is kept in. #[clap(long)] pub server_data_dir: Option, /// Set the root path for extensions. #[clap(long)] pub extensions_dir: Option, } impl BaseServerArgs { pub fn apply_to(&self, csa: &mut CodeServerArgs) { csa.install_extensions .extend_from_slice(&self.install_extension); if let Some(d) = &self.server_data_dir { csa.server_data_dir = Some(d.clone()); } if let Some(d) = &self.extensions_dir { csa.extensions_dir = Some(d.clone()); } } } #[derive(Args, Debug, Clone)] pub struct TunnelArgs { #[clap(subcommand)] pub subcommand: Option, #[clap(flatten)] pub serve_args: TunnelServeArgs, } #[derive(Subcommand, Debug, Clone)] pub enum TunnelSubcommand { /// Delete all servers which are currently not running. Prune, /// Stops any running tunnel on the system. Kill, /// Restarts any running tunnel on the system. Restart, /// Gets whether there is a tunnel running on the current machine. Status, /// Rename the name of this machine associated with port forwarding service. Rename(TunnelRenameArgs), /// Remove this machine's association with the port forwarding service. Unregister, #[clap(subcommand)] User(TunnelUserSubCommands), /// (Preview) Manages the tunnel when installed as a system service, #[clap(subcommand)] Service(TunnelServiceSubCommands), /// (Preview) Forwards local port using the dev tunnel #[clap(hide = true)] ForwardInternal(TunnelForwardArgs), } #[derive(Subcommand, Debug, Clone)] pub enum TunnelServiceSubCommands { /// Installs or re-installs the tunnel service on the machine. Install(TunnelServiceInstallArgs), /// Uninstalls and stops the tunnel service. Uninstall, /// Shows logs for the running service. Log, /// Internal command for running the service #[clap(hide = true)] InternalRun, } #[derive(Args, Debug, Clone)] pub struct TunnelServiceInstallArgs { /// If set, the user accepts the server license terms and the server will be started without a user prompt. #[clap(long)] pub accept_server_license_terms: bool, /// Sets the machine name for port forwarding service #[clap(long)] pub name: Option, } #[derive(Args, Debug, Clone)] pub struct TunnelRenameArgs { /// The name you'd like to rename your machine to. pub name: String, } #[derive(Args, Debug, Clone)] pub struct TunnelForwardArgs { /// One or more ports to forward. pub ports: Vec, /// Login args -- used for convenience so the forwarding call is a single action. #[clap(flatten)] pub login: LoginArgs, } #[derive(Subcommand, Debug, Clone)] pub enum TunnelUserSubCommands { /// Log in to port forwarding service Login(LoginArgs), /// Log out of port forwarding service Logout, /// Show the account that's logged into port forwarding service Show, } #[derive(Args, Debug, Clone)] pub struct LoginArgs { /// An access token to store for authentication. #[clap(long, requires = "provider", env = "VSCODE_CLI_ACCESS_TOKEN")] pub access_token: Option, /// An access token to store for authentication. #[clap(long, requires = "access_token", env = "VSCODE_CLI_REFRESH_TOKEN")] pub refresh_token: Option, /// The auth provider to use. If not provided, a prompt will be shown. #[clap(value_enum, long)] pub provider: Option, } #[derive(clap::ValueEnum, Debug, Clone, Copy)] pub enum AuthProvider { Microsoft, Github, } ================================================ FILE: cli/src/commands/context.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::{log, state::LauncherPaths}; use super::args::CliCore; pub struct CommandContext { pub log: log::Logger, pub paths: LauncherPaths, pub args: CliCore, pub http: reqwest::Client, } ================================================ FILE: cli/src/commands/output.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::fmt::Display; use std::io::{BufWriter, Write}; use super::args::OutputFormat; pub struct Column { max_width: usize, heading: &'static str, data: Vec, } impl Column { pub fn new(heading: &'static str) -> Self { Column { max_width: heading.len(), heading, data: vec![], } } pub fn add_row(&mut self, row: String) { self.max_width = std::cmp::max(self.max_width, row.len()); self.data.push(row); } } impl OutputFormat { pub fn print_table(&self, table: OutputTable) -> Result<(), std::io::Error> { match *self { OutputFormat::Json => JsonTablePrinter().print(table, &mut std::io::stdout()), OutputFormat::Text => TextTablePrinter().print(table, &mut std::io::stdout()), } } } pub struct OutputTable { cols: Vec, } impl OutputTable { pub fn new(cols: Vec) -> Self { OutputTable { cols } } } trait TablePrinter { fn print(&self, table: OutputTable, out: &mut dyn std::io::Write) -> Result<(), std::io::Error>; } pub struct JsonTablePrinter(); impl TablePrinter for JsonTablePrinter { fn print( &self, table: OutputTable, out: &mut dyn std::io::Write, ) -> Result<(), std::io::Error> { let mut bw = BufWriter::new(out); bw.write_all(b"[")?; if !table.cols.is_empty() { let data_len = table.cols[0].data.len(); for i in 0..data_len { if i > 0 { bw.write_all(b",{")?; } else { bw.write_all(b"{")?; } for col in &table.cols { serde_json::to_writer(&mut bw, col.heading)?; bw.write_all(b":")?; serde_json::to_writer(&mut bw, &col.data[i])?; } } } bw.write_all(b"]")?; bw.flush() } } /// Type that prints the output as an ASCII, markdown-style table. pub struct TextTablePrinter(); impl TablePrinter for TextTablePrinter { fn print( &self, table: OutputTable, out: &mut dyn std::io::Write, ) -> Result<(), std::io::Error> { let mut bw = BufWriter::new(out); let sizes = table.cols.iter().map(|c| c.max_width).collect::>(); // print headers write_columns(&mut bw, table.cols.iter().map(|c| c.heading), &sizes)?; // print --- separators write_columns( &mut bw, table.cols.iter().map(|c| "-".repeat(c.max_width)), &sizes, )?; // print each column if !table.cols.is_empty() { let data_len = table.cols[0].data.len(); for i in 0..data_len { write_columns(&mut bw, table.cols.iter().map(|c| &c.data[i]), &sizes)?; } } bw.flush() } } fn write_columns( mut w: impl Write, cols: impl Iterator, sizes: &[usize], ) -> Result<(), std::io::Error> where T: Display, { w.write_all(b"|")?; for (i, col) in cols.enumerate() { write!(w, " {:width$} |", col, width = sizes[i])?; } w.write_all(b"\r\n") } ================================================ FILE: cli/src/commands/serve_web.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::collections::HashMap; use std::convert::Infallible; use std::fs; use std::io::{Read, Write}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response, Server}; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::{pin, time}; use crate::async_pipe::{ get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, }; use crate::constants::VSCODE_CLI_QUALITY; use crate::download_cache::DownloadCache; use crate::log; use crate::options::Quality; use crate::state::{LauncherPaths, PersistedState}; use crate::tunnels::shutdown_signal::ShutdownRequest; use crate::update_service::{ unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, }; use crate::util::command::new_script_command; use crate::util::errors::AnyError; use crate::util::http::{self, ReqwestSimpleHttp}; use crate::util::io::SilentCopyProgress; use crate::util::sync::{new_barrier, Barrier, BarrierOpener}; use crate::{ tunnels::legal, util::{errors::CodeError, prereqs::PreReqChecker}, }; use super::{args::ServeWebArgs, CommandContext}; /// Length of a commit hash, for validation const COMMIT_HASH_LEN: usize = 40; /// Number of seconds where, if there's no connections to a VS Code server, /// the server is shut down. const SERVER_IDLE_TIMEOUT_SECS: u64 = 60 * 60; /// Number of seconds in which the server times out when there is a connection /// (should be large enough to basically never happen) const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12; /// How long to cache the "latest" version we get from the update service. const RELEASE_CHECK_INTERVAL: u64 = 60 * 60; /// Number of bytes for the secret keys. See workbench.ts for their usage. const SECRET_KEY_BYTES: usize = 32; /// Path to mint the key combining server and client parts. const SECRET_KEY_MINT_PATH: &str = "_vscode-cli/mint-key"; /// Cookie set to the `SECRET_KEY_MINT_PATH` const PATH_COOKIE_NAME: &str = "vscode-secret-key-path"; /// HTTP-only cookie where the client's secret half is stored. const SECRET_KEY_COOKIE_NAME: &str = "vscode-cli-secret-half"; /// Implements the vscode "server of servers". Clients who go to the URI get /// served the latest version of the VS Code server whenever they load the /// page. The VS Code server prefixes all assets and connections it loads with /// its version string, so existing clients can continue to get served even /// while new clients get new VS Code Server versions. pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result { legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; let platform: crate::update_service::Platform = PreReqChecker::new().verify().await?; if !args.without_connection_token { if let Some(p) = args.connection_token_file.as_deref() { let token = fs::read_to_string(PathBuf::from(p)) .map_err(CodeError::CouldNotReadConnectionTokenFile)?; args.connection_token = Some(token.trim().to_string()); } else { // Ensure there's a defined connection token, since if multiple server versions // are executed, they will need to have a single shared token. let token_path = ctx.paths.root().join("serve-web-token"); let token = mint_connection_token(&token_path, args.connection_token.clone()) .map_err(CodeError::CouldNotCreateConnectionTokenFile)?; args.connection_token = Some(token); args.connection_token_file = Some(token_path.to_string_lossy().to_string()); } } let cm: Arc = ConnectionManager::new(&ctx, platform, args.clone()); let update_check_interval = 3600; cm.clone() .start_update_checker(Duration::from_secs(update_check_interval)); let key = get_server_key_half(&ctx.paths); let make_svc = move || { let ctx = HandleContext { cm: cm.clone(), log: cm.log.clone(), server_secret_key: key.clone(), }; let service = service_fn(move |req| handle(ctx.clone(), req)); async move { Ok::<_, Infallible>(service) } }; let mut shutdown = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]); let r = if let Some(s) = args.socket_path { let s = PathBuf::from(&s); let socket = listen_socket_rw_stream(&s).await?; ctx.log .result(format!("Web UI available on {}", s.display())); let r = Server::builder(socket.into_pollable()) .serve(make_service_fn(|_| make_svc())) .with_graceful_shutdown(async { let _ = shutdown.wait().await; }) .await; let _ = std::fs::remove_file(&s); // cleanup r } else { let addr: SocketAddr = match &args.host { Some(h) => { SocketAddr::new(h.parse().map_err(CodeError::InvalidHostAddress)?, args.port) } None => SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), args.port), }; let builder = Server::try_bind(&addr).map_err(CodeError::CouldNotListenOnInterface)?; let mut listening = format!("Web UI available at http://{addr}"); if let Some(base) = args.server_base_path { if !base.starts_with('/') { listening.push('/'); } listening.push_str(&base); } if let Some(ct) = args.connection_token { listening.push_str(&format!("?tkn={ct}")); } ctx.log.result(listening); builder .serve(make_service_fn(|_| make_svc())) .with_graceful_shutdown(async { let _ = shutdown.wait().await; }) .await }; r.map_err(CodeError::CouldNotListenOnInterface)?; Ok(0) } #[derive(Clone)] struct HandleContext { cm: Arc, log: log::Logger, server_secret_key: SecretKeyPart, } /// Handler function for an inbound request async fn handle(ctx: HandleContext, req: Request) -> Result, Infallible> { let client_key_half = get_client_key_half(&req); let path = req.uri().path(); let mut res = if path.starts_with(&ctx.cm.base_path) && path.get(ctx.cm.base_path.len()..).unwrap_or_default() == SECRET_KEY_MINT_PATH { handle_secret_mint(&ctx, req) } else { handle_proxied(&ctx, req).await }; append_secret_headers(&ctx.cm.base_path, &mut res, &client_key_half); Ok(res) } async fn handle_proxied(ctx: &HandleContext, req: Request) -> Response { let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), ctx.cm.platform) { r } else { match ctx.cm.get_release_from_cache().await { Ok(r) => r, Err(e) => { error!(ctx.log, "error getting latest version: {}", e); return response::code_err(e); } } }; match ctx.cm.get_connection(release).await { Ok(rw) => { if req.headers().contains_key(hyper::header::UPGRADE) { forward_ws_req_to_server(ctx.log.clone(), rw, req).await } else { forward_http_req_to_server(rw, req).await } } Err(CodeError::ServerNotYetDownloaded) => response::wait_for_download(), Err(e) => response::code_err(e), } } fn handle_secret_mint(ctx: &HandleContext, req: Request) -> Response { use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); hasher.update(ctx.server_secret_key.0.as_ref()); hasher.update(get_client_key_half(&req).0.as_ref()); let hash = hasher.finalize(); let hash = hash[..SECRET_KEY_BYTES].to_vec(); response::secret_key(hash) } /// Appends headers to response to maintain the secret storage of the workbench: /// sets the `PATH_COOKIE_VALUE` so workbench.ts knows about the 'mint' endpoint, /// and maintains the http-only cookie the client will use for cookies. fn append_secret_headers( base_path: &str, res: &mut Response, client_key_half: &SecretKeyPart, ) { let headers = res.headers_mut(); headers.append( hyper::header::SET_COOKIE, format!("{PATH_COOKIE_NAME}={base_path}{SECRET_KEY_MINT_PATH}; SameSite=Strict; Path=/",) .parse() .unwrap(), ); headers.append( hyper::header::SET_COOKIE, format!( "{}={}; SameSite=Strict; HttpOnly; Max-Age=2592000; Path=/", SECRET_KEY_COOKIE_NAME, client_key_half.encode() ) .parse() .unwrap(), ); } /// Gets the release info from the VS Code path prefix, which is in the /// format `/-/...` fn get_release_from_path(path: &str, platform: Platform) -> Option<(Release, String)> { if !path.starts_with('/') { return None; // paths must start with '/' } let path = &path[1..]; let i = path.find('/').unwrap_or(path.len()); let quality_commit_sep = path.get(..i).and_then(|p| p.find('-'))?; let (quality_commit, remaining) = path.split_at(i); let (quality, commit) = quality_commit.split_at(quality_commit_sep); let commit = &commit[1..]; if !is_commit_hash(commit) { return None; } Some(( Release { // remember to trim off the leading '/' which is now part of th quality quality: Quality::try_from(quality).ok()?, commit: commit.to_string(), platform, target: TargetKind::Web, name: "".to_string(), }, remaining.to_string(), )) } /// Proxies the standard HTTP request to the async pipe, returning the piped response async fn forward_http_req_to_server( (rw, handle): (AsyncPipe, ConnectionHandle), req: Request, ) -> Response { let (mut request_sender, connection) = match hyper::client::conn::Builder::new().handshake(rw).await { Ok(r) => r, Err(e) => return response::connection_err(e), }; tokio::spawn(connection); let res = request_sender .send_request(req) .await .unwrap_or_else(response::connection_err); // technically, we should buffer the body into memory since it may not be // read at this point, but because the keepalive time is very large // there's not going to be responses that take hours to send and x // cause us to kill the server before the response is sent drop(handle); res } /// Proxies the websocket request to the async pipe async fn forward_ws_req_to_server( log: log::Logger, (rw, handle): (AsyncPipe, ConnectionHandle), mut req: Request, ) -> Response { // splicing of client and servers inspired by https://github.com/hyperium/hyper/blob/fece9f7f50431cf9533cfe7106b53a77b48db699/examples/upgrades.rs let (mut request_sender, connection) = match hyper::client::conn::Builder::new().handshake(rw).await { Ok(r) => r, Err(e) => return response::connection_err(e), }; tokio::spawn(connection); let mut proxied_req = Request::builder().uri(req.uri()); for (k, v) in req.headers() { proxied_req = proxied_req.header(k, v); } let mut res = request_sender .send_request(proxied_req.body(Body::empty()).unwrap()) .await .unwrap_or_else(response::connection_err); let mut proxied_res = Response::new(Body::empty()); *proxied_res.status_mut() = res.status(); for (k, v) in res.headers() { proxied_res.headers_mut().insert(k, v.clone()); } // only start upgrade at this point in case the server decides to deny socket if res.status() == hyper::StatusCode::SWITCHING_PROTOCOLS { tokio::spawn(async move { let (s_req, s_res) = tokio::join!(hyper::upgrade::on(&mut req), hyper::upgrade::on(&mut res)); match (s_req, s_res) { (Err(e1), Err(e2)) => debug!( log, "client ({}) and server ({}) websocket upgrade failed", e1, e2 ), (Err(e1), _) => debug!(log, "client ({}) websocket upgrade failed", e1), (_, Err(e2)) => debug!(log, "server ({}) websocket upgrade failed", e2), (Ok(mut s_req), Ok(mut s_res)) => { trace!(log, "websocket upgrade succeeded"); let r = tokio::io::copy_bidirectional(&mut s_req, &mut s_res).await; trace!(log, "websocket closed (error: {:?})", r.err()); } } drop(handle); }); } proxied_res } /// Returns whether the string looks like a commit hash. fn is_commit_hash(s: &str) -> bool { s.len() == COMMIT_HASH_LEN && s.chars().all(|c| c.is_ascii_hexdigit()) } /// Gets a cookie from the request by name. fn extract_cookie(req: &Request, name: &str) -> Option { for h in req.headers().get_all(hyper::header::COOKIE) { if let Ok(str) = h.to_str() { for pair in str.split("; ") { let i = match pair.find('=') { Some(i) => i, None => continue, }; if &pair[..i] == name { return Some(pair[i + 1..].to_string()); } } } } None } #[derive(Clone)] struct SecretKeyPart(Box<[u8; SECRET_KEY_BYTES]>); impl SecretKeyPart { pub fn new() -> Self { let key: [u8; SECRET_KEY_BYTES] = rand::random(); Self(Box::new(key)) } pub fn decode(s: &str) -> Result { use base64::{engine::general_purpose, Engine as _}; let mut key: [u8; SECRET_KEY_BYTES] = [0; SECRET_KEY_BYTES]; let v = general_purpose::URL_SAFE.decode(s)?; if v.len() != SECRET_KEY_BYTES { return Err(base64::DecodeSliceError::OutputSliceTooSmall); } key.copy_from_slice(&v); Ok(Self(Box::new(key))) } pub fn encode(&self) -> String { use base64::{engine::general_purpose, Engine as _}; general_purpose::URL_SAFE.encode(self.0.as_ref()) } } /// Gets the server's half of the secret key. fn get_server_key_half(paths: &LauncherPaths) -> SecretKeyPart { let ps = PersistedState::new(paths.root().join("serve-web-key-half")); let value: String = ps.load(); if let Ok(sk) = SecretKeyPart::decode(&value) { return sk; } let key = SecretKeyPart::new(); let _ = ps.save(key.encode()); key } /// Gets the client's half of the secret key. fn get_client_key_half(req: &Request) -> SecretKeyPart { if let Some(c) = extract_cookie(req, SECRET_KEY_COOKIE_NAME) { if let Ok(sk) = SecretKeyPart::decode(&c) { return sk; } } SecretKeyPart::new() } /// Module holding original responses the CLI's server makes. mod response { use const_format::concatcp; use crate::constants::QUALITYLESS_SERVER_NAME; use super::*; pub fn connection_err(err: hyper::Error) -> Response { Response::builder() .status(503) .body(Body::from(format!("Error connecting to server: {err:?}"))) .unwrap() } pub fn code_err(err: CodeError) -> Response { Response::builder() .status(500) .body(Body::from(format!("Error serving request: {err}"))) .unwrap() } pub fn wait_for_download() -> Response { Response::builder() .status(202) .header("Content-Type", "text/html") // todo: get latest .body(Body::from(concatcp!("The latest version of the ", QUALITYLESS_SERVER_NAME, " is downloading, please wait a moment...", ))) .unwrap() } pub fn secret_key(hash: Vec) -> Response { Response::builder() .status(200) .header("Content-Type", "application/octet-stream") // todo: get latest .body(Body::from(hash)) .unwrap() } } /// Handle returned when getting a stream to the server, used to refcount /// connections to a server so it can be disposed when there are no more clients. struct ConnectionHandle { client_counter: Arc>, } impl ConnectionHandle { pub fn new(client_counter: Arc>) -> Self { client_counter.send_modify(|v| { *v += 1; }); Self { client_counter } } } impl Drop for ConnectionHandle { fn drop(&mut self) { self.client_counter.send_modify(|v| { *v -= 1; }); } } type StartData = (PathBuf, Arc>); /// State stored in the ConnectionManager for each server version. struct VersionState { downloaded: bool, socket_path: Barrier>, } type ConnectionStateMap = Arc>>; /// Manages the connections to running web UI instances. Multiple web servers /// can run concurrently, with routing based on the URL path. struct ConnectionManager { pub platform: Platform, pub log: log::Logger, args: ServeWebArgs, /// Server base path, ending in `/` base_path: String, /// Cache where servers are stored cache: DownloadCache, /// Mapping of (Quality, Commit) to the state each server is in state: ConnectionStateMap, /// Update service instance update_service: UpdateService, /// Cache of the latest released version, storing the time we checked as well latest_version: tokio::sync::Mutex>, } fn key_for_release(release: &Release) -> (Quality, String) { (release.quality, release.commit.clone()) } fn normalize_base_path(p: &str) -> String { let p = p.trim_matches('/'); if p.is_empty() { return "/".to_string(); } format!("/{}/", p.trim_matches('/')) } impl ConnectionManager { pub fn new(ctx: &CommandContext, platform: Platform, args: ServeWebArgs) -> Arc { let base_path = normalize_base_path(args.server_base_path.as_deref().unwrap_or_default()); let cache = DownloadCache::new(ctx.paths.web_server_storage()); let target_kind = TargetKind::Web; let quality = VSCODE_CLI_QUALITY.map_or(Quality::Stable, |q| match Quality::try_from(q) { Ok(q) => q, Err(_) => Quality::Stable, }); let now = Instant::now(); let latest_version = tokio::sync::Mutex::new(cache.get().first().map(|latest_commit| { ( now.checked_sub(Duration::from_secs(RELEASE_CHECK_INTERVAL)) .unwrap_or(now), // handle 0-ish instants, #233155 Release { name: String::from("0.0.0"), // Version information not stored on cache commit: latest_commit.clone(), platform, target: target_kind, quality, }, ) })); Arc::new(Self { platform, args, base_path, log: ctx.log.clone(), cache, update_service: UpdateService::new( ctx.log.clone(), Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())), ), state: ConnectionStateMap::default(), latest_version, }) } // spawns a task that checks for updates every n seconds duration pub fn start_update_checker(self: Arc, duration: Duration) { tokio::spawn(async move { let mut interval = time::interval(duration); loop { interval.tick().await; if let Err(e) = self.get_latest_release().await { warning!(self.log, "error getting latest version: {}", e); } } }); } // Returns the latest release from the cache, if one exists. pub async fn get_release_from_cache(&self) -> Result { let latest = self.latest_version.lock().await; if let Some((_, release)) = &*latest { return Ok(release.clone()); } drop(latest); self.get_latest_release().await } /// Gets a connection to a server version pub async fn get_connection( &self, release: Release, ) -> Result<(AsyncPipe, ConnectionHandle), CodeError> { // todo@connor4312: there is likely some performance benefit to // implementing a 'keepalive' for these connections. let (path, counter) = self.get_version_data(release).await?; let handle = ConnectionHandle::new(counter); let rw = get_socket_rw_stream(&path).await?; Ok((rw, handle)) } /// Gets the latest release for the CLI quality, caching its result for some /// time to allow for fast loads. pub async fn get_latest_release(&self) -> Result { let mut latest = self.latest_version.lock().await; let now = Instant::now(); let target_kind = TargetKind::Web; let quality = VSCODE_CLI_QUALITY .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) .and_then(|q| { Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) })?; let release = self .update_service .get_latest_commit(self.platform, target_kind, quality) .await .map_err(|e| CodeError::UpdateCheckFailed(e.to_string())); // If the update service is unavailable and we have stale data, use that if let (Err(e), Some((_, previous))) = (&release, latest.clone()) { warning!(self.log, "error getting latest release, using stale: {}", e); *latest = Some((now, previous.clone())); return Ok(previous.clone()); } let release = release?; debug!(self.log, "refreshed latest release: {}", release); *latest = Some((now, release.clone())); Ok(release) } /// Gets the StartData for the a version of the VS Code server, triggering /// download/start if necessary. It returns `CodeError::ServerNotYetDownloaded` /// while the server is downloading, which is used to have a refresh loop on the page. async fn get_version_data(&self, release: Release) -> Result { self.get_version_data_inner(release)? .wait() .await .unwrap() .map_err(CodeError::ServerDownloadError) } fn get_version_data_inner( &self, release: Release, ) -> Result>, CodeError> { let mut state = self.state.lock().unwrap(); let key = key_for_release(&release); if let Some(s) = state.get_mut(&key) { if !s.downloaded { if s.socket_path.is_open() { s.downloaded = true; } else { return Err(CodeError::ServerNotYetDownloaded); } } return Ok(s.socket_path.clone()); } let (socket_path, opener) = new_barrier(); let state_map_dup = self.state.clone(); let args = StartArgs { args: self.args.clone(), log: self.log.clone(), opener, release, }; if let Some(p) = self.cache.exists(&args.release.commit) { state.insert( key.clone(), VersionState { socket_path: socket_path.clone(), downloaded: true, }, ); tokio::spawn(async move { Self::start_version(args, p).await; state_map_dup.lock().unwrap().remove(&key); }); Ok(socket_path) } else { state.insert( key.clone(), VersionState { socket_path, downloaded: false, }, ); let update_service = self.update_service.clone(); let cache = self.cache.clone(); tokio::spawn(async move { Self::download_version(args, update_service.clone(), cache.clone()).await; state_map_dup.lock().unwrap().remove(&key); }); Err(CodeError::ServerNotYetDownloaded) } } /// Downloads a server version into the cache and starts it. async fn download_version( args: StartArgs, update_service: UpdateService, cache: DownloadCache, ) { let release_for_fut = args.release.clone(); let log_for_fut = args.log.clone(); let dir_fut = cache.create(&args.release.commit, |target_dir| async move { info!(log_for_fut, "Downloading server {}", release_for_fut.commit); let tmpdir = tempfile::tempdir().unwrap(); let response = update_service.get_download_stream(&release_for_fut).await?; let name = response.url_path_basename().unwrap(); let archive_path = tmpdir.path().join(name); http::download_into_file( &archive_path, log_for_fut.get_download_logger("Downloading server:"), response, ) .await?; unzip_downloaded_release(&archive_path, &target_dir, SilentCopyProgress())?; Ok(()) }); match dir_fut.await { Err(e) => args.opener.open(Err(e.to_string())), Ok(dir) => Self::start_version(args, dir).await, } } /// Starts a downloaded server that can be found in the given `path`. async fn start_version(args: StartArgs, path: PathBuf) { info!(args.log, "Starting server {}", args.release.commit); let executable = path .join("bin") .join(args.release.quality.server_entrypoint()); let socket_path = get_socket_name(); let mut cmd = new_script_command(&executable); cmd.stdin(std::process::Stdio::null()); cmd.stderr(std::process::Stdio::piped()); cmd.stdout(std::process::Stdio::piped()); cmd.arg("--socket-path"); cmd.arg(&socket_path); // License agreement already checked by the `server_web` function. cmd.args(["--accept-server-license-terms"]); if let Some(a) = &args.args.server_base_path { cmd.arg("--server-base-path"); cmd.arg(a); } if let Some(a) = &args.args.server_data_dir { cmd.arg("--server-data-dir"); cmd.arg(a); } if args.args.without_connection_token { cmd.arg("--without-connection-token"); } // Note: intentional that we don't pass --connection-token here, we always // convert it into the file variant. if let Some(ct) = &args.args.connection_token_file { cmd.arg("--connection-token-file"); cmd.arg(ct); } // removed, otherwise the workbench will not be usable when running the CLI from sources. cmd.env_remove("VSCODE_DEV"); let mut child = match cmd.spawn() { Ok(c) => c, Err(e) => { args.opener.open(Err(e.to_string())); return; } }; let (mut stdout, mut stderr) = ( BufReader::new(child.stdout.take().unwrap()).lines(), BufReader::new(child.stderr.take().unwrap()).lines(), ); // wrapped option to prove that we only use this once in the loop let (counter_tx, mut counter_rx) = tokio::sync::watch::channel(0); let mut opener = Some((args.opener, socket_path, Arc::new(counter_tx))); let commit_prefix = &args.release.commit[..7]; let kill_timer = tokio::time::sleep(Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS)); pin!(kill_timer); loop { tokio::select! { Ok(Some(l)) = stdout.next_line() => { info!(args.log, "[{} stdout]: {}", commit_prefix, l); if l.contains("Server bound to") { if let Some((opener, path, counter_tx)) = opener.take() { opener.open(Ok((path, counter_tx))); } } } Ok(Some(l)) = stderr.next_line() => { info!(args.log, "[{} stderr]: {}", commit_prefix, l); }, n = counter_rx.changed() => { kill_timer.as_mut().reset(match n { // err means that the record was dropped Err(_) => tokio::time::Instant::now(), Ok(_) => { if *counter_rx.borrow() == 0 { tokio::time::Instant::now() + Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS) } else { tokio::time::Instant::now() + Duration::from_secs(SERVER_ACTIVE_TIMEOUT_SECS) } } }); } _ = &mut kill_timer => { info!(args.log, "[{} process]: idle timeout reached, ending", commit_prefix); let _ = child.kill().await; break; } e = child.wait() => { info!(args.log, "[{} process]: exited: {:?}", commit_prefix, e); break; } } } } } struct StartArgs { log: log::Logger, args: ServeWebArgs, release: Release, opener: BarrierOpener>, } fn mint_connection_token(path: &Path, prefer_token: Option) -> std::io::Result { #[cfg(not(windows))] use std::os::unix::fs::OpenOptionsExt; let mut f = fs::OpenOptions::new(); f.create(true); f.write(true); f.read(true); #[cfg(not(windows))] f.mode(0o600); let mut f = f.open(path)?; if prefer_token.is_none() { let mut t = String::new(); f.read_to_string(&mut t)?; let t = t.trim(); if !t.is_empty() { return Ok(t.to_string()); } } f.set_len(0)?; let prefer_token = prefer_token.unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); f.write_all(prefer_token.as_bytes())?; Ok(prefer_token) } ================================================ FILE: cli/src/commands/tunnels.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use async_trait::async_trait; use base64::{engine::general_purpose as b64, Engine as _}; use futures::{stream::FuturesUnordered, StreamExt}; use serde::Serialize; use sha2::{Digest, Sha256}; use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, str::FromStr, time::Duration, }; use sysinfo::Pid; use tokio::{ io::{AsyncBufReadExt, BufReader}, sync::watch, }; use super::{ args::{ AuthProvider, CliCore, CommandShellArgs, ExistingTunnelArgs, TunnelArgs, TunnelForwardArgs, TunnelRenameArgs, TunnelServeArgs, TunnelServiceSubCommands, TunnelUserSubCommands, }, CommandContext, }; use crate::{ async_pipe::{get_socket_name, listen_socket_rw_stream, AsyncRWAccepter}, auth::Auth, constants::{ APPLICATION_NAME, CONTROL_PORT, IS_A_TTY, TUNNEL_CLI_LOCK_NAME, TUNNEL_SERVICE_LOCK_NAME, }, log, state::LauncherPaths, tunnels::{ code_server::CodeServerArgs, create_service_manager, dev_tunnels::{self, DevTunnels}, legal, local_forwarding, paths::get_all_servers, protocol, serve_stream, shutdown_signal::ShutdownRequest, singleton_client::do_single_rpc_call, singleton_server::{ make_singleton_server, start_singleton_server, BroadcastLogSink, SingletonServerArgs, }, AuthRequired, Next, ServeStreamParams, ServiceContainer, ServiceManager, }, util::{ app_lock::AppMutex, command::new_std_command, errors::{wrap, AnyError, CodeError}, machine::canonical_exe, prereqs::PreReqChecker, }, }; use crate::{ singleton::{acquire_singleton, SingletonConnection}, tunnels::{ dev_tunnels::ActiveTunnel, singleton_client::{start_singleton_client, SingletonClientArgs}, SleepInhibitor, }, }; impl From for crate::auth::AuthProvider { fn from(auth_provider: AuthProvider) -> Self { match auth_provider { AuthProvider::Github => crate::auth::AuthProvider::Github, AuthProvider::Microsoft => crate::auth::AuthProvider::Microsoft, } } } fn fulfill_existing_tunnel_args( d: ExistingTunnelArgs, name_arg: &Option, ) -> Option { let tunnel_name = d.tunnel_name.or_else(|| name_arg.clone()); match (d.tunnel_id, d.cluster, d.host_token) { (Some(tunnel_id), None, Some(host_token)) => { let i = tunnel_id.find('.')?; Some(dev_tunnels::ExistingTunnel { tunnel_id: tunnel_id[..i].to_string(), cluster: tunnel_id[i + 1..].to_string(), tunnel_name, host_token, }) } (Some(tunnel_id), Some(cluster), Some(host_token)) => Some(dev_tunnels::ExistingTunnel { tunnel_id, tunnel_name, host_token, cluster, }), _ => None, } } struct TunnelServiceContainer { core_args: CliCore, tunnel_args: TunnelArgs, } impl TunnelServiceContainer { fn new(core_args: CliCore, tunnel_args: TunnelArgs) -> Self { Self { core_args, tunnel_args, } } } #[async_trait] impl ServiceContainer for TunnelServiceContainer { async fn run_service( &mut self, log: log::Logger, launcher_paths: LauncherPaths, ) -> Result<(), AnyError> { let mut csa = (&self.core_args).into(); self.tunnel_args.serve_args.server_args.apply_to(&mut csa); serve_with_csa( launcher_paths, log, TunnelServeArgs { random_name: true, // avoid prompting ..Default::default() }, csa, TUNNEL_SERVICE_LOCK_NAME, ) .await?; Ok(()) } } pub async fn command_shell(ctx: CommandContext, args: CommandShellArgs) -> Result { let platform = PreReqChecker::new().verify().await?; let mut shutdown_reqs = vec![ShutdownRequest::CtrlC]; if let Some(p) = args.parent_process_id.and_then(|p| Pid::from_str(&p).ok()) { shutdown_reqs.push(ShutdownRequest::ParentProcessKilled(p)); } let mut params = ServeStreamParams { log: ctx.log, launcher_paths: ctx.paths, platform, requires_auth: args .require_token .map(AuthRequired::VSDAWithToken) .unwrap_or(AuthRequired::VSDA), exit_barrier: ShutdownRequest::create_rx(shutdown_reqs), code_server_args: (&ctx.args).into(), }; args.server_args.apply_to(&mut params.code_server_args); let mut listener: Box = match (args.on_port.first(), &args.on_host, args.on_socket) { (_, _, true) => { let socket = get_socket_name(); let listener = listen_socket_rw_stream(&socket) .await .map_err(|e| wrap(e, "error listening on socket"))?; params .log .result(format!("Listening on {}", socket.display())); Box::new(listener) } (Some(_), _, _) | (_, Some(_), _) => { let host = args .on_host .as_ref() .map(|h| h.parse().map_err(CodeError::InvalidHostAddress)) .unwrap_or(Ok(IpAddr::V4(Ipv4Addr::LOCALHOST)))?; let lower_port = args.on_port.first().copied().unwrap_or_default(); let port_no = if let Some(upper) = args.on_port.get(1) { find_unused_port(&host, lower_port, *upper) .await .unwrap_or_default() } else { lower_port }; let addr = SocketAddr::new(host, port_no); let listener = tokio::net::TcpListener::bind(addr) .await .map_err(|e| wrap(e, "error listening on port"))?; params .log .result(format!("Listening on {}", listener.local_addr().unwrap())); Box::new(listener) } _ => { serve_stream(tokio::io::stdin(), tokio::io::stderr(), params).await; return Ok(0); } }; let mut servers = FuturesUnordered::new(); loop { tokio::select! { Some(_) = servers.next() => {}, socket = listener.accept_rw() => { match socket { Ok((read, write)) => servers.push(serve_stream(read, write, params.clone())), Err(e) => { error!(params.log, &format!("Error accepting connection: {e}")); return Ok(1); } } }, _ = params.exit_barrier.wait() => { // wait for all servers to finish up: while (servers.next().await).is_some() { } return Ok(0); } } } } async fn find_unused_port(host: &IpAddr, start_port: u16, end_port: u16) -> Option { for port in start_port..=end_port { if is_port_available(*host, port).await { return Some(port); } } None } async fn is_port_available(host: IpAddr, port: u16) -> bool { tokio::net::TcpListener::bind(SocketAddr::new(host, port)) .await .is_ok() } fn make_service_args<'a: 'c, 'b: 'c, 'c>( root_path: &'a str, tunnel_args: &'b TunnelArgs, ) -> Vec<&'c str> { let mut args = ["--verbose", "--cli-data-dir", root_path, "tunnel"].to_vec(); if let Some(d) = tunnel_args.serve_args.server_args.extensions_dir.as_ref() { args.extend_from_slice(&["--extensions-dir", d]); } if let Some(d) = tunnel_args.serve_args.server_args.server_data_dir.as_ref() { args.extend_from_slice(&["--server-data-dir", d]); } args.extend_from_slice(&["service", "internal-run"]); args } pub async fn service( ctx: CommandContext, tunnel_args: TunnelArgs, service_args: TunnelServiceSubCommands, ) -> Result { let manager = create_service_manager(ctx.log.clone(), &ctx.paths); match service_args { TunnelServiceSubCommands::Install(args) => { let auth = Auth::new(&ctx.paths, ctx.log.clone()); if let Some(name) = &args.name { // ensure the name matches, and tunnel exists dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths) .rename_tunnel(name) .await?; } else { // still ensure they're logged in, otherwise subsequent serving will fail auth.get_credential().await?; } // likewise for license consent legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; let current_exe = canonical_exe().map_err(|e| wrap(e, "could not get current exe"))?; let root_path = ctx.paths.root().as_os_str().to_string_lossy(); let args = make_service_args(&root_path, &tunnel_args); manager.register(current_exe, &args).await?; ctx.log.result(format!("Service successfully installed! You can use `{APPLICATION_NAME} tunnel service log` to monitor it, and `{APPLICATION_NAME} tunnel service uninstall` to remove it.")); } TunnelServiceSubCommands::Uninstall => { manager.unregister().await?; } TunnelServiceSubCommands::Log => { manager.show_logs().await?; } TunnelServiceSubCommands::InternalRun => { manager .run( ctx.paths.clone(), TunnelServiceContainer::new(ctx.args, tunnel_args), ) .await?; } } Ok(0) } pub async fn user(ctx: CommandContext, user_args: TunnelUserSubCommands) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); match user_args { TunnelUserSubCommands::Login(mut login_args) => { auth.login( login_args.provider.map(|p| p.into()), login_args.access_token.take(), login_args.refresh_token.take(), ) .await?; } TunnelUserSubCommands::Logout => { auth.clear_credentials()?; } TunnelUserSubCommands::Show => { if let Ok(Some(sc)) = auth.get_current_credential() { ctx.log.result(format!("logged in with provider {}", sc.provider)); } else { ctx.log.result("not logged in"); return Ok(1); } } } Ok(0) } /// Remove the tunnel used by this tunnel, if any. pub async fn rename(ctx: CommandContext, rename_args: TunnelRenameArgs) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths); dt.rename_tunnel(&rename_args.name).await?; ctx.log.result(format!( "Successfully renamed this tunnel to {}", &rename_args.name )); Ok(0) } /// Remove the tunnel used by this tunnel, if any. pub async fn unregister(ctx: CommandContext) -> Result { let auth = Auth::new(&ctx.paths, ctx.log.clone()); let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&ctx.log, auth, &ctx.paths); dt.remove_tunnel().await?; Ok(0) } pub async fn restart(ctx: CommandContext) -> Result { do_single_rpc_call::<_, ()>( &ctx.paths.tunnel_lockfile(), ctx.log, protocol::singleton::METHOD_RESTART, protocol::EmptyObject {}, ) .await .map(|_| 0) .map_err(|e| e.into()) } pub async fn kill(ctx: CommandContext) -> Result { do_single_rpc_call::<_, ()>( &ctx.paths.tunnel_lockfile(), ctx.log, protocol::singleton::METHOD_SHUTDOWN, protocol::EmptyObject {}, ) .await .map(|_| 0) .map_err(|e| e.into()) } #[derive(Serialize)] pub struct StatusOutput { pub tunnel: Option, pub service_installed: bool, } pub async fn status(ctx: CommandContext) -> Result { let tunnel = do_single_rpc_call::<_, protocol::singleton::StatusWithTunnelName>( &ctx.paths.tunnel_lockfile(), ctx.log.clone(), protocol::singleton::METHOD_STATUS, protocol::EmptyObject {}, ) .await; let service_installed = create_service_manager(ctx.log.clone(), &ctx.paths) .is_installed() .await .unwrap_or(false); ctx.log.result( serde_json::to_string(&StatusOutput { service_installed, tunnel: match tunnel { Ok(s) => Some(s), Err(CodeError::NoRunningTunnel | CodeError::AsyncPipeFailed(_)) => None, Err(e) => return Err(e.into()), }, }) .unwrap(), ); Ok(0) } /// Removes unused servers. pub async fn prune(ctx: CommandContext) -> Result { get_all_servers(&ctx.paths) .into_iter() .map(|s| s.server_paths(&ctx.paths)) .filter(|s| s.get_running_pid().is_none()) .try_for_each(|s| { ctx.log .result(format!("Deleted {}", s.server_dir.display())); s.delete() }) .map_err(AnyError::from)?; ctx.log.result("Successfully removed all unused servers"); Ok(0) } /// Starts the gateway server. pub async fn serve(ctx: CommandContext, gateway_args: TunnelServeArgs) -> Result { let CommandContext { log, paths, args, .. } = ctx; let no_sleep = match gateway_args.no_sleep.then(SleepInhibitor::new) { Some(i) => match i.await { Ok(i) => Some(i), Err(e) => { warning!(log, "Could not inhibit sleep: {}", e); None } }, None => None, }; legal::require_consent(&paths, gateway_args.accept_server_license_terms)?; let mut csa = (&args).into(); gateway_args.server_args.apply_to(&mut csa); let result = serve_with_csa(paths, log, gateway_args, csa, TUNNEL_CLI_LOCK_NAME).await; drop(no_sleep); result } /// Internal command used by port forwarding. It reads requests for forwarded ports /// on lines from stdin, as JSON. It uses singleton logic as well (though on /// a different tunnel than the main one used for the control server) so that /// all forward requests on a single machine go through a single hosted tunnel /// process. Without singleton logic, requests could get routed to processes /// that aren't forwarding a given port and then fail. pub async fn forward( ctx: CommandContext, mut forward_args: TunnelForwardArgs, ) -> Result { // Spooky: check IS_A_TTY before starting the stdin reader, since IS_A_TTY will // access stdin but a lock will later be held on stdin by the line-reader. if *IS_A_TTY { trace!(ctx.log, "port forwarding is an internal preview feature"); } // #region stdin reading logic: let (own_ports_tx, own_ports_rx) = watch::channel(vec![]); let ports_process_log = ctx.log.clone(); tokio::spawn(async move { let mut lines = BufReader::new(tokio::io::stdin()).lines(); while let Ok(Some(line)) = lines.next_line().await { match serde_json::from_str(&line) { Ok(p) => { let _ = own_ports_tx.send(p); } Err(e) => warning!(ports_process_log, "error parsing ports: {}", e), } } }); // #region singleton acquisition let shutdown = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]); let server = loop { if shutdown.is_open() { return Ok(0); } match acquire_singleton(&ctx.paths.forwarding_lockfile()).await { Ok(SingletonConnection::Client(stream)) => { debug!(ctx.log, "starting as client to singleton"); let r = local_forwarding::client(local_forwarding::SingletonClientArgs { log: ctx.log.clone(), shutdown: shutdown.clone(), stream, port_requests: own_ports_rx.clone(), }) .await; if let Err(e) = r { warning!(ctx.log, "error contacting forwarding singleton: {}", e); } } Ok(SingletonConnection::Singleton(server)) => break server, Err(e) => { warning!(ctx.log, "error access singleton, retrying: {}", e); tokio::time::sleep(Duration::from_secs(2)).await } } }; // #region singleton handler let auth = Auth::new(&ctx.paths, ctx.log.clone()); if let (Some(p), Some(at)) = ( forward_args.login.provider.take(), forward_args.login.access_token.take(), ) { auth.login( Some(p.into()), Some(at), forward_args.login.refresh_token.take(), ) .await?; } let mut tunnels = DevTunnels::new_port_forwarding(&ctx.log, auth, &ctx.paths); let tunnel = tunnels .start_new_launcher_tunnel(None, true, &forward_args.ports) .await?; local_forwarding::server(ctx.log, tunnel, server, own_ports_rx, shutdown).await?; Ok(0) } fn get_connection_token(tunnel: &ActiveTunnel) -> String { let mut hash = Sha256::new(); hash.update(tunnel.id.as_bytes()); let result = hash.finalize(); let mut result = b64::URL_SAFE_NO_PAD.encode(result); if result.starts_with('-') { result.insert(0, 'a'); // avoid arg parsing issue } result } async fn serve_with_csa( paths: LauncherPaths, mut log: log::Logger, gateway_args: TunnelServeArgs, mut csa: CodeServerArgs, app_mutex_name: Option<&'static str>, ) -> Result { let log_broadcast = BroadcastLogSink::new(); log = log.tee(log_broadcast.clone()); log::install_global_logger(log.clone()); // re-install so that library logs are captured debug!( log, "Starting tunnel with `{} {}`", APPLICATION_NAME, std::env::args().collect::>().join(" ") ); // Intentionally read before starting the server. If the server updated and // respawn is requested, the old binary will get renamed, and then // current_exe will point to the wrong path. let current_exe = std::env::current_exe().unwrap(); let mut vec = vec![ ShutdownRequest::CtrlC, ShutdownRequest::ExeUninstalled(current_exe.to_owned()), ]; if let Some(p) = gateway_args .parent_process_id .and_then(|p| Pid::from_str(&p).ok()) { vec.push(ShutdownRequest::ParentProcessKilled(p)); } let mut shutdown = ShutdownRequest::create_rx(vec); let server = loop { if shutdown.is_open() { return Ok(0); } match acquire_singleton(&paths.tunnel_lockfile()).await { Ok(SingletonConnection::Client(stream)) => { debug!(log, "starting as client to singleton"); if gateway_args.name.is_some() || !gateway_args.server_args.install_extension.is_empty() || gateway_args.tunnel.tunnel_id.is_some() { warning!( log, "Command-line options will not be applied until the existing tunnel exits." ); } let should_exit = start_singleton_client(SingletonClientArgs { log: log.clone(), shutdown: shutdown.clone(), stream, }) .await; if should_exit { return Ok(0); } } Ok(SingletonConnection::Singleton(server)) => break server, Err(e) => { warning!(log, "error access singleton, retrying: {}", e); tokio::time::sleep(Duration::from_secs(2)).await } } }; debug!(log, "starting as new singleton"); let mut server = make_singleton_server(log_broadcast.clone(), log.clone(), server, shutdown.clone()); let platform = spanf!(log, log.span("prereq"), PreReqChecker::new().verify())?; let _lock = app_mutex_name.map(AppMutex::new); let auth = Auth::new(&paths, log.clone()); let mut dt = dev_tunnels::DevTunnels::new_remote_tunnel(&log, auth, &paths); loop { let tunnel = if let Some(t) = fulfill_existing_tunnel_args(gateway_args.tunnel.clone(), &gateway_args.name) { dt.start_existing_tunnel(t).await } else { tokio::select! { t = dt.start_new_launcher_tunnel(gateway_args.name.as_deref(), gateway_args.random_name, &[CONTROL_PORT]) => t, _ = shutdown.wait() => return Ok(1), } }?; csa.connection_token = Some(get_connection_token(&tunnel)); let mut r = start_singleton_server(SingletonServerArgs { log: log.clone(), tunnel, paths: &paths, code_server_args: &csa, platform, log_broadcast: &log_broadcast, shutdown: shutdown.clone(), server: &mut server, }) .await?; r.tunnel.close().await.ok(); match r.next { Next::Respawn => { warning!(log, "respawn requested, starting new server"); // reuse current args, but specify no-forward since tunnels will // already be running in this process, and we cannot do a login let args = std::env::args().skip(1).collect::>(); let exit = new_std_command(current_exe) .args(args) .spawn() .map_err(|e| wrap(e, "error respawning after update"))? .wait() .map_err(|e| wrap(e, "error waiting for child"))?; return Ok(exit.code().unwrap_or(1)); } Next::Exit => { debug!(log, "Tunnel shut down"); return Ok(0); } Next::Restart => continue, } } } ================================================ FILE: cli/src/commands/update.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::sync::Arc; use indicatif::ProgressBar; use crate::{ constants::PRODUCT_NAME_LONG, self_update::SelfUpdate, update_service::UpdateService, util::{errors::AnyError, http::ReqwestSimpleHttp, input::ProgressBarReporter}, }; use super::{args::StandaloneUpdateArgs, CommandContext}; pub async fn update(ctx: CommandContext, args: StandaloneUpdateArgs) -> Result { let update_service = UpdateService::new( ctx.log.clone(), Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())), ); let update_service = SelfUpdate::new(&update_service)?; let _ = update_service.cleanup_old_update(); let current_version = update_service.get_current_release().await?; if update_service.is_up_to_date_with(¤t_version) { ctx.log.result(format!( "{} is already to to date ({})", PRODUCT_NAME_LONG, current_version.commit )); return Ok(1); } if args.check { ctx.log .result(format!("Update to {current_version} is available")); return Ok(0); } let pb = ProgressBar::new(1); pb.set_message("Downloading..."); update_service .do_update(¤t_version, ProgressBarReporter::from(pb)) .await?; ctx.log .result(format!("Successfully updated to {current_version}")); Ok(0) } ================================================ FILE: cli/src/commands/version.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::path::{Path, PathBuf}; use crate::{ desktop::{prompt_to_install, CodeVersionManager, RequestedVersion}, log, util::{ errors::{AnyError, NoInstallInUserProvidedPath}, prereqs::PreReqChecker, }, }; use super::{args::UseVersionArgs, CommandContext}; pub async fn switch_to(ctx: CommandContext, args: UseVersionArgs) -> Result { let platform = PreReqChecker::new().verify().await?; let vm = CodeVersionManager::new(ctx.log.clone(), &ctx.paths, platform); let version = RequestedVersion::try_from(args.name.as_str())?; let maybe_path = match args.install_dir { Some(d) => Some( CodeVersionManager::get_entrypoint_for_install_dir(&PathBuf::from(&d)) .await .ok_or(NoInstallInUserProvidedPath(d))?, ), None => vm.try_get_entrypoint(&version).await, }; match maybe_path { Some(p) => { vm.set_preferred_version(version.clone(), p.clone()).await?; print_now_using(&ctx.log, &version, &p); Ok(0) } None => { prompt_to_install(&version); Ok(1) } } } pub async fn show(ctx: CommandContext) -> Result { let platform = PreReqChecker::new().verify().await?; let vm = CodeVersionManager::new(ctx.log.clone(), &ctx.paths, platform); let version = vm.get_preferred_version(); println!("Current quality: {version}"); match vm.try_get_entrypoint(&version).await { Some(p) => println!("Installation path: {}", p.display()), None => println!("No existing installation found"), } Ok(0) } fn print_now_using(log: &log::Logger, version: &RequestedVersion, path: &Path) { log.result(format!("Now using {} from {}", version, path.display())); } ================================================ FILE: cli/src/commands.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ mod context; pub mod args; pub mod serve_web; pub mod tunnels; pub mod update; pub mod version; pub use context::CommandContext; ================================================ FILE: cli/src/constants.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use serde::Deserialize; use std::{collections::HashMap, io::IsTerminal}; use const_format::concatcp; use lazy_static::lazy_static; use crate::options::Quality; pub const CONTROL_PORT: u16 = 31545; /// Protocol version sent to clients. This can be used to indicate new or /// changed capabilities that clients may wish to leverage. /// 1 - Initial protocol version /// 2 - Addition of `serve.compressed` property to control whether servermsg's /// are compressed bidirectionally. /// 3 - The server's connection token is set to a SHA256 hash of the tunnel ID /// 4 - The server's msgpack messages are no longer length-prefixed pub const PROTOCOL_VERSION: u32 = 4; /// Prefix for the tunnel tag that includes the version. pub const PROTOCOL_VERSION_TAG_PREFIX: &str = "protocolv"; /// Tag for the current protocol version, which is included in dev tunnels. pub const PROTOCOL_VERSION_TAG: &str = concatcp!("protocolv", PROTOCOL_VERSION); pub const VSCODE_CLI_VERSION: Option<&'static str> = option_env!("VSCODE_CLI_VERSION"); pub const VSCODE_CLI_AI_KEY: Option<&'static str> = option_env!("VSCODE_CLI_AI_KEY"); pub const VSCODE_CLI_AI_ENDPOINT: Option<&'static str> = option_env!("VSCODE_CLI_AI_ENDPOINT"); pub const VSCODE_CLI_QUALITY: Option<&'static str> = option_env!("VSCODE_CLI_QUALITY"); pub const DOCUMENTATION_URL: Option<&'static str> = option_env!("VSCODE_CLI_DOCUMENTATION_URL"); pub const VSCODE_CLI_COMMIT: Option<&'static str> = option_env!("VSCODE_CLI_COMMIT"); pub const VSCODE_CLI_UPDATE_ENDPOINT: Option<&'static str> = option_env!("VSCODE_CLI_UPDATE_URL"); /// Windows lock name for the running tunnel service. Used by the setup script /// to detect a tunnel process. See #179265. pub const TUNNEL_SERVICE_LOCK_NAME: Option<&'static str> = option_env!("VSCODE_CLI_WIN32_TUNNEL_SERVICE_MUTEX"); /// Windows lock name for the running tunnel without a service. Used by the setup /// script to detect a tunnel process. See #179265. pub const TUNNEL_CLI_LOCK_NAME: Option<&'static str> = option_env!("VSCODE_CLI_WIN32_TUNNEL_MUTEX"); pub const TUNNEL_SERVICE_USER_AGENT_ENV_VAR: &str = "TUNNEL_SERVICE_USER_AGENT"; /// Application name as it appears on the CLI. pub const APPLICATION_NAME: &str = match option_env!("VSCODE_CLI_APPLICATION_NAME") { Some(n) => n, None => "code", }; /// Full name of the product with its version. pub const PRODUCT_NAME_LONG: &str = match option_env!("VSCODE_CLI_NAME_LONG") { Some(n) => n, None => "Code - OSS", }; /// Name of the application without quality information. pub const QUALITYLESS_PRODUCT_NAME: &str = match option_env!("VSCODE_CLI_QUALITYLESS_PRODUCT_NAME") { Some(n) => n, None => "Code", }; /// Name of the application without quality information. pub const QUALITYLESS_SERVER_NAME: &str = concatcp!(QUALITYLESS_PRODUCT_NAME, " Server"); pub const QUALITY: &str = match VSCODE_CLI_QUALITY { Some(q) => q, _ => "oss", }; /// Web URL the editor is hosted at. For VS Code, this is vscode.dev. pub const EDITOR_WEB_URL: Option<&'static str> = option_env!("VSCODE_CLI_TUNNEL_EDITOR_WEB_URL"); /// Name shown in places where we need to tell a user what a process is, e.g. in sleep inhibition. pub const TUNNEL_ACTIVITY_NAME: &str = concatcp!(PRODUCT_NAME_LONG, " Tunnel"); /// Download URL of the desktop product. pub const PRODUCT_DOWNLOAD_URL: Option<&'static str> = option_env!("VSCODE_CLI_DOWNLOAD_URL"); const NONINTERACTIVE_VAR: &str = "VSCODE_CLI_NONINTERACTIVE"; /// Default data CLI data directory. pub const DEFAULT_DATA_PARENT_DIR: &str = match option_env!("VSCODE_CLI_DATA_FOLDER_NAME") { Some(n) => n, None => ".vscode-oss", }; pub fn get_default_user_agent() -> String { format!( "vscode-server-launcher/{}", VSCODE_CLI_VERSION.unwrap_or("dev") ) } const NO_COLOR_ENV: &str = "NO_COLOR"; #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct ServerQualityInfo { pub server_application_name: String, } lazy_static! { pub static ref TUNNEL_SERVICE_USER_AGENT: String = match std::env::var(TUNNEL_SERVICE_USER_AGENT_ENV_VAR) { Ok(ua) if !ua.is_empty() => format!("{} {}", ua, get_default_user_agent()), _ => get_default_user_agent(), }; /// Map of qualities to the server name pub static ref SERVER_NAME_MAP: Option> = option_env!("VSCODE_CLI_TUNNEL_SERVER_QUALITIES").and_then(|s| serde_json::from_str(s).unwrap()); /// Whether i/o interactions are allowed in the current CLI. pub static ref IS_A_TTY: bool = std::io::stdin().is_terminal(); /// Whether i/o interactions are allowed in the current CLI. pub static ref COLORS_ENABLED: bool = *IS_A_TTY && std::env::var(NO_COLOR_ENV).is_err(); /// Whether i/o interactions are allowed in the current CLI. pub static ref IS_INTERACTIVE_CLI: bool = *IS_A_TTY && std::env::var(NONINTERACTIVE_VAR).is_err(); /// Map of quality names to arrays of app IDs used for them, for example, `{"stable":["ABC123"]}` pub static ref WIN32_APP_IDS: Option> = option_env!("VSCODE_CLI_WIN32_APP_IDS").map(|s| s.split(',').map(|s| s.to_string()).collect()); } ================================================ FILE: cli/src/desktop/version_manager.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ ffi::OsString, fmt, io, path::{Path, PathBuf}, }; use lazy_static::lazy_static; use regex::Regex; use serde::{Deserialize, Serialize}; use crate::{ constants::{PRODUCT_DOWNLOAD_URL, QUALITY, QUALITYLESS_PRODUCT_NAME}, log, state::{LauncherPaths, PersistedState}, update_service::Platform, util::{ command::new_std_command, errors::{AnyError, InvalidRequestedVersion}, }, }; /// Parsed instance that a user can request. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(tag = "t", content = "c")] pub enum RequestedVersion { Default, Commit(String), Path(String), } lazy_static! { static ref COMMIT_RE: Regex = Regex::new(r"^[a-e0-f]{40}$").unwrap(); } impl RequestedVersion { pub fn get_command(&self) -> String { match self { RequestedVersion::Default => { format!("code version use {QUALITY}") } RequestedVersion::Commit(commit) => { format!("code version use {QUALITY}/{commit}") } RequestedVersion::Path(path) => { format!("code version use {path}") } } } } impl std::fmt::Display for RequestedVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { RequestedVersion::Default => { write!(f, "{QUALITY}") } RequestedVersion::Commit(commit) => { write!(f, "{QUALITY}/{commit}") } RequestedVersion::Path(path) => write!(f, "{path}"), } } } impl TryFrom<&str> for RequestedVersion { type Error = InvalidRequestedVersion; fn try_from(s: &str) -> Result { if s == QUALITY { return Ok(RequestedVersion::Default); } if Path::is_absolute(&PathBuf::from(s)) { return Ok(RequestedVersion::Path(s.to_string())); } if COMMIT_RE.is_match(s) { return Ok(RequestedVersion::Commit(s.to_string())); } Err(InvalidRequestedVersion()) } } #[derive(Serialize, Deserialize, Clone, Default)] struct Stored { /// Map of requested versions to locations where those versions are installed. versions: Vec<(RequestedVersion, OsString)>, current: usize, } pub struct CodeVersionManager { state: PersistedState, log: log::Logger, } impl CodeVersionManager { pub fn new(log: log::Logger, lp: &LauncherPaths, _platform: Platform) -> Self { CodeVersionManager { log, state: PersistedState::new(lp.root().join("versions.json")), } } /// Tries to find the binary entrypoint for VS Code installed in the path. pub async fn get_entrypoint_for_install_dir(path: &Path) -> Option { use tokio::sync::mpsc; // Check whether the user is supplying a path to the CLI directly (e.g. #164622) if let Ok(true) = path.metadata().map(|m| m.is_file()) { let result = new_std_command(path) .args(["--version"]) .output() .map(|o| o.status.success()); if let Ok(true) = result { return Some(path.to_owned()); } } let (tx, mut rx) = mpsc::channel(1); // Look for all the possible paths in parallel for entry in DESKTOP_CLI_RELATIVE_PATH.split(',') { let my_path = path.join(entry); let my_tx = tx.clone(); tokio::spawn(async move { if tokio::fs::metadata(&my_path).await.is_ok() { my_tx.send(my_path).await.ok(); } }); } drop(tx); // drop so rx gets None if no sender emits rx.recv().await } /// Sets the "version" as the persisted one for the user. pub async fn set_preferred_version( &self, version: RequestedVersion, path: PathBuf, ) -> Result<(), AnyError> { let mut stored = self.state.load(); stored.current = self.store_version_path(&mut stored, version, path); self.state.save(stored)?; Ok(()) } /// Stores or updates the path used for the given version. Returns the index /// that the path exists at. fn store_version_path( &self, state: &mut Stored, version: RequestedVersion, path: PathBuf, ) -> usize { if let Some(i) = state.versions.iter().position(|(v, _)| v == &version) { state.versions[i].1 = path.into_os_string(); i } else { state .versions .push((version.clone(), path.into_os_string())); state.versions.len() - 1 } } /// Gets the currently preferred version based on set_preferred_version. pub fn get_preferred_version(&self) -> RequestedVersion { let stored = self.state.load(); stored .versions .get(stored.current) .map(|(v, _)| v.clone()) .unwrap_or(RequestedVersion::Default) } /// Tries to get the entrypoint for the version, if one can be found. pub async fn try_get_entrypoint(&self, version: &RequestedVersion) -> Option { let mut state = self.state.load(); if let Some((_, install_path)) = state.versions.iter().find(|(v, _)| v == version) { let p = PathBuf::from(install_path); if p.exists() { return Some(p); } } // For simple quality requests, see if that's installed already on the system let candidates = match &version { RequestedVersion::Default => match detect_installed_program(&self.log) { Ok(p) => p, Err(e) => { warning!(self.log, "error looking up installed applications: {}", e); return None; } }, _ => return None, }; let found = match candidates.into_iter().next() { Some(p) => p, None => return None, }; // stash the found path for faster lookup self.store_version_path(&mut state, version.clone(), found.clone()); if let Err(e) = self.state.save(state) { debug!(self.log, "error caching version path: {}", e); } Some(found) } } /// Shows a nice UI prompt to users asking them if they want to install the /// requested version. pub fn prompt_to_install(version: &RequestedVersion) { println!("No installation of {QUALITYLESS_PRODUCT_NAME} {version} was found."); if let RequestedVersion::Default = version { if let Some(uri) = PRODUCT_DOWNLOAD_URL { // todo: on some platforms, we may be able to help automate installation. For example, // we can unzip the app ourselves on macOS and on windows we can download and spawn the GUI installer #[cfg(target_os = "linux")] println!("Install it from your system's package manager or {uri}, restart your shell, and try again."); #[cfg(target_os = "macos")] println!("Download and unzip it from {} and try again.", uri); #[cfg(target_os = "windows")] println!("Install it from {} and try again.", uri); } } println!(); println!("If you already installed {} and we didn't detect it, run `{} --install-dir /path/to/installation`", QUALITYLESS_PRODUCT_NAME, version.get_command()); } #[cfg(target_os = "macos")] fn detect_installed_program(log: &log::Logger) -> io::Result> { use crate::constants::PRODUCT_NAME_LONG; // easy, fast detection for where apps are usually installed let mut probable = PathBuf::from("/Applications"); probable.push(format!("{}.app", PRODUCT_NAME_LONG)); if probable.exists() { probable.extend(["Contents/Resources", "app", "bin", "code"]); return Ok(vec![probable]); } // _Much_ slower detection using the system_profiler (~10s for me). While the // profiler can output nicely structure plist xml, pulling in an xml parser // just for this is overkill. The default output looks something like... // // Visual Studio Code - Exploration 2: // // Version: 1.73.0-exploration // Obtained from: Identified Developer // Last Modified: 9/23/22, 10:16 AM // Kind: Intel // Signed by: Developer ID Application: Microsoft Corporation (UBF8T346G9), Developer ID Certification Authority, Apple Root CA // Location: /Users/connor/Downloads/Visual Studio Code - Exploration 2.app // // So, use a simple state machine that looks for the first line, and then for // the `Location:` line for the path. info!(log, "Searching for installations on your machine, this is done once and will take about 10 seconds..."); let stdout = new_std_command("system_profiler") .args(["SPApplicationsDataType", "-detailLevel", "mini"]) .output()? .stdout; enum State { LookingForName, LookingForLocation, } let mut state = State::LookingForName; let mut output: Vec = vec![]; const LOCATION_PREFIX: &str = "Location:"; for mut line in String::from_utf8_lossy(&stdout).lines() { line = line.trim(); match state { State::LookingForName => { if line.starts_with(PRODUCT_NAME_LONG) && line.ends_with(':') { state = State::LookingForLocation; } } State::LookingForLocation => { if let Some(suffix) = line.strip_prefix(LOCATION_PREFIX) { output.push( [suffix.trim(), "Contents/Resources", "app", "bin", "code"] .iter() .collect(), ); state = State::LookingForName; } } } } // Sort shorter paths to the front, preferring "more global" installs, and // incidentally preferring local installs over Parallels 'installs'. output.sort_by_key(|a| a.as_os_str().len()); Ok(output) } #[cfg(windows)] fn detect_installed_program(_log: &log::Logger) -> io::Result> { use crate::constants::{APPLICATION_NAME, WIN32_APP_IDS}; use winreg::enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; use winreg::RegKey; let mut output: Vec = vec![]; let app_ids = match WIN32_APP_IDS.as_ref() { Some(ids) => ids, None => return Ok(output), }; let scopes = [ ( HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", ), ( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", ), ( HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", ), ]; for (scope, key) in scopes { let cur_ver = match RegKey::predef(scope).open_subkey(key) { Ok(k) => k, Err(_) => continue, }; for key in cur_ver.enum_keys().flatten() { if app_ids.iter().any(|id| key.contains(id)) { let sk = cur_ver.open_subkey(&key)?; if let Ok(location) = sk.get_value::("InstallLocation") { output.push( [ location.as_str(), "bin", &format!("{}.cmd", APPLICATION_NAME), ] .iter() .collect(), ) } } } } Ok(output) } // Looks for the given binary name in the PATH, returning all candidate matches. // Based on https://github.dev/microsoft/vscode-js-debug/blob/7594d05518df6700df51771895fcad0ddc7f92f9/src/common/pathUtils.ts#L15 #[cfg(target_os = "linux")] fn detect_installed_program(log: &log::Logger) -> io::Result> { use crate::constants::APPLICATION_NAME; let path = match std::env::var("PATH") { Ok(p) => p, Err(e) => { info!(log, "PATH is empty ({}), skipping detection", e); return Ok(vec![]); } }; let current_exe = std::env::current_exe().expect("expected to read current exe"); let mut output = vec![]; for dir in path.split(':') { let target: PathBuf = [dir, APPLICATION_NAME].iter().collect(); match std::fs::canonicalize(&target) { Ok(m) if m == current_exe => continue, Ok(_) => {} Err(_) => continue, }; // note: intentionally store the non-canonicalized version, since if it's a // symlink, (1) it's probably desired to use it and (2) resolving the link // breaks snap installations. output.push(target); } Ok(output) } const DESKTOP_CLI_RELATIVE_PATH: &str = if cfg!(target_os = "macos") { "Contents/Resources/app/bin/code" } else if cfg!(target_os = "windows") { "bin/code.cmd,bin/code-insiders.cmd,bin/code-exploration.cmd" } else { "bin/code,bin/code-insiders,bin/code-exploration" }; #[cfg(test)] mod tests { use std::{ fs::{create_dir_all, File}, io::Write, }; use super::*; fn make_fake_vscode_install(path: &Path) { let bin = DESKTOP_CLI_RELATIVE_PATH .split(',') .next() .expect("expected exe path"); let binary_file_path = path.join(bin); let parent_dir_path = binary_file_path.parent().expect("expected parent path"); create_dir_all(parent_dir_path).expect("expected to create parent dir"); let mut binary_file = File::create(binary_file_path).expect("expected to make file"); binary_file .write_all(b"") .expect("expected to write binary"); } fn make_multiple_vscode_install() -> tempfile::TempDir { let dir = tempfile::tempdir().expect("expected to make temp dir"); make_fake_vscode_install(&dir.path().join("desktop/stable")); make_fake_vscode_install(&dir.path().join("desktop/1.68.2")); dir } #[test] fn test_detect_installed_program() { // developers can run this test and debug output manually; VS Code will not // be installed in CI, so the test only makes sure it doesn't error out let result = detect_installed_program(&log::Logger::test()); println!("result: {result:?}"); assert!(result.is_ok()); } #[tokio::test] async fn test_set_preferred_version() { let dir = make_multiple_vscode_install(); let lp = LauncherPaths::new_without_replacements(dir.path().to_owned()); let vm1 = CodeVersionManager::new(log::Logger::test(), &lp, Platform::LinuxARM64); assert_eq!(vm1.get_preferred_version(), RequestedVersion::Default); vm1.set_preferred_version( RequestedVersion::Commit("foobar".to_string()), dir.path().join("desktop/stable"), ) .await .expect("expected to store"); vm1.set_preferred_version( RequestedVersion::Commit("foobar2".to_string()), dir.path().join("desktop/stable"), ) .await .expect("expected to store"); assert_eq!( vm1.get_preferred_version(), RequestedVersion::Commit("foobar2".to_string()), ); let vm2 = CodeVersionManager::new(log::Logger::test(), &lp, Platform::LinuxARM64); assert_eq!( vm2.get_preferred_version(), RequestedVersion::Commit("foobar2".to_string()), ); } #[tokio::test] async fn test_gets_entrypoint() { let dir = make_multiple_vscode_install(); assert!(CodeVersionManager::get_entrypoint_for_install_dir( &dir.path().join("desktop").join("stable") ) .await .is_some()); assert!( CodeVersionManager::get_entrypoint_for_install_dir(&dir.path().join("invalid")) .await .is_none() ); } #[tokio::test] async fn test_gets_entrypoint_as_binary() { let dir = tempfile::tempdir().expect("expected to make temp dir"); #[cfg(windows)] let binary_file_path = { let path = dir.path().join("code.cmd"); File::create(&path).expect("expected to create file"); path }; #[cfg(unix)] let binary_file_path = { use std::fs; use std::os::unix::fs::PermissionsExt; let path = dir.path().join("code"); { let mut f = File::create(&path).expect("expected to create file"); f.write_all(b"#!/bin/sh") .expect("expected to write to file"); } fs::set_permissions(&path, fs::Permissions::from_mode(0o777)) .expect("expected to set permissions"); path }; assert_eq!( CodeVersionManager::get_entrypoint_for_install_dir(&binary_file_path).await, Some(binary_file_path) ); } } ================================================ FILE: cli/src/desktop.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ mod version_manager; pub use version_manager::{prompt_to_install, CodeVersionManager, RequestedVersion}; ================================================ FILE: cli/src/download_cache.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ fs::create_dir_all, path::{Path, PathBuf}, }; use futures::Future; use tokio::fs::remove_dir_all; use crate::{ state::PersistedState, util::errors::{wrap, AnyError, WrappedError}, }; const KEEP_LRU: usize = 5; const STAGING_SUFFIX: &str = ".staging"; const RENAME_ATTEMPTS: u32 = 20; const RENAME_DELAY: std::time::Duration = std::time::Duration::from_millis(200); const PERSISTED_STATE_FILE_NAME: &str = "lru.json"; #[derive(Clone)] pub struct DownloadCache { path: PathBuf, state: PersistedState>, } impl DownloadCache { pub fn new(path: PathBuf) -> DownloadCache { DownloadCache { state: PersistedState::new(path.join(PERSISTED_STATE_FILE_NAME)), path, } } /// Gets the value stored on the state pub fn get(&self) -> Vec { self.state.load() } /// Gets the download cache path. Names of cache entries can be formed by /// joining them to the path. pub fn path(&self) -> &Path { &self.path } /// Gets whether a cache exists with the name already. Marks it as recently /// used if it does exist. pub fn exists(&self, name: &str) -> Option { let p = self.path.join(name); if !p.exists() { return None; } let _ = self.touch(name.to_string()); Some(p) } /// Removes the item from the cache, if it exists pub fn delete(&self, name: &str) -> Result<(), WrappedError> { let f = self.path.join(name); if f.exists() { std::fs::remove_dir_all(f).map_err(|e| wrap(e, "error removing cached folder"))?; } self.state.update(|l| { l.retain(|n| n != name); }) } /// Calls the function to create the cached folder if it doesn't exist, /// returning the path where the folder is. Note that the path passed to /// the `do_create` method is a staging path and will not be the same as the /// final returned path. pub async fn create( &self, name: impl AsRef, do_create: F, ) -> Result where F: FnOnce(PathBuf) -> T, T: Future> + Send, { let name = name.as_ref(); let target_dir = self.path.join(name); if target_dir.exists() { return Ok(target_dir); } let temp_dir = self.path.join(format!("{name}{STAGING_SUFFIX}")); let _ = remove_dir_all(&temp_dir).await; // cleanup any existing create_dir_all(&temp_dir).map_err(|e| wrap(e, "error creating server directory"))?; do_create(temp_dir.clone()).await?; let _ = self.touch(name.to_string()); // retry the rename, it seems on WoA sometimes it takes a second for the // directory to be 'unlocked' after doing file/process operations in it. for attempt_no in 0..=RENAME_ATTEMPTS { match std::fs::rename(&temp_dir, &target_dir) { Ok(_) => { break; } Err(e) if attempt_no == RENAME_ATTEMPTS => { return Err(wrap(e, "error renaming downloaded server").into()) } Err(_) => { tokio::time::sleep(RENAME_DELAY).await; } } } Ok(target_dir) } fn touch(&self, name: String) -> Result<(), AnyError> { self.state.update(|l| { if let Some(index) = l.iter().position(|s| s == &name) { l.remove(index); } l.insert(0, name); if l.len() <= KEEP_LRU { return; } if let Some(f) = l.last() { let f = self.path.join(f); if !f.exists() || std::fs::remove_dir_all(f).is_ok() { l.pop(); } } })?; Ok(()) } } ================================================ FILE: cli/src/json_rpc.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use tokio::{ io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader}, pin, sync::mpsc, }; use crate::{ rpc::{self, MaybeSync, Serialization}, util::{ errors::InvalidRpcDataError, sync::{Barrier, Receivable}, }, }; use std::io; #[derive(Clone)] pub struct JsonRpcSerializer {} impl Serialization for JsonRpcSerializer { fn serialize(&self, value: impl serde::Serialize) -> Vec { let mut v = serde_json::to_vec(&value).unwrap(); v.push(b'\n'); v } fn deserialize( &self, b: &[u8], ) -> Result { serde_json::from_slice(b).map_err(|e| InvalidRpcDataError(e.to_string()).into()) } } /// Creates a new RPC Builder that serializes to JSON. #[allow(dead_code)] pub fn new_json_rpc() -> rpc::RpcBuilder { rpc::RpcBuilder::new(JsonRpcSerializer {}) } #[allow(dead_code)] pub async fn start_json_rpc( dispatcher: rpc::RpcDispatcher, read: impl AsyncRead + Unpin, mut write: impl AsyncWrite + Unpin, mut msg_rx: impl Receivable>, mut shutdown_rx: Barrier, ) -> io::Result> { let (write_tx, mut write_rx) = mpsc::channel::>(8); let mut read = BufReader::new(read); let mut read_buf = String::new(); let shutdown_fut = shutdown_rx.wait(); pin!(shutdown_fut); loop { tokio::select! { r = &mut shutdown_fut => return Ok(r.ok()), Some(w) = write_rx.recv() => { write.write_all(&w).await?; }, Some(w) = msg_rx.recv_msg() => { write.write_all(&w).await?; }, n = read.read_line(&mut read_buf) => { let r = match n { Ok(0) => return Ok(None), Ok(n) => dispatcher.dispatch(read_buf[..n].as_bytes()), Err(e) => return Err(e) }; read_buf.truncate(0); match r { MaybeSync::Sync(Some(v)) => { write.write_all(&v).await?; }, MaybeSync::Sync(None) => continue, MaybeSync::Future(fut) => { let write_tx = write_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { let _ = write_tx.send(v).await; } }); }, MaybeSync::Stream((dto, fut)) => { if let Some(dto) = dto { dispatcher.register_stream(write_tx.clone(), dto).await; } let write_tx = write_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { let _ = write_tx.send(v).await; } }); } } } } } } ================================================ FILE: cli/src/lib.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // todo: we should reduce the exported surface area over time as things are // moved into a common CLI pub mod auth; pub mod constants; #[macro_use] pub mod log; pub mod commands; pub mod desktop; pub mod options; pub mod self_update; pub mod state; pub mod tunnels; pub mod update_service; pub mod util; mod async_pipe; mod download_cache; mod json_rpc; mod msgpack_rpc; mod rpc; mod singleton; ================================================ FILE: cli/src/log.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use chrono::Local; use opentelemetry::{ sdk::trace::{Tracer, TracerProvider}, trace::{SpanBuilder, Tracer as TraitTracer, TracerProvider as TracerProviderTrait}, }; use serde::{Deserialize, Serialize}; use std::fmt; use std::{ io::Write, sync::atomic::{AtomicU32, Ordering}, }; use std::{path::Path, sync::Arc}; use crate::constants::COLORS_ENABLED; static INSTANCE_COUNTER: AtomicU32 = AtomicU32::new(0); // Gets a next incrementing number that can be used in logs pub fn next_counter() -> u32 { INSTANCE_COUNTER.fetch_add(1, Ordering::SeqCst) } // Log level #[derive( clap::ValueEnum, PartialEq, Eq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default, )] pub enum Level { Trace = 0, Debug, #[default] Info, Warn, Error, Critical, Off, } impl fmt::Display for Level { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Level::Critical => write!(f, "critical"), Level::Debug => write!(f, "debug"), Level::Error => write!(f, "error"), Level::Info => write!(f, "info"), Level::Off => write!(f, "off"), Level::Trace => write!(f, "trace"), Level::Warn => write!(f, "warn"), } } } impl Level { pub fn name(&self) -> Option<&str> { match self { Level::Trace => Some("trace"), Level::Debug => Some("debug"), Level::Info => Some("info"), Level::Warn => Some("warn"), Level::Error => Some("error"), Level::Critical => Some("critical"), Level::Off => None, } } pub fn color_code(&self) -> Option<&str> { if !*COLORS_ENABLED { return None; } match self { Level::Trace => None, Level::Debug => Some("\x1b[36m"), Level::Info => Some("\x1b[35m"), Level::Warn => Some("\x1b[33m"), Level::Error => Some("\x1b[31m"), Level::Critical => Some("\x1b[31m"), Level::Off => None, } } pub fn to_u8(self) -> u8 { self as u8 } } pub fn new_tunnel_prefix() -> String { format!("[tunnel.{}]", next_counter()) } pub fn new_code_server_prefix() -> String { format!("[codeserver.{}]", next_counter()) } pub fn new_rpc_prefix() -> String { format!("[rpc.{}]", next_counter()) } // Base logger implementation #[derive(Clone)] pub struct Logger { tracer: Arc, sink: Vec>, prefix: Option, } // Copy trick from https://stackoverflow.com/a/30353928 pub trait LogSinkClone { fn clone_box(&self) -> Box; } impl LogSinkClone for T where T: 'static + LogSink + Clone, { fn clone_box(&self) -> Box { Box::new(self.clone()) } } pub trait LogSink: LogSinkClone + Sync + Send { fn write_log(&self, level: Level, prefix: &str, message: &str); fn write_result(&self, message: &str); } impl Clone for Box { fn clone(&self) -> Box { self.clone_box() } } /// The basic log sink that writes output to stdout, with colors when relevant. #[derive(Clone)] pub struct StdioLogSink { level: Level, } impl LogSink for StdioLogSink { fn write_log(&self, level: Level, prefix: &str, message: &str) { if level < self.level { return; } emit(level, prefix, message); } fn write_result(&self, message: &str) { println!("{message}"); } } #[derive(Clone)] pub struct FileLogSink { level: Level, file: Arc>, } const FILE_LOG_SIZE_LIMIT: u64 = 1024 * 1024 * 10; // 10MB impl FileLogSink { pub fn new(level: Level, path: &Path) -> std::io::Result { // Truncate the service log occasionally to avoid growing infinitely if matches!(path.metadata(), Ok(m) if m.len() > FILE_LOG_SIZE_LIMIT) { // ignore errors, can happen if another process is writing right now let _ = std::fs::remove_file(path); } let file = std::fs::OpenOptions::new() .append(true) .create(true) .open(path)?; Ok(Self { level, file: Arc::new(std::sync::Mutex::new(file)), }) } } impl LogSink for FileLogSink { fn write_log(&self, level: Level, prefix: &str, message: &str) { if level < self.level { return; } let line = format(level, prefix, message, false); // ignore any errors, not much we can do if logging fails... self.file.lock().unwrap().write_all(line.as_bytes()).ok(); } fn write_result(&self, _message: &str) {} } impl Logger { pub fn test() -> Self { Self { tracer: Arc::new(TracerProvider::builder().build().tracer("codeclitest")), sink: vec![], prefix: None, } } pub fn new(tracer: Tracer, level: Level) -> Self { Self { tracer: Arc::new(tracer), sink: vec![Box::new(StdioLogSink { level })], prefix: None, } } pub fn span(&self, name: &str) -> SpanBuilder { self.tracer.span_builder(format!("serverlauncher/{name}")) } pub fn tracer(&self) -> &Tracer { &self.tracer } pub fn emit(&self, level: Level, message: &str) { let prefix = self.prefix.as_deref().unwrap_or(""); for sink in &self.sink { sink.write_log(level, prefix, message); } } pub fn result(&self, message: impl AsRef) { for sink in &self.sink { sink.write_result(message.as_ref()); } } pub fn prefixed(&self, prefix: &str) -> Logger { Logger { prefix: Some(match &self.prefix { Some(p) => format!("{p}{prefix} "), None => format!("{prefix} "), }), ..self.clone() } } /// Creates a new logger with the additional log sink added. pub fn tee(&self, sink: T) -> Logger where T: LogSink + 'static, { let mut new_sinks = self.sink.clone(); new_sinks.push(Box::new(sink)); Logger { sink: new_sinks, ..self.clone() } } /// Creates a new logger with the sink replace with the given sink. pub fn with_sink(&self, sink: T) -> Logger where T: LogSink + 'static, { Logger { sink: vec![Box::new(sink)], ..self.clone() } } pub fn get_download_logger<'a>(&'a self, prefix: &'static str) -> DownloadLogger<'a> { DownloadLogger { prefix, logger: self, } } } pub struct DownloadLogger<'a> { prefix: &'static str, logger: &'a Logger, } impl crate::util::io::ReportCopyProgress for DownloadLogger<'_> { fn report_progress(&mut self, bytes_so_far: u64, total_bytes: u64) { if total_bytes > 0 { self.logger.emit( Level::Trace, &format!( "{} {}/{} ({:.0}%)", self.prefix, bytes_so_far, total_bytes, (bytes_so_far as f64 / total_bytes as f64) * 100.0, ), ); } else { self.logger.emit( Level::Trace, &format!("{} {}/{}", self.prefix, bytes_so_far, total_bytes,), ); } } } fn format(level: Level, prefix: &str, message: &str, use_colors: bool) -> String { let current = Local::now(); let timestamp = current.format("%Y-%m-%d %H:%M:%S").to_string(); let name = level.name().unwrap(); if use_colors { if let Some(c) = level.color_code() { return format!("\x1b[2m[{timestamp}]\x1b[0m {c}{name}\x1b[0m {prefix}{message}\n"); } } format!("[{timestamp}] {name} {prefix}{message}\n") } pub fn emit(level: Level, prefix: &str, message: &str) { let line = format(level, prefix, message, *COLORS_ENABLED); if level == Level::Trace && *COLORS_ENABLED { print!("\x1b[2m{line}\x1b[0m"); } else { print!("{line}"); } } /// Installs the logger instance as the global logger for the 'log' service. /// Replaces any existing registered logger. Note that the logger will be leaked/ pub fn install_global_logger(log: Logger) { log::set_logger(Box::leak(Box::new(RustyLogger(log)))) .map(|()| log::set_max_level(log::LevelFilter::Debug)) .expect("expected to make logger"); } /// Logger that uses the common rust "log" crate and directs back to one of /// our managed loggers. struct RustyLogger(Logger); impl log::Log for RustyLogger { fn enabled(&self, metadata: &log::Metadata) -> bool { metadata.level() <= log::Level::Debug } fn log(&self, record: &log::Record) { if !self.enabled(record.metadata()) { return; } // exclude noisy log modules: let src = match record.module_path() { Some("russh::cipher" | "russh::negotiation" | "russh::kex::dh") => return, Some(s) => s, None => "", }; self.0.emit( match record.level() { log::Level::Debug => Level::Debug, log::Level::Error => Level::Error, log::Level::Info => Level::Info, log::Level::Trace => Level::Trace, log::Level::Warn => Level::Warn, }, &format!("[{}] {}", src, record.args()), ); } fn flush(&self) {} } #[macro_export] macro_rules! error { ($logger:expr, $str:expr) => { $logger.emit(log::Level::Error, $str) }; ($logger:expr, $($fmt:expr),+) => { $logger.emit(log::Level::Error, &format!($($fmt),+)) }; } #[macro_export] macro_rules! trace { ($logger:expr, $str:expr) => { $logger.emit(log::Level::Trace, $str) }; ($logger:expr, $($fmt:expr),+) => { $logger.emit(log::Level::Trace, &format!($($fmt),+)) }; } #[macro_export] macro_rules! debug { ($logger:expr, $str:expr) => { $logger.emit(log::Level::Debug, $str) }; ($logger:expr, $($fmt:expr),+) => { $logger.emit(log::Level::Debug, &format!($($fmt),+)) }; } #[macro_export] macro_rules! info { ($logger:expr, $str:expr) => { $logger.emit(log::Level::Info, $str) }; ($logger:expr, $($fmt:expr),+) => { $logger.emit(log::Level::Info, &format!($($fmt),+)) }; } #[macro_export] macro_rules! warning { ($logger:expr, $str:expr) => { $logger.emit(log::Level::Warn, $str) }; ($logger:expr, $($fmt:expr),+) => { $logger.emit(log::Level::Warn, &format!($($fmt),+)) }; } #[macro_export] macro_rules! span { ($logger:expr, $span:expr, $func:expr) => {{ use opentelemetry::trace::TraceContextExt; let span = $span.start($logger.tracer()); let cx = opentelemetry::Context::current_with_span(span); let guard = cx.clone().attach(); let t = $func; if let Err(e) = &t { cx.span().record_error(e); } std::mem::drop(guard); t }}; } #[macro_export] macro_rules! spanf { ($logger:expr, $span:expr, $func:expr) => {{ use opentelemetry::trace::{FutureExt, TraceContextExt}; let span = $span.start($logger.tracer()); let cx = opentelemetry::Context::current_with_span(span); let t = $func.with_context(cx.clone()).await; if let Err(e) = &t { cx.span().record_error(e); } cx.span().end(); t }}; } ================================================ FILE: cli/src/msgpack_rpc.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use bytes::Buf; use serde::de::DeserializeOwned; use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, pin, sync::mpsc, }; use tokio_util::codec::Decoder; use crate::{ rpc::{self, MaybeSync, Serialization}, util::{ errors::{AnyError, InvalidRpcDataError}, sync::{Barrier, Receivable}, }, }; use std::io::{self, Cursor, ErrorKind}; #[derive(Copy, Clone)] pub struct MsgPackSerializer {} impl Serialization for MsgPackSerializer { fn serialize(&self, value: impl serde::Serialize) -> Vec { rmp_serde::to_vec_named(&value).expect("expected to serialize") } fn deserialize(&self, b: &[u8]) -> Result { rmp_serde::from_slice(b).map_err(|e| InvalidRpcDataError(e.to_string()).into()) } } pub type MsgPackCaller = rpc::RpcCaller; /// Creates a new RPC Builder that serializes to msgpack. pub fn new_msgpack_rpc() -> rpc::RpcBuilder { rpc::RpcBuilder::new(MsgPackSerializer {}) } /// Starting processing msgpack rpc over the given i/o. It's recommended that /// the reader be passed in as a BufReader for efficiency. pub async fn start_msgpack_rpc< C: Send + Sync + 'static, X: Clone, S: Send + Sync + Serialization, Read: AsyncRead + Unpin, Write: AsyncWrite + Unpin, >( dispatcher: rpc::RpcDispatcher, mut read: Read, mut write: Write, mut msg_rx: impl Receivable>, mut shutdown_rx: Barrier, ) -> io::Result<(Option, Read, Write)> { let (write_tx, mut write_rx) = mpsc::channel::>(8); let mut decoder = MsgPackCodec::new(); let mut decoder_buf = bytes::BytesMut::new(); let shutdown_fut = shutdown_rx.wait(); pin!(shutdown_fut); loop { tokio::select! { r = read.read_buf(&mut decoder_buf) => { r?; while let Some(frame) = decoder.decode(&mut decoder_buf)? { match dispatcher.dispatch_with_partial(&frame.vec, frame.obj) { MaybeSync::Sync(Some(v)) => { let _ = write_tx.send(v).await; }, MaybeSync::Sync(None) => continue, MaybeSync::Future(fut) => { let write_tx = write_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { let _ = write_tx.send(v).await; } }); } MaybeSync::Stream((stream, fut)) => { if let Some(stream) = stream { dispatcher.register_stream(write_tx.clone(), stream).await; } let write_tx = write_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { let _ = write_tx.send(v).await; } }); } } }; }, Some(m) = write_rx.recv() => { write.write_all(&m).await?; }, Some(m) = msg_rx.recv_msg() => { write.write_all(&m).await?; }, r = &mut shutdown_fut => return Ok((r.ok(), read, write)), } write.flush().await?; } } /// Reader that reads msgpack object messages in a cancellation-safe way using Tokio's codecs. /// /// rmp_serde does not support async reads, and does not plan to. But we know every /// type in protocol is some kind of object, so by asking to deserialize the /// requested object from a reader (repeatedly, if incomplete) we can /// accomplish streaming. pub struct MsgPackCodec { _marker: std::marker::PhantomData, } impl MsgPackCodec { pub fn new() -> Self { Self { _marker: std::marker::PhantomData, } } } pub struct MsgPackDecoded { pub obj: T, pub vec: Vec, } impl tokio_util::codec::Decoder for MsgPackCodec { type Item = MsgPackDecoded; type Error = io::Error; fn decode(&mut self, src: &mut bytes::BytesMut) -> Result, Self::Error> { let bytes_ref = src.as_ref(); let mut cursor = Cursor::new(bytes_ref); match rmp_serde::decode::from_read::<_, T>(&mut cursor) { Err( rmp_serde::decode::Error::InvalidDataRead(e) | rmp_serde::decode::Error::InvalidMarkerRead(e), ) if e.kind() == ErrorKind::UnexpectedEof => { src.reserve(1024); Ok(None) } Err(e) => Err(std::io::Error::new( std::io::ErrorKind::InvalidData, e.to_string(), )), Ok(obj) => { let len = cursor.position() as usize; let vec = src[..len].to_vec(); src.advance(len); Ok(Some(MsgPackDecoded { obj, vec })) } } } } #[cfg(test)] mod tests { use serde::{Deserialize, Serialize}; use super::*; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] pub struct Msg { pub x: i32, } #[test] fn test_protocol() { let mut c = MsgPackCodec::::new(); let mut buf = bytes::BytesMut::new(); assert!(c.decode(&mut buf).unwrap().is_none()); buf.extend_from_slice(rmp_serde::to_vec_named(&Msg { x: 1 }).unwrap().as_slice()); buf.extend_from_slice(rmp_serde::to_vec_named(&Msg { x: 2 }).unwrap().as_slice()); assert_eq!( c.decode(&mut buf).unwrap().expect("expected msg1").obj, Msg { x: 1 } ); assert_eq!( c.decode(&mut buf).unwrap().expect("expected msg1").obj, Msg { x: 2 } ); } } ================================================ FILE: cli/src/options.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::fmt; use serde::{Deserialize, Serialize}; use crate::constants::SERVER_NAME_MAP; #[derive(clap::ValueEnum, Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum Quality { #[serde(rename = "stable")] Stable, #[serde(rename = "exploration")] Exploration, #[serde(other)] Insiders, } impl Quality { /// Lowercased quality name in paths and protocol pub fn get_machine_name(&self) -> &'static str { match self { Quality::Insiders => "insiders", Quality::Exploration => "exploration", Quality::Stable => "stable", } } /// Uppercased quality display name for humans pub fn get_capitalized_name(&self) -> &'static str { match self { Quality::Insiders => "Insiders", Quality::Exploration => "Exploration", Quality::Stable => "Stable", } } /// Server application name pub fn server_entrypoint(&self) -> String { let mut server_name = SERVER_NAME_MAP .as_ref() .and_then(|m| m.get(self)) .map(|s| s.server_application_name.as_str()) .unwrap_or("code-server-oss") .to_string(); if cfg!(windows) { server_name.push_str(".cmd"); } server_name } } impl fmt::Display for Quality { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.get_capitalized_name()) } } impl TryFrom<&str> for Quality { type Error = String; fn try_from(s: &str) -> Result { match s { "stable" => Ok(Quality::Stable), "insiders" | "insider" => Ok(Quality::Insiders), "exploration" => Ok(Quality::Exploration), _ => Err(format!( "Unknown quality: {s}. Must be one of stable, insiders, or exploration." )), } } } #[derive(clap::ValueEnum, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum TelemetryLevel { Off, Crash, Error, All, } impl fmt::Display for TelemetryLevel { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { TelemetryLevel::Off => write!(f, "off"), TelemetryLevel::Crash => write!(f, "crash"), TelemetryLevel::Error => write!(f, "error"), TelemetryLevel::All => write!(f, "all"), } } } ================================================ FILE: cli/src/rpc.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ collections::HashMap, future, sync::{ atomic::{AtomicU32, Ordering}, Arc, Mutex, }, }; use crate::log; use futures::{future::BoxFuture, Future, FutureExt}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tokio::{ io::{AsyncReadExt, AsyncWriteExt, DuplexStream, WriteHalf}, sync::{mpsc, oneshot}, }; use crate::util::errors::AnyError; pub type SyncMethod = Arc, &[u8]) -> Option>>; pub type AsyncMethod = Arc, &[u8]) -> BoxFuture<'static, Option>>>; pub type Duplex = Arc< dyn Send + Sync + Fn(Option, &[u8]) -> (Option, BoxFuture<'static, Option>>), >; pub enum Method { Sync(SyncMethod), Async(AsyncMethod), Duplex(Duplex), } /// Serialization is given to the RpcBuilder and defines how data gets serialized /// when callinth methods. pub trait Serialization: Send + Sync + 'static { fn serialize(&self, value: impl Serialize) -> Vec; fn deserialize(&self, b: &[u8]) -> Result; } /// RPC is a basic, transport-agnostic builder for RPC methods. You can /// register methods to it, then call `.build()` to get a "dispatcher" type. pub struct RpcBuilder { serializer: Arc, methods: HashMap<&'static str, Method>, calls: Arc>>, } impl RpcBuilder { /// Creates a new empty RPC builder. pub fn new(serializer: S) -> Self { Self { serializer: Arc::new(serializer), methods: HashMap::new(), calls: Arc::new(std::sync::Mutex::new(HashMap::new())), } } /// Creates a caller that will be connected to any eventual dispatchers, /// and that sends data to the "tx" channel. pub fn get_caller(&mut self, sender: mpsc::UnboundedSender>) -> RpcCaller { RpcCaller { serializer: self.serializer.clone(), calls: self.calls.clone(), sender, } } /// Gets a method builder. pub fn methods(self, context: C) -> RpcMethodBuilder { RpcMethodBuilder { context: Arc::new(context), serializer: self.serializer, methods: self.methods, calls: self.calls, } } } pub struct RpcMethodBuilder { context: Arc, serializer: Arc, methods: HashMap<&'static str, Method>, calls: Arc>>, } #[derive(Serialize)] struct DuplexStreamStarted { pub for_request_id: u32, pub stream_ids: Vec, } impl RpcMethodBuilder { /// Registers a synchronous rpc call that returns its result directly. pub fn register_sync(&mut self, method_name: &'static str, callback: F) where P: DeserializeOwned, R: Serialize, F: Fn(P, &C) -> Result + Send + Sync + 'static, { if self.methods.contains_key(method_name) { panic!("Method already registered: {method_name}"); } let serial = self.serializer.clone(); let context = self.context.clone(); self.methods.insert( method_name, Method::Sync(Arc::new(move |id, body| { let param = match serial.deserialize::>(body) { Ok(p) => p, Err(err) => { return id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, message: format!("{err:?}"), }, }) }) } }; match callback(param.params, &context) { Ok(result) => id.map(|id| serial.serialize(&SuccessResponse { id, result })), Err(err) => id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, message: format!("{err:?}"), }, }) }), } })), ); } /// Registers an async rpc call that returns a Future. pub fn register_async(&mut self, method_name: &'static str, callback: F) where P: DeserializeOwned + Send + 'static, R: Serialize + Send + Sync + 'static, Fut: Future> + Send, F: (Fn(P, Arc) -> Fut) + Clone + Send + Sync + 'static, { let serial = self.serializer.clone(); let context = self.context.clone(); self.methods.insert( method_name, Method::Async(Arc::new(move |id, body| { let param = match serial.deserialize::>(body) { Ok(p) => p, Err(err) => { return future::ready(id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, message: format!("{err:?}"), }, }) })) .boxed(); } }; let callback = callback.clone(); let serial = serial.clone(); let context = context.clone(); let fut = async move { match callback(param.params, context).await { Ok(result) => { id.map(|id| serial.serialize(&SuccessResponse { id, result })) } Err(err) => id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, message: format!("{err:?}"), }, }) }), } }; fut.boxed() })), ); } /// Registers an async rpc call that returns a Future containing a duplex /// stream that should be handled by the client. pub fn register_duplex( &mut self, method_name: &'static str, streams: usize, callback: F, ) where P: DeserializeOwned + Send + 'static, R: Serialize + Send + Sync + 'static, Fut: Future> + Send, F: (Fn(Vec, P, Arc) -> Fut) + Clone + Send + Sync + 'static, { let serial = self.serializer.clone(); let context = self.context.clone(); self.methods.insert( method_name, Method::Duplex(Arc::new(move |id, body| { let param = match serial.deserialize::>(body) { Ok(p) => p, Err(err) => { return ( None, future::ready(id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: 0, message: format!("{err:?}"), }, }) })) .boxed(), ); } }; let callback = callback.clone(); let serial = serial.clone(); let context = context.clone(); let mut dto = StreamDto { req_id: id.unwrap_or(0), streams: Vec::with_capacity(streams), }; let mut servers = Vec::with_capacity(streams); for _ in 0..streams { let (client, server) = tokio::io::duplex(8192); servers.push(server); dto.streams.push((next_message_id(), client)); } let fut = async move { match callback(servers, param.params, context).await { Ok(r) => id.map(|id| serial.serialize(&SuccessResponse { id, result: r })), Err(err) => id.map(|id| { serial.serialize(ErrorResponse { id, error: ResponseError { code: -1, message: format!("{err:?}"), }, }) }), } }; (Some(dto), fut.boxed()) })), ); } /// Builds into a usable, sync rpc dispatcher. pub fn build(mut self, log: log::Logger) -> RpcDispatcher { let streams = Streams::default(); let s1 = streams.clone(); self.register_async(METHOD_STREAM_ENDED, move |m: StreamEndedParams, _| { let s1 = s1.clone(); async move { s1.remove(m.stream).await; Ok(()) } }); let s2 = streams.clone(); self.register_sync(METHOD_STREAM_DATA, move |m: StreamDataIncomingParams, _| { s2.write(m.stream, m.segment); Ok(()) }); RpcDispatcher { log, context: self.context, calls: self.calls, serializer: self.serializer, methods: Arc::new(self.methods), streams, } } } type DispatchMethod = Box; /// Dispatcher returned from a Builder that provides a transport-agnostic way to /// deserialize and dispatch RPC calls. This structure may get more advanced as /// time goes on... #[derive(Clone)] pub struct RpcCaller { serializer: Arc, calls: Arc>>, sender: mpsc::UnboundedSender>, } impl RpcCaller { pub fn serialize_notify(serializer: &S, method: M, params: A) -> Vec where S: Serialization, M: AsRef + serde::Serialize, A: Serialize, { serializer.serialize(&FullRequest { id: None, method, params, }) } /// Enqueues an outbound call. Returns whether the message was enqueued. pub fn notify(&self, method: M, params: A) -> bool where M: AsRef + serde::Serialize, A: Serialize, { self.sender .send(Self::serialize_notify(&self.serializer, method, params)) .is_ok() } /// Enqueues an outbound call, returning its result. pub fn call(&self, method: M, params: A) -> oneshot::Receiver> where M: AsRef + serde::Serialize, A: Serialize, R: DeserializeOwned + Send + 'static, { let (tx, rx) = oneshot::channel(); let id = next_message_id(); let body = self.serializer.serialize(&FullRequest { id: Some(id), method, params, }); if self.sender.send(body).is_err() { drop(tx); return rx; } let serializer = self.serializer.clone(); self.calls.lock().unwrap().insert( id, Box::new(move |body| { match body { Outcome::Error(e) => tx.send(Err(e)).ok(), Outcome::Success(r) => match serializer.deserialize::>(&r) { Ok(r) => tx.send(Ok(r.result)).ok(), Err(err) => tx .send(Err(ResponseError { code: 0, message: err.to_string(), })) .ok(), }, }; }), ); rx } } /// Dispatcher returned from a Builder that provides a transport-agnostic way to /// deserialize and handle RPC calls. This structure may get more advanced as /// time goes on... #[derive(Clone)] pub struct RpcDispatcher { log: log::Logger, context: Arc, serializer: Arc, methods: Arc>, calls: Arc>>, streams: Streams, } static MESSAGE_ID_COUNTER: AtomicU32 = AtomicU32::new(0); fn next_message_id() -> u32 { MESSAGE_ID_COUNTER.fetch_add(1, Ordering::SeqCst) } impl RpcDispatcher { /// Runs the incoming request, returning the result of the call synchronously /// or in a future. (The caller can then decide whether to run the future /// sequentially in its receive loop, or not.) /// /// The future or return result will be optional bytes that should be sent /// back to the socket. pub fn dispatch(&self, body: &[u8]) -> MaybeSync { match self.serializer.deserialize::(body) { Ok(partial) => self.dispatch_with_partial(body, partial), Err(_err) => { warning!(self.log, "Failed to deserialize request, hex: {:X?}", body); MaybeSync::Sync(None) } } } /// Like dispatch, but allows passing an existing PartialIncoming. pub fn dispatch_with_partial(&self, body: &[u8], partial: PartialIncoming) -> MaybeSync { let id = partial.id; if let Some(method_name) = partial.method { let method = self.methods.get(method_name.as_str()); match method { Some(Method::Sync(callback)) => MaybeSync::Sync(callback(id, body)), Some(Method::Async(callback)) => MaybeSync::Future(callback(id, body)), Some(Method::Duplex(callback)) => MaybeSync::Stream(callback(id, body)), None => MaybeSync::Sync(id.map(|id| { self.serializer.serialize(ErrorResponse { id, error: ResponseError { code: -1, message: format!("Method not found: {method_name}"), }, }) })), } } else if let Some(err) = partial.error { if let Some(cb) = self.calls.lock().unwrap().remove(&id.unwrap()) { cb(Outcome::Error(err)); } MaybeSync::Sync(None) } else { if let Some(cb) = self.calls.lock().unwrap().remove(&id.unwrap()) { cb(Outcome::Success(body.to_vec())); } MaybeSync::Sync(None) } } /// Registers a stream call returned from dispatch(). pub async fn register_stream( &self, write_tx: mpsc::Sender> + Send>, dto: StreamDto, ) { let r = write_tx .send( self.serializer .serialize(&FullRequest { id: None, method: METHOD_STREAMS_STARTED, params: DuplexStreamStarted { stream_ids: dto.streams.iter().map(|(id, _)| *id).collect(), for_request_id: dto.req_id, }, }) .into(), ) .await; if r.is_err() { return; } for (stream_id, duplex) in dto.streams { let (mut read, write) = tokio::io::split(duplex); self.streams.insert(stream_id, write); let write_tx = write_tx.clone(); let serial = self.serializer.clone(); tokio::spawn(async move { let mut buf = vec![0; 4096]; loop { match read.read(&mut buf).await { Ok(0) | Err(_) => break, Ok(n) => { let r = write_tx .send( serial .serialize(&FullRequest { id: None, method: METHOD_STREAM_DATA, params: StreamDataParams { segment: &buf[..n], stream: stream_id, }, }) .into(), ) .await; if r.is_err() { return; } } } } let _ = write_tx .send( serial .serialize(&FullRequest { id: None, method: METHOD_STREAM_ENDED, params: StreamEndedParams { stream: stream_id }, }) .into(), ) .await; }); } } pub fn context(&self) -> Arc { self.context.clone() } } struct StreamRec { write: Option>, q: Vec>, ended: bool, } #[derive(Clone, Default)] struct Streams { map: Arc>>, } impl Streams { pub async fn remove(&self, id: u32) { let mut remove = None; { let mut map = self.map.lock().unwrap(); if let Some(s) = map.get_mut(&id) { if let Some(w) = s.write.take() { map.remove(&id); remove = Some(w); } else { s.ended = true; // will shut down in write loop } } } // do this outside of the sync lock: if let Some(mut w) = remove { let _ = w.shutdown().await; } } pub fn write(&self, id: u32, buf: Vec) { let mut map = self.map.lock().unwrap(); if let Some(s) = map.get_mut(&id) { s.q.push(buf); if let Some(w) = s.write.take() { tokio::spawn(write_loop(id, w, self.map.clone())); } } } pub fn insert(&self, id: u32, stream: WriteHalf) { self.map.lock().unwrap().insert( id, StreamRec { write: Some(stream), q: Vec::new(), ended: false, }, ); } } /// Write loop started by `Streams.write`. It takes the WriteHalf, and /// runs until there's no more items in the 'write queue'. At that point, if the /// record still exists in the `streams` (i.e. we haven't shut down), it'll /// return the WriteHalf so that the next `write` call starts /// the loop again. Otherwise, it'll shut down the WriteHalf. /// /// This is the equivalent of the same write_loop in the server_multiplexer. /// I couldn't figure out a nice way to abstract it without introducing /// performance overhead... async fn write_loop( id: u32, mut w: WriteHalf, streams: Arc>>, ) { let mut items_vec = vec![]; loop { { let mut lock = streams.lock().unwrap(); let stream_rec = match lock.get_mut(&id) { Some(b) => b, None => break, }; if stream_rec.q.is_empty() { if stream_rec.ended { lock.remove(&id); break; } else { stream_rec.write = Some(w); return; } } std::mem::swap(&mut stream_rec.q, &mut items_vec); } for item in items_vec.drain(..) { if w.write_all(&item).await.is_err() { break; } } } let _ = w.shutdown().await; // got here from `break` above, meaning our record got cleared. Close the bridge if so } const METHOD_STREAMS_STARTED: &str = "streams_started"; const METHOD_STREAM_DATA: &str = "stream_data"; const METHOD_STREAM_ENDED: &str = "stream_ended"; #[allow(dead_code)] // false positive trait AssertIsSync: Sync {} impl AssertIsSync for RpcDispatcher {} /// Approximate shape that is used to determine what kind of data is incoming. #[derive(Deserialize, Debug)] pub struct PartialIncoming { pub id: Option, pub method: Option, pub error: Option, } #[derive(Deserialize)] struct StreamDataIncomingParams { #[serde(with = "serde_bytes")] pub segment: Vec, pub stream: u32, } #[derive(Serialize, Deserialize)] struct StreamDataParams<'a> { #[serde(with = "serde_bytes")] pub segment: &'a [u8], pub stream: u32, } #[derive(Serialize, Deserialize)] struct StreamEndedParams { pub stream: u32, } #[derive(Serialize)] pub struct FullRequest, P> { pub id: Option, pub method: M, pub params: P, } #[derive(Deserialize)] struct RequestParams

{ pub params: P, } #[derive(Serialize, Deserialize)] struct SuccessResponse { pub id: u32, pub result: T, } #[derive(Serialize, Deserialize)] struct ErrorResponse { pub id: u32, pub error: ResponseError, } #[derive(Serialize, Deserialize, Debug)] pub struct ResponseError { pub code: i32, pub message: String, } enum Outcome { Success(Vec), Error(ResponseError), } pub struct StreamDto { req_id: u32, streams: Vec<(u32, DuplexStream)>, } pub enum MaybeSync { Stream((Option, BoxFuture<'static, Option>>)), Future(BoxFuture<'static, Option>>), Sync(Option>), } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_remove() { let streams = Streams::default(); let (writer, mut reader) = tokio::io::duplex(1024); streams.insert(1, tokio::io::split(writer).1); streams.remove(1).await; assert!(streams.map.lock().unwrap().get(&1).is_none()); let mut buffer = Vec::new(); assert_eq!(reader.read_to_end(&mut buffer).await.unwrap(), 0); } #[tokio::test] async fn test_write() { let streams = Streams::default(); let (writer, mut reader) = tokio::io::duplex(1024); streams.insert(1, tokio::io::split(writer).1); streams.write(1, vec![1, 2, 3]); let mut buffer = [0; 3]; assert_eq!(reader.read_exact(&mut buffer).await.unwrap(), 3); assert_eq!(buffer, [1, 2, 3]); } #[tokio::test] async fn test_write_with_immediate_end() { let streams = Streams::default(); let (writer, mut reader) = tokio::io::duplex(1); streams.insert(1, tokio::io::split(writer).1); streams.write(1, vec![1, 2, 3]); // spawn write loop streams.write(1, vec![4, 5, 6]); // enqueued while writing streams.remove(1).await; // end stream let mut buffer = Vec::new(); assert_eq!(reader.read_to_end(&mut buffer).await.unwrap(), 6); assert_eq!(buffer, vec![1, 2, 3, 4, 5, 6]); } } ================================================ FILE: cli/src/self_update.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{fs, path::Path}; use tempfile::tempdir; use crate::{ constants::{VSCODE_CLI_COMMIT, VSCODE_CLI_QUALITY}, options::Quality, update_service::{unzip_downloaded_release, Platform, Release, TargetKind, UpdateService}, util::{ command::new_std_command, errors::{wrap, AnyError, CodeError, CorruptDownload}, http, io::{ReportCopyProgress, SilentCopyProgress}, }, }; pub struct SelfUpdate<'a> { commit: &'static str, quality: Quality, platform: Platform, update_service: &'a UpdateService, } static OLD_UPDATE_EXTENSION: &str = "Updating CLI"; impl<'a> SelfUpdate<'a> { pub fn new(update_service: &'a UpdateService) -> Result { let commit = VSCODE_CLI_COMMIT .ok_or_else(|| CodeError::UpdatesNotConfigured("unknown build commit"))?; let quality = VSCODE_CLI_QUALITY .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) .and_then(|q| { Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) })?; let platform = Platform::env_default().ok_or_else(|| { CodeError::UpdatesNotConfigured("Unknown platform, please report this error") })?; Ok(Self { commit, quality, platform, update_service, }) } /// Gets the current release pub async fn get_current_release(&self) -> Result { self.update_service .get_latest_commit(self.platform, TargetKind::Cli, self.quality) .await } /// Gets whether the given release is what this CLI is built against pub fn is_up_to_date_with(&self, release: &Release) -> bool { release.commit == self.commit } /// Cleans up old self-updated binaries. Should be called with regularity. /// May fail if old versions are still running. pub fn cleanup_old_update(&self) -> Result<(), std::io::Error> { let current_path = std::env::current_exe()?; let old_path = current_path.with_extension(OLD_UPDATE_EXTENSION); if old_path.exists() { fs::remove_file(old_path)?; } Ok(()) } /// Updates the CLI to the given release. pub async fn do_update( &self, release: &Release, progress: impl ReportCopyProgress, ) -> Result<(), AnyError> { // 1. Download the archive into a temporary directory let tempdir = tempdir().map_err(|e| wrap(e, "Failed to create temp dir"))?; let stream = self.update_service.get_download_stream(release).await?; let archive_path = tempdir.path().join(stream.url_path_basename().unwrap()); http::download_into_file(&archive_path, progress, stream).await?; // 2. Unzip the archive and get the binary let target_path = std::env::current_exe().map_err(|e| wrap(e, "could not get current exe"))?; let staging_path = target_path.with_extension(".update"); let archive_contents_path = tempdir.path().join("content"); // unzipping the single binary is pretty small and fast--don't bother with passing progress unzip_downloaded_release(&archive_path, &archive_contents_path, SilentCopyProgress())?; copy_updated_cli_to_path(&archive_contents_path, &staging_path)?; // 3. Copy file metadata, make sure the new binary is executable\ copy_file_metadata(&target_path, &staging_path) .map_err(|e| wrap(e, "failed to set file permissions"))?; validate_cli_is_good(&staging_path)?; // Try to rename the old CLI to the tempdir, where it can get cleaned up by the // OS later. However, this can fail if the tempdir is on a different drive // than the installation dir. In this case just rename it to ".old". if fs::rename(&target_path, tempdir.path().join("old-code-cli")).is_err() { fs::rename( &target_path, target_path.with_extension(OLD_UPDATE_EXTENSION), ) .map_err(|e| wrap(e, "failed to rename old CLI"))?; } fs::rename(&staging_path, &target_path) .map_err(|e| wrap(e, "failed to rename newly installed CLI"))?; Ok(()) } } fn validate_cli_is_good(exe_path: &Path) -> Result<(), AnyError> { let o = new_std_command(exe_path) .args(["--version"]) .output() .map_err(|e| CorruptDownload(format!("could not execute new binary, aborting: {e}")))?; if !o.status.success() { let msg = format!( "could not execute new binary, aborting. Stdout:\n\n{}\n\nStderr:\n\n{}", String::from_utf8_lossy(&o.stdout), String::from_utf8_lossy(&o.stderr), ); return Err(CorruptDownload(msg).into()); } Ok(()) } fn copy_updated_cli_to_path(unzipped_content: &Path, staging_path: &Path) -> Result<(), AnyError> { let unzipped_files = fs::read_dir(unzipped_content) .map_err(|e| wrap(e, "could not read update contents"))? .collect::>(); if unzipped_files.len() != 1 { let msg = format!( "expected exactly one file in update, got {}", unzipped_files.len() ); return Err(CorruptDownload(msg).into()); } let archive_file = unzipped_files[0] .as_ref() .map_err(|e| wrap(e, "error listing update files"))?; fs::copy(archive_file.path(), staging_path) .map_err(|e| wrap(e, "error copying to staging file"))?; Ok(()) } #[cfg(target_os = "windows")] fn copy_file_metadata(from: &Path, to: &Path) -> Result<(), std::io::Error> { let permissions = from.metadata()?.permissions(); fs::set_permissions(to, permissions)?; Ok(()) } #[cfg(not(target_os = "windows"))] fn copy_file_metadata(from: &Path, to: &Path) -> Result<(), std::io::Error> { use std::os::unix::ffi::OsStrExt; use std::os::unix::fs::MetadataExt; let metadata = from.metadata()?; fs::set_permissions(to, metadata.permissions())?; // based on coreutils' chown https://github.com/uutils/coreutils/blob/72b4629916abe0852ad27286f4e307fbca546b6e/src/chown/chown.rs#L266-L281 let s = std::ffi::CString::new(to.as_os_str().as_bytes()).unwrap(); let ret = unsafe { libc::chown(s.as_ptr(), metadata.uid(), metadata.gid()) }; if ret != 0 { return Err(std::io::Error::last_os_error()); } Ok(()) } ================================================ FILE: cli/src/singleton.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use serde::{Deserialize, Serialize}; use std::{ fs::{File, OpenOptions}, io::{Seek, SeekFrom, Write}, path::{Path, PathBuf}, time::Duration, }; use sysinfo::{Pid, PidExt}; use crate::{ async_pipe::{ get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, AsyncPipeListener, }, util::{ errors::CodeError, file_lock::{FileLock, Lock, PREFIX_LOCKED_BYTES}, machine::wait_until_process_exits, }, }; pub struct SingletonServer { server: AsyncPipeListener, _lock: FileLock, } impl SingletonServer { pub async fn accept(&mut self) -> Result { self.server.accept().await } } pub enum SingletonConnection { /// This instance got the singleton lock. It started listening on a socket /// and has the read/write pair. If this gets dropped, the lock is released. Singleton(SingletonServer), /// Another instance is a singleton, and this client connected to it. Client(AsyncPipe), } /// Contents of the lock file; the listening socket ID and process ID /// doing the listening. #[derive(Deserialize, Serialize)] struct LockFileMatter { socket_path: String, pid: u32, } /// Tries to acquire the singleton homed at the given lock file, either starting /// a new singleton if it doesn't exist, or connecting otherwise. pub async fn acquire_singleton(lock_file: &Path) -> Result { let file = OpenOptions::new() .read(true) .write(true) .create(true) .truncate(false) .open(lock_file) .map_err(CodeError::SingletonLockfileOpenFailed)?; match FileLock::acquire(file) { Ok(Lock::AlreadyLocked(mut file)) => connect_as_client_with_file(&mut file) .await .map(SingletonConnection::Client), Ok(Lock::Acquired(lock)) => start_singleton_server(lock) .await .map(SingletonConnection::Singleton), Err(e) => Err(e), } } /// Tries to connect to the singleton homed at the given file as a client. pub async fn connect_as_client(lock_file: &Path) -> Result { let mut file = OpenOptions::new() .read(true) .open(lock_file) .map_err(CodeError::SingletonLockfileOpenFailed)?; connect_as_client_with_file(&mut file).await } async fn start_singleton_server(mut lock: FileLock) -> Result { let socket_path = get_socket_name(); let mut vec = Vec::with_capacity(128); let _ = vec.write(&[0; PREFIX_LOCKED_BYTES]); let _ = rmp_serde::encode::write( &mut vec, &LockFileMatter { socket_path: socket_path.to_string_lossy().to_string(), pid: std::process::id(), }, ); lock.file_mut() .write_all(&vec) .map_err(CodeError::SingletonLockfileOpenFailed)?; let server = listen_socket_rw_stream(&socket_path).await?; Ok(SingletonServer { server, _lock: lock, }) } const MAX_CLIENT_ATTEMPTS: i32 = 10; async fn connect_as_client_with_file(mut file: &mut File) -> Result { // retry, since someone else could get a lock and we could read it before // the JSON info was finished writing out let mut attempt = 0; loop { let _ = file.seek(SeekFrom::Start(PREFIX_LOCKED_BYTES as u64)); let r = match rmp_serde::from_read::<_, LockFileMatter>(&mut file) { Ok(prev) => { let socket_path = PathBuf::from(prev.socket_path); tokio::select! { p = retry_get_socket_rw_stream(&socket_path, 5, Duration::from_millis(500)) => p, _ = wait_until_process_exits(Pid::from_u32(prev.pid), 500) => return Err(CodeError::SingletonLockedProcessExited(prev.pid)), } } Err(e) => Err(CodeError::SingletonLockfileReadFailed(e)), }; if r.is_ok() || attempt == MAX_CLIENT_ATTEMPTS { return r; } attempt += 1; tokio::time::sleep(Duration::from_millis(500)).await; } } async fn retry_get_socket_rw_stream( path: &Path, max_tries: usize, interval: Duration, ) -> Result { for i in 0.. { match get_socket_rw_stream(path).await { Ok(s) => return Ok(s), Err(e) if i == max_tries => return Err(e), Err(_) => tokio::time::sleep(interval).await, } } unreachable!() } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_acquires_singleton() { let dir = tempfile::tempdir().expect("expected to make temp dir"); let s = acquire_singleton(&dir.path().join("lock")) .await .expect("expected to acquire"); match s { SingletonConnection::Singleton(_) => {} _ => panic!("expected to be singleton"), } } #[tokio::test] async fn test_acquires_client() { let dir = tempfile::tempdir().expect("expected to make temp dir"); let lockfile = dir.path().join("lock"); let s1 = acquire_singleton(&lockfile) .await .expect("expected to acquire1"); match s1 { SingletonConnection::Singleton(mut l) => tokio::spawn(async move { l.accept().await.expect("expected to accept"); }), _ => panic!("expected to be singleton"), }; let s2 = acquire_singleton(&lockfile) .await .expect("expected to acquire2"); match s2 { SingletonConnection::Client(_) => {} _ => panic!("expected to be client"), } } } ================================================ FILE: cli/src/state.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ extern crate dirs; use std::{ fs::{self, create_dir_all, read_to_string, remove_dir_all}, io::Write, path::{Path, PathBuf}, sync::{Arc, Mutex}, }; use serde::{de::DeserializeOwned, Serialize}; use crate::{ constants::{DEFAULT_DATA_PARENT_DIR, VSCODE_CLI_QUALITY}, download_cache::DownloadCache, util::errors::{wrap, AnyError, NoHomeForLauncherError, WrappedError}, }; const HOME_DIR_ALTS: [&str; 2] = ["$HOME", "~"]; #[derive(Clone)] pub struct LauncherPaths { pub server_cache: DownloadCache, pub cli_cache: DownloadCache, root: PathBuf, } struct PersistedStateContainer where T: Clone + Serialize + DeserializeOwned + Default, { path: PathBuf, state: Option, #[allow(dead_code)] mode: u32, } impl PersistedStateContainer where T: Clone + Serialize + DeserializeOwned + Default, { fn load_or_get(&mut self) -> T { if let Some(state) = &self.state { return state.clone(); } let state = if let Ok(s) = read_to_string(&self.path) { serde_json::from_str::(&s).unwrap_or_default() } else { T::default() }; self.state = Some(state.clone()); state } fn save(&mut self, state: T) -> Result<(), WrappedError> { let s = serde_json::to_string(&state).unwrap(); self.state = Some(state); self.write_state(s).map_err(|e| { wrap( e, format!("error saving launcher state into {}", self.path.display()), ) }) } fn write_state(&mut self, s: String) -> std::io::Result<()> { #[cfg(not(windows))] use std::os::unix::fs::OpenOptionsExt; let mut f = fs::OpenOptions::new(); f.create(true); f.write(true); f.truncate(true); #[cfg(not(windows))] f.mode(self.mode); let mut f = f.open(&self.path)?; f.write_all(s.as_bytes()) } } /// Container that holds some state value that is persisted to disk. #[derive(Clone)] pub struct PersistedState where T: Clone + Serialize + DeserializeOwned + Default, { container: Arc>>, } impl PersistedState where T: Clone + Serialize + DeserializeOwned + Default, { /// Creates a new state container that persists to the given path. pub fn new(path: PathBuf) -> PersistedState { Self::new_with_mode(path, 0o644) } /// Creates a new state container that persists to the given path. pub fn new_with_mode(path: PathBuf, mode: u32) -> PersistedState { PersistedState { container: Arc::new(Mutex::new(PersistedStateContainer { path, state: None, mode, })), } } /// Loads persisted state. pub fn load(&self) -> T { self.container.lock().unwrap().load_or_get() } /// Saves persisted state. pub fn save(&self, state: T) -> Result<(), WrappedError> { self.container.lock().unwrap().save(state) } /// Mutates persisted state. pub fn update(&self, mutator: impl FnOnce(&mut T) -> R) -> Result { let mut container = self.container.lock().unwrap(); let mut state = container.load_or_get(); let r = mutator(&mut state); container.save(state).map(|_| r) } } impl LauncherPaths { /// todo@conno4312: temporary migration from the old CLI data directory pub fn migrate(root: Option) -> Result { if root.is_some() { return Self::new(root); } let home_dir = match dirs::home_dir() { None => return Self::new(root), Some(d) => d, }; let old_dir = home_dir.join(".vscode-cli"); let mut new_dir = home_dir; new_dir.push(DEFAULT_DATA_PARENT_DIR); new_dir.push("cli"); if !old_dir.exists() || new_dir.exists() { return Self::new_for_path(new_dir); } if let Err(e) = std::fs::rename(&old_dir, &new_dir) { // no logger exists at this point in the lifecycle, so just log to stderr eprintln!("Failed to migrate old CLI data directory, will create a new one ({e})"); } Self::new_for_path(new_dir) } pub fn new(root: Option) -> Result { let root = root.unwrap_or_else(|| format!("~/{DEFAULT_DATA_PARENT_DIR}/cli")); let mut replaced = root.to_owned(); for token in HOME_DIR_ALTS { if root.contains(token) { if let Some(home) = dirs::home_dir() { replaced = root.replace(token, &home.to_string_lossy()) } else { return Err(AnyError::from(NoHomeForLauncherError())); } } } Self::new_for_path(PathBuf::from(replaced)) } fn new_for_path(root: PathBuf) -> Result { if !root.exists() { create_dir_all(&root) .map_err(|e| wrap(e, format!("error creating directory {}", root.display())))?; } Ok(LauncherPaths::new_without_replacements(root)) } pub fn new_without_replacements(root: PathBuf) -> LauncherPaths { // cleanup folders that existed before the new LRU strategy: let _ = std::fs::remove_dir_all(root.join("server-insiders")); let _ = std::fs::remove_dir_all(root.join("server-stable")); LauncherPaths { server_cache: DownloadCache::new(root.join("servers")), cli_cache: DownloadCache::new(root.join("cli")), root, } } /// Root directory for the server launcher pub fn root(&self) -> &Path { &self.root } /// Lockfile for the running tunnel pub fn tunnel_lockfile(&self) -> PathBuf { self.root.join(format!( "tunnel-{}.lock", VSCODE_CLI_QUALITY.unwrap_or("oss") )) } /// Lockfile for port forwarding pub fn forwarding_lockfile(&self) -> PathBuf { self.root.join(format!( "forwarding-{}.lock", VSCODE_CLI_QUALITY.unwrap_or("oss") )) } /// Suggested path for tunnel service logs, when using file logs pub fn service_log_file(&self) -> PathBuf { self.root.join("tunnel-service.log") } /// Removes the launcher data directory. pub fn remove(&self) -> Result<(), WrappedError> { remove_dir_all(&self.root).map_err(|e| { wrap( e, format!( "error removing launcher data directory {}", self.root.display() ), ) }) } /// Suggested path for web server storage pub fn web_server_storage(&self) -> PathBuf { self.root.join("serve-web") } } ================================================ FILE: cli/src/tunnels/challenge.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ #[cfg(not(feature = "vsda"))] pub fn create_challenge() -> String { use rand::distributions::{Alphanumeric, DistString}; Alphanumeric.sample_string(&mut rand::thread_rng(), 16) } #[cfg(not(feature = "vsda"))] pub fn sign_challenge(challenge: &str) -> String { use base64::{engine::general_purpose as b64, Engine as _}; use sha2::{Digest, Sha256}; let mut hash = Sha256::new(); hash.update(challenge.as_bytes()); let result = hash.finalize(); b64::URL_SAFE_NO_PAD.encode(result) } #[cfg(not(feature = "vsda"))] pub fn verify_challenge(challenge: &str, response: &str) -> bool { sign_challenge(challenge) == response } #[cfg(feature = "vsda")] pub fn create_challenge() -> String { use rand::distributions::{Alphanumeric, DistString}; let str = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); vsda::create_new_message(&str) } #[cfg(feature = "vsda")] pub fn sign_challenge(challenge: &str) -> String { vsda::sign(challenge) } #[cfg(feature = "vsda")] pub fn verify_challenge(challenge: &str, response: &str) -> bool { vsda::validate(challenge, response) } ================================================ FILE: cli/src/tunnels/code_server.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::paths::{InstalledServer, ServerPaths}; use crate::async_pipe::get_socket_name; use crate::constants::{ APPLICATION_NAME, EDITOR_WEB_URL, QUALITYLESS_PRODUCT_NAME, QUALITYLESS_SERVER_NAME, }; use crate::download_cache::DownloadCache; use crate::options::{Quality, TelemetryLevel}; use crate::state::LauncherPaths; use crate::tunnels::paths::{get_server_folder_name, SERVER_FOLDER_NAME}; use crate::update_service::{ unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, }; use crate::util::command::{ capture_command, capture_command_and_check_status, check_output_status, kill_tree, new_script_command, }; use crate::util::errors::{wrap, AnyError, CodeError, ExtensionInstallFailed, WrappedError}; use crate::util::http::{self, BoxedHttp}; use crate::util::io::SilentCopyProgress; use crate::util::machine::process_exists; use crate::util::prereqs::skip_requirements_check; use crate::{debug, info, log, spanf, trace, warning}; use lazy_static::lazy_static; use opentelemetry::KeyValue; use regex::Regex; use serde::Deserialize; use std::fs; use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; use tokio::fs::remove_file; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::process::{Child, Command}; use tokio::sync::oneshot::Receiver; use tokio::time::{interval, timeout}; lazy_static! { static ref LISTENING_PORT_RE: Regex = Regex::new(r"Extension host agent listening on (.+)").unwrap(); static ref WEB_UI_RE: Regex = Regex::new(r"Web UI available at (.+)").unwrap(); } #[derive(Clone, Debug, Default)] pub struct CodeServerArgs { pub host: Option, pub port: Option, pub socket_path: Option, // common argument pub telemetry_level: Option, pub log: Option, pub accept_server_license_terms: bool, pub verbose: bool, pub server_data_dir: Option, pub extensions_dir: Option, // extension management pub install_extensions: Vec, pub uninstall_extensions: Vec, pub update_extensions: bool, pub list_extensions: bool, pub show_versions: bool, pub category: Option, pub pre_release: bool, pub donot_include_pack_and_dependencies: bool, pub force: bool, pub start_server: bool, // connection tokens pub connection_token: Option, pub connection_token_file: Option, pub without_connection_token: bool, } impl CodeServerArgs { pub fn log_level(&self) -> log::Level { if self.verbose { log::Level::Trace } else { self.log.unwrap_or(log::Level::Info) } } pub fn telemetry_disabled(&self) -> bool { self.telemetry_level == Some(TelemetryLevel::Off) } pub fn command_arguments(&self) -> Vec { let mut args = Vec::new(); if let Some(i) = &self.socket_path { args.push(format!("--socket-path={i}")); } else { if let Some(i) = &self.host { args.push(format!("--host={i}")); } if let Some(i) = &self.port { args.push(format!("--port={i}")); } } if let Some(i) = &self.connection_token { args.push(format!("--connection-token={i}")); } if let Some(i) = &self.connection_token_file { args.push(format!("--connection-token-file={i}")); } if self.without_connection_token { args.push(String::from("--without-connection-token")); } if self.accept_server_license_terms { args.push(String::from("--accept-server-license-terms")); } if let Some(i) = self.telemetry_level { args.push(format!("--telemetry-level={i}")); } if let Some(i) = self.log { args.push(format!("--log={i}")); } for extension in &self.install_extensions { args.push(format!("--install-extension={extension}")); } if !&self.install_extensions.is_empty() { if self.pre_release { args.push(String::from("--pre-release")); } if self.force { args.push(String::from("--force")); } } for extension in &self.uninstall_extensions { args.push(format!("--uninstall-extension={extension}")); } if self.update_extensions { args.push(String::from("--update-extensions")); } if self.list_extensions { args.push(String::from("--list-extensions")); if self.show_versions { args.push(String::from("--show-versions")); } if let Some(i) = &self.category { args.push(format!("--category={i}")); } } if let Some(d) = &self.server_data_dir { args.push(format!("--server-data-dir={d}")); } if let Some(d) = &self.extensions_dir { args.push(format!("--extensions-dir={d}")); } if self.start_server { args.push(String::from("--start-server")); } args } } /// Base server params that can be `resolve()`d to a `ResolvedServerParams`. /// Doing so fetches additional information like a commit ID if previously /// unspecified. pub struct ServerParamsRaw { pub commit_id: Option, pub quality: Quality, pub code_server_args: CodeServerArgs, pub headless: bool, pub platform: Platform, } /// Server params that can be used to start a VS Code server. pub struct ResolvedServerParams { pub release: Release, pub code_server_args: CodeServerArgs, } impl ResolvedServerParams { fn as_installed_server(&self) -> InstalledServer { InstalledServer { commit: self.release.commit.clone(), quality: self.release.quality, headless: self.release.target == TargetKind::Server, } } } impl ServerParamsRaw { pub async fn resolve( self, log: &log::Logger, http: BoxedHttp, ) -> Result { Ok(ResolvedServerParams { release: self.get_or_fetch_commit_id(log, http).await?, code_server_args: self.code_server_args, }) } async fn get_or_fetch_commit_id( &self, log: &log::Logger, http: BoxedHttp, ) -> Result { let target = match self.headless { true => TargetKind::Server, false => TargetKind::Web, }; if let Some(c) = &self.commit_id { return Ok(Release { commit: c.clone(), quality: self.quality, target, name: String::new(), platform: self.platform, }); } UpdateService::new(log.clone(), http) .get_latest_commit(self.platform, target, self.quality) .await } } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] #[allow(dead_code)] struct UpdateServerVersion { pub name: String, pub version: String, pub product_version: String, pub timestamp: i64, } /// Code server listening on a port address. #[derive(Clone)] pub struct SocketCodeServer { pub commit_id: String, pub socket: PathBuf, pub origin: Arc, } /// Code server listening on a socket address. #[derive(Clone)] pub struct PortCodeServer { pub commit_id: String, pub port: u16, pub origin: Arc, } /// A server listening on any address/location. pub enum AnyCodeServer { Socket(SocketCodeServer), Port(PortCodeServer), } pub enum CodeServerOrigin { /// A new code server, that opens the barrier when it exits. New(Box), /// An existing code server with a PID. Existing(u32), } impl CodeServerOrigin { pub async fn wait_for_exit(&mut self) { match self { CodeServerOrigin::New(child) => { child.wait().await.ok(); } CodeServerOrigin::Existing(pid) => { let mut interval = interval(Duration::from_secs(30)); while process_exists(*pid) { interval.tick().await; } } } } pub async fn kill(&mut self) { match self { CodeServerOrigin::New(child) => { child.kill().await.ok(); } CodeServerOrigin::Existing(pid) => { kill_tree(*pid).await.ok(); } } } } /// Ensures the given list of extensions are installed on the running server. async fn do_extension_install_on_running_server( start_script_path: &Path, extensions: &[String], log: &log::Logger, ) -> Result<(), AnyError> { if extensions.is_empty() { return Ok(()); } debug!(log, "Installing extensions..."); let command = format!( "{} {}", start_script_path.display(), extensions .iter() .map(|s| get_extensions_flag(s)) .collect::>() .join(" ") ); let result = capture_command("bash", &["-c", &command]).await?; if !result.status.success() { Err(AnyError::from(ExtensionInstallFailed( String::from_utf8_lossy(&result.stderr).to_string(), ))) } else { Ok(()) } } pub struct ServerBuilder<'a> { logger: &'a log::Logger, server_params: &'a ResolvedServerParams, launcher_paths: &'a LauncherPaths, server_paths: ServerPaths, http: BoxedHttp, } impl<'a> ServerBuilder<'a> { pub fn new( logger: &'a log::Logger, server_params: &'a ResolvedServerParams, launcher_paths: &'a LauncherPaths, http: BoxedHttp, ) -> Self { Self { logger, server_params, launcher_paths, server_paths: server_params .as_installed_server() .server_paths(launcher_paths), http, } } /// Gets any already-running server from this directory. pub async fn get_running(&self) -> Result, AnyError> { info!( self.logger, "Checking {} and {} for a running server...", self.server_paths.logfile.display(), self.server_paths.pidfile.display() ); let pid = match self.server_paths.get_running_pid() { Some(pid) => pid, None => return Ok(None), }; info!(self.logger, "Found running server (pid={})", pid); if !Path::new(&self.server_paths.logfile).exists() { warning!(self.logger, "{} Server is running but its logfile is missing. Don't delete the {} Server manually, run the command '{} prune'.", QUALITYLESS_PRODUCT_NAME, QUALITYLESS_PRODUCT_NAME, APPLICATION_NAME); return Ok(None); } do_extension_install_on_running_server( &self.server_paths.executable, &self.server_params.code_server_args.install_extensions, self.logger, ) .await?; let origin = Arc::new(CodeServerOrigin::Existing(pid)); let contents = fs::read_to_string(&self.server_paths.logfile) .expect("Something went wrong reading log file"); if let Some(port) = parse_port_from(&contents) { Ok(Some(AnyCodeServer::Port(PortCodeServer { commit_id: self.server_params.release.commit.to_owned(), port, origin, }))) } else if let Some(socket) = parse_socket_from(&contents) { Ok(Some(AnyCodeServer::Socket(SocketCodeServer { commit_id: self.server_params.release.commit.to_owned(), socket, origin, }))) } else { Ok(None) } } /// Removes a cached server. pub async fn evict(&self) -> Result<(), WrappedError> { let name = get_server_folder_name( self.server_params.release.quality, &self.server_params.release.commit, ); self.launcher_paths.server_cache.delete(&name) } /// Ensures the server is set up in the configured directory. pub async fn setup(&self) -> Result<(), AnyError> { debug!( self.logger, "Installing and setting up {}...", QUALITYLESS_SERVER_NAME ); let update_service = UpdateService::new(self.logger.clone(), self.http.clone()); let name = get_server_folder_name( self.server_params.release.quality, &self.server_params.release.commit, ); let result = self .launcher_paths .server_cache .create(name, |target_dir| async move { let tmpdir = tempfile::tempdir().map_err(|e| wrap(e, "error creating temp download dir"))?; let response = update_service .get_download_stream(&self.server_params.release) .await?; let archive_path = tmpdir.path().join(response.url_path_basename().unwrap()); info!( self.logger, "Downloading {} server -> {}", QUALITYLESS_PRODUCT_NAME, archive_path.display() ); http::download_into_file( &archive_path, self.logger.get_download_logger("server download progress:"), response, ) .await?; let server_dir = target_dir.join(SERVER_FOLDER_NAME); unzip_downloaded_release( &archive_path, &server_dir, self.logger.get_download_logger("server inflate progress:"), )?; if !skip_requirements_check().await { let output = capture_command_and_check_status( server_dir .join("bin") .join(self.server_params.release.quality.server_entrypoint()), &["--version"], ) .await .map_err(|e| wrap(e, "error checking server integrity"))?; trace!( self.logger, "Server integrity verified, version: {}", String::from_utf8_lossy(&output.stdout).replace('\n', " / ") ); } else { info!(self.logger, "Skipping server integrity check"); } Ok(()) }) .await; if let Err(e) = result { error!(self.logger, "Error installing server: {}", e); return Err(e); } debug!(self.logger, "Server setup complete"); Ok(()) } pub async fn listen_on_port(&self, port: u16) -> Result { let mut cmd = self.get_base_command(); cmd.arg("--start-server") .arg("--enable-remote-auto-shutdown") .arg(format!("--port={port}")); let child = self.spawn_server_process(cmd).await?; let log_file = self.get_logfile()?; let plog = self.logger.prefixed(&log::new_code_server_prefix()); let (mut origin, listen_rx) = monitor_server::(child, Some(log_file), plog, false); let port = match timeout(Duration::from_secs(8), listen_rx).await { Err(_) => { origin.kill().await; return Err(CodeError::ServerOriginTimeout.into()); } Ok(Err(s)) => { origin.kill().await; return Err(CodeError::ServerUnexpectedExit(format!("{s}")).into()); } Ok(Ok(p)) => p, }; info!(self.logger, "Server started"); Ok(PortCodeServer { commit_id: self.server_params.release.commit.to_owned(), port, origin: Arc::new(origin), }) } /// Runs the command that just installs extensions and exits. pub async fn install_extensions(&self) -> Result<(), AnyError> { // cmd already has --install-extensions from base let mut cmd = self.get_base_command(); let cmd_str = || { self.server_params .code_server_args .command_arguments() .join(" ") }; let r = cmd.output().await.map_err(|e| CodeError::CommandFailed { command: cmd_str(), code: -1, output: e.to_string(), })?; check_output_status(r, cmd_str)?; Ok(()) } pub async fn listen_on_default_socket(&self) -> Result { let requested_file = get_socket_name(); self.listen_on_socket(&requested_file).await } pub async fn listen_on_socket(&self, socket: &Path) -> Result { Ok(spanf!( self.logger, self.logger.span("server.start").with_attributes(vec! { KeyValue::new("commit_id", self.server_params.release.commit.to_string()), KeyValue::new("quality", format!("{}", self.server_params.release.quality)), }), self._listen_on_socket(socket) )?) } async fn _listen_on_socket(&self, socket: &Path) -> Result { remove_file(&socket).await.ok(); // ignore any error if it doesn't exist let mut cmd = self.get_base_command(); cmd.arg("--start-server") .arg("--enable-remote-auto-shutdown") .arg(format!("--socket-path={}", socket.display())); let child = self.spawn_server_process(cmd).await?; let log_file = self.get_logfile()?; let plog = self.logger.prefixed(&log::new_code_server_prefix()); let (mut origin, listen_rx) = monitor_server::(child, Some(log_file), plog, false); let socket = match timeout(Duration::from_secs(30), listen_rx).await { Err(_) => { origin.kill().await; return Err(CodeError::ServerOriginTimeout.into()); } Ok(Err(s)) => { origin.kill().await; return Err(CodeError::ServerUnexpectedExit(format!("{s}")).into()); } Ok(Ok(socket)) => socket, }; info!(self.logger, "Server started"); Ok(SocketCodeServer { commit_id: self.server_params.release.commit.to_owned(), socket, origin: Arc::new(origin), }) } async fn spawn_server_process(&self, mut cmd: Command) -> Result { info!(self.logger, "Starting server..."); debug!(self.logger, "Starting server with command... {:?}", cmd); // On Windows spawning a code-server binary will run cmd.exe /c C:\path\to\code-server.cmd... // This spawns a cmd.exe window for the user, which if they close will kill the code-server process // and disconnect the tunnel. To prevent this, pass the CREATE_NO_WINDOW flag to the Command // only on Windows. // Original issue: https://github.com/microsoft/vscode/issues/184058 // Partial fix: https://github.com/microsoft/vscode/pull/184621 #[cfg(target_os = "windows")] let cmd = cmd.creation_flags( winapi::um::winbase::CREATE_NO_WINDOW | winapi::um::winbase::CREATE_NEW_PROCESS_GROUP | get_should_use_breakaway_from_job() .await .then_some(winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB) .unwrap_or_default(), ); let child = cmd .stderr(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) .spawn() .map_err(|e| CodeError::ServerUnexpectedExit(format!("{e}")))?; self.server_paths .write_pid(child.id().expect("expected server to have pid"))?; Ok(child) } fn get_logfile(&self) -> Result { File::create(&self.server_paths.logfile).map_err(|e| { wrap( e, format!( "error creating log file {}", self.server_paths.logfile.display() ), ) }) } fn get_base_command(&self) -> Command { let mut cmd = new_script_command(&self.server_paths.executable); cmd.stdin(std::process::Stdio::null()) .args(self.server_params.code_server_args.command_arguments()); cmd } } fn monitor_server( mut child: Child, log_file: Option, plog: log::Logger, write_directly: bool, ) -> (CodeServerOrigin, Receiver) where M: ServerOutputMatcher, R: 'static + Send + std::fmt::Debug, { let stdout = child .stdout .take() .expect("child did not have a handle to stdout"); let stderr = child .stderr .take() .expect("child did not have a handle to stdout"); let (listen_tx, listen_rx) = tokio::sync::oneshot::channel(); // Handle stderr and stdout in a separate task. Initially scan lines looking // for the listening port. Afterwards, just scan and write out to the file. tokio::spawn(async move { let mut stdout_reader = BufReader::new(stdout).lines(); let mut stderr_reader = BufReader::new(stderr).lines(); let write_line = |line: &str| -> std::io::Result<()> { if let Some(mut f) = log_file.as_ref() { f.write_all(line.as_bytes())?; f.write_all(b"\n")?; } if write_directly { println!("{line}"); } else { trace!(plog, line); } Ok(()) }; loop { let line = tokio::select! { l = stderr_reader.next_line() => l, l = stdout_reader.next_line() => l, }; match line { Err(e) => { trace!(plog, "error reading from stdout/stderr: {}", e); return; } Ok(None) => break, Ok(Some(l)) => { write_line(&l).ok(); if let Some(listen_on) = M::match_line(&l) { trace!(plog, "parsed location: {:?}", listen_on); listen_tx.send(listen_on).ok(); break; } } } } loop { let line = tokio::select! { l = stderr_reader.next_line() => l, l = stdout_reader.next_line() => l, }; match line { Err(e) => { trace!(plog, "error reading from stdout/stderr: {}", e); break; } Ok(None) => break, Ok(Some(l)) => { write_line(&l).ok(); } } } }); let origin = CodeServerOrigin::New(Box::new(child)); (origin, listen_rx) } fn get_extensions_flag(extension_id: &str) -> String { format!("--install-extension={extension_id}") } /// A type that can be used to scan stdout from the VS Code server. Returns /// some other type that, in turn, is returned from starting the server. pub trait ServerOutputMatcher where R: Send, { fn match_line(line: &str) -> Option; } /// Parses a line like "Extension host agent listening on /tmp/foo.sock" struct SocketMatcher(); impl ServerOutputMatcher for SocketMatcher { fn match_line(line: &str) -> Option { parse_socket_from(line) } } /// Parses a line like "Extension host agent listening on 9000" pub struct PortMatcher(); impl ServerOutputMatcher for PortMatcher { fn match_line(line: &str) -> Option { parse_port_from(line) } } /// Parses a line like "Web UI available at http://localhost:9000/?tkn=..." pub struct WebUiMatcher(); impl ServerOutputMatcher for WebUiMatcher { fn match_line(line: &str) -> Option { WEB_UI_RE.captures(line).and_then(|cap| { cap.get(1) .and_then(|uri| reqwest::Url::parse(uri.as_str()).ok()) }) } } /// Does not do any parsing and just immediately returns an empty result. pub struct NoOpMatcher(); impl ServerOutputMatcher<()> for NoOpMatcher { fn match_line(_: &str) -> Option<()> { Some(()) } } fn parse_socket_from(text: &str) -> Option { LISTENING_PORT_RE .captures(text) .and_then(|cap| cap.get(1).map(|path| PathBuf::from(path.as_str()))) } fn parse_port_from(text: &str) -> Option { LISTENING_PORT_RE.captures(text).and_then(|cap| { cap.get(1) .and_then(|path| path.as_str().parse::().ok()) }) } pub fn print_listening(log: &log::Logger, tunnel_name: &str) { debug!( log, "{} is listening for incoming connections", QUALITYLESS_SERVER_NAME ); let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("")); let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("")); let dir = if home_dir == current_dir { PathBuf::from("") } else { current_dir }; let base_web_url = match EDITOR_WEB_URL { Some(u) => u, None => return, }; let mut addr = url::Url::parse(base_web_url).unwrap(); { let mut ps = addr.path_segments_mut().unwrap(); ps.push("tunnel"); ps.push(tunnel_name); for segment in &dir { let as_str = segment.to_string_lossy(); if !(as_str.len() == 1 && as_str.starts_with(std::path::MAIN_SEPARATOR)) { ps.push(as_str.as_ref()); } } } let message = &format!("\nOpen this link in your browser {addr}\n"); log.result(message); } pub async fn download_cli_into_cache( cache: &DownloadCache, release: &Release, update_service: &UpdateService, ) -> Result { let cache_name = format!( "{}-{}-{}", release.quality, release.commit, release.platform ); let cli_dir = cache .create(&cache_name, |target_dir| async move { let tmpdir = tempfile::tempdir().map_err(|e| wrap(e, "error creating temp download dir"))?; let response = update_service.get_download_stream(release).await?; let name = response.url_path_basename().unwrap(); let archive_path = tmpdir.path().join(name); http::download_into_file(&archive_path, SilentCopyProgress(), response).await?; unzip_downloaded_release(&archive_path, &target_dir, SilentCopyProgress())?; Ok(()) }) .await?; let cli = std::fs::read_dir(cli_dir) .map_err(|_| CodeError::CorruptDownload("could not read cli folder contents"))? .next(); match cli { Some(Ok(cli)) => Ok(cli.path()), _ => { let _ = cache.delete(&cache_name); Err(CodeError::CorruptDownload("cli directory is empty").into()) } } } #[cfg(target_os = "windows")] async fn get_should_use_breakaway_from_job() -> bool { let mut cmd = Command::new("cmd"); cmd.creation_flags( winapi::um::winbase::CREATE_NO_WINDOW | winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB, ); cmd.args(["/C", "echo ok"]).output().await.is_ok() } ================================================ FILE: cli/src/tunnels/control_server.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::async_pipe::get_socket_rw_stream; use crate::constants::{CONTROL_PORT, PRODUCT_NAME_LONG}; use crate::log; use crate::msgpack_rpc::{new_msgpack_rpc, start_msgpack_rpc, MsgPackCodec, MsgPackSerializer}; use crate::options::Quality; use crate::rpc::{MaybeSync, RpcBuilder, RpcCaller, RpcDispatcher}; use crate::self_update::SelfUpdate; use crate::state::LauncherPaths; use crate::tunnels::protocol::{HttpRequestParams, PortPrivacy, METHOD_CHALLENGE_ISSUE}; use crate::tunnels::socket_signal::CloseReason; use crate::update_service::{Platform, Release, TargetKind, UpdateService}; use crate::util::command::new_tokio_command; use crate::util::errors::{ wrap, AnyError, CodeError, MismatchedLaunchModeError, NoAttachedServerError, }; use crate::util::http::{ DelegatedHttpRequest, DelegatedSimpleHttp, FallbackSimpleHttp, ReqwestSimpleHttp, }; use crate::util::io::SilentCopyProgress; use crate::util::is_integrated_cli; use crate::util::machine::kill_pid; use crate::util::os::os_release; use crate::util::sync::{new_barrier, Barrier, BarrierOpener}; use futures::stream::FuturesUnordered; use futures::FutureExt; use opentelemetry::trace::SpanKind; use opentelemetry::KeyValue; use std::collections::HashMap; use std::path::PathBuf; use std::process::Stdio; use tokio::net::TcpStream; use tokio::pin; use tokio::process::{ChildStderr, ChildStdin}; use tokio_util::codec::Decoder; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Instant; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader, DuplexStream}; use tokio::sync::{mpsc, Mutex}; use super::challenge::{create_challenge, sign_challenge, verify_challenge}; use super::code_server::{ download_cli_into_cache, AnyCodeServer, CodeServerArgs, ServerBuilder, ServerParamsRaw, SocketCodeServer, }; use super::dev_tunnels::ActiveTunnel; use super::paths::prune_stopped_servers; use super::port_forwarder::{PortForwarding, PortForwardingProcessor}; use super::protocol::{ AcquireCliParams, CallServerHttpParams, CallServerHttpResult, ChallengeIssueParams, ChallengeIssueResponse, ChallengeVerifyParams, ClientRequestMethod, EmptyObject, ForwardParams, ForwardResult, FsReadDirEntry, FsReadDirResponse, FsRenameRequest, FsSinglePathRequest, FsStatResponse, GetEnvResponse, GetHostnameResponse, HttpBodyParams, HttpHeadersParams, NetConnectRequest, ServeParams, ServerLog, ServerMessageParams, SpawnParams, SpawnResult, SysKillRequest, SysKillResponse, ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, VersionResponse, METHOD_CHALLENGE_VERIFY, }; use super::server_bridge::ServerBridge; use super::server_multiplexer::ServerMultiplexer; use super::shutdown_signal::ShutdownSignal; use super::socket_signal::{ ClientMessageDecoder, ServerMessageDestination, ServerMessageSink, SocketSignal, }; type HttpRequestsMap = Arc>>; type CodeServerCell = Arc>>; struct HandlerContext { /// Log handle for the server log: log::Logger, /// Whether the server update during the handler session. did_update: Arc, /// Whether authentication is still required on the socket. auth_state: Arc>, /// A loopback channel to talk to the socket server task. socket_tx: mpsc::Sender, /// Configured launcher paths. launcher_paths: LauncherPaths, /// Connected VS Code Server code_server: CodeServerCell, /// Potentially many "websocket" connections to client server_bridges: ServerMultiplexer, // the cli arguments used to start the code server code_server_args: CodeServerArgs, /// port forwarding functionality port_forwarding: Option, /// install platform for the VS Code server platform: Platform, /// http client to make download/update requests http: Arc, /// requests being served by the client http_requests: HttpRequestsMap, } /// Handler auth state. enum AuthState { /// Auth is required, we're waiting for the client to send its challenge optionally bearing a token. WaitingForChallenge(Option), /// A challenge has been issued. Waiting for a verification. ChallengeIssued(String), /// Auth is no longer required. Authenticated, } static MESSAGE_ID_COUNTER: AtomicU32 = AtomicU32::new(0); // Gets a next incrementing number that can be used in logs pub fn next_message_id() -> u32 { MESSAGE_ID_COUNTER.fetch_add(1, Ordering::SeqCst) } impl HandlerContext { async fn dispose(&self) { self.server_bridges.dispose().await; info!(self.log, "Disposed of connection to running server."); } } enum ServerSignal { /// Signalled when the server has been updated and we want to respawn. /// We'd generally need to stop and then restart the launcher, but the /// program might be managed by a supervisor like systemd. Instead, we /// will stop the TCP listener and spawn the launcher again as a subprocess /// with the same arguments we used. Respawn, } pub enum Next { /// Whether the server should be respawned in a new binary (see ServerSignal.Respawn). Respawn, /// Whether the tunnel should be restarted Restart, /// Whether the process should exit Exit, } pub struct ServerTermination { pub next: Next, pub tunnel: ActiveTunnel, } async fn preload_extensions( log: &log::Logger, platform: Platform, mut args: CodeServerArgs, launcher_paths: LauncherPaths, ) -> Result<(), AnyError> { args.start_server = false; let params_raw = ServerParamsRaw { commit_id: None, quality: Quality::Stable, code_server_args: args.clone(), headless: true, platform, }; // cannot use delegated HTTP here since there's no remote connection yet let http = Arc::new(ReqwestSimpleHttp::new()); let resolved = params_raw.resolve(log, http.clone()).await?; let sb = ServerBuilder::new(log, &resolved, &launcher_paths, http.clone()); sb.setup().await?; sb.install_extensions().await } // Runs the launcher server. Exits on a ctrl+c or when requested by a user. // Note that client connections may not be closed when this returns; use // `close_all_clients()` on the ServerTermination to make this happen. pub async fn serve( log: &log::Logger, mut tunnel: ActiveTunnel, launcher_paths: &LauncherPaths, code_server_args: &CodeServerArgs, platform: Platform, mut shutdown_rx: Barrier, ) -> Result { let mut port = tunnel.add_port_direct(CONTROL_PORT).await?; let mut forwarding = PortForwardingProcessor::new(); let (tx, mut rx) = mpsc::channel::(4); let (exit_barrier, signal_exit) = new_barrier(); if !code_server_args.install_extensions.is_empty() { info!( log, "Preloading extensions using stable server: {:?}", code_server_args.install_extensions ); let log = log.clone(); let code_server_args = code_server_args.clone(); let launcher_paths = launcher_paths.clone(); // This is run async to the primary tunnel setup to be speedy. tokio::spawn(async move { if let Err(e) = preload_extensions(&log, platform, code_server_args, launcher_paths).await { warning!(log, "Failed to preload extensions: {:?}", e); } else { info!(log, "Extension install complete"); } }); } loop { tokio::select! { Ok(reason) = shutdown_rx.wait() => { info!(log, "Shutting down: {}", reason); drop(signal_exit); return Ok(ServerTermination { next: match reason { ShutdownSignal::RpcRestartRequested => Next::Restart, _ => Next::Exit, }, tunnel, }); }, c = rx.recv() => { if let Some(ServerSignal::Respawn) = c { drop(signal_exit); return Ok(ServerTermination { next: Next::Respawn, tunnel, }); } }, Some(w) = forwarding.recv() => { forwarding.process(w, &mut tunnel).await; }, l = port.recv() => { let socket = match l { Some(p) => p, None => { warning!(log, "ssh tunnel disposed, tearing down"); return Ok(ServerTermination { next: Next::Restart, tunnel, }); } }; let own_log = log.prefixed(&log::new_rpc_prefix()); let own_tx = tx.clone(); let own_paths = launcher_paths.clone(); let own_exit = exit_barrier.clone(); let own_code_server_args = code_server_args.clone(); let own_forwarding = forwarding.handle(); tokio::spawn(async move { use opentelemetry::trace::{FutureExt, TraceContextExt}; let span = own_log.span("server.socket").with_kind(SpanKind::Consumer).start(own_log.tracer()); let cx = opentelemetry::Context::current_with_span(span); let serve_at = Instant::now(); debug!(own_log, "Serving new connection"); let (writehalf, readhalf) = socket.into_split(); let stats = process_socket(readhalf, writehalf, own_tx, Some(own_forwarding), ServeStreamParams { log: own_log, launcher_paths: own_paths, code_server_args: own_code_server_args, platform, exit_barrier: own_exit, requires_auth: AuthRequired::None, }).with_context(cx.clone()).await; cx.span().add_event( "socket.bandwidth", vec![ KeyValue::new("tx", stats.tx as f64), KeyValue::new("rx", stats.rx as f64), KeyValue::new("duration_ms", serve_at.elapsed().as_millis() as f64), ], ); cx.span().end(); }); } } } } #[derive(Clone)] pub enum AuthRequired { None, VSDA, VSDAWithToken(String), } #[derive(Clone)] pub struct ServeStreamParams { pub log: log::Logger, pub launcher_paths: LauncherPaths, pub code_server_args: CodeServerArgs, pub platform: Platform, pub requires_auth: AuthRequired, pub exit_barrier: Barrier, } pub async fn serve_stream( readhalf: impl AsyncRead + Send + Unpin + 'static, writehalf: impl AsyncWrite + Unpin, params: ServeStreamParams, ) -> SocketStats { // Currently the only server signal is respawn, that doesn't have much meaning // when serving a stream, so make an ignored channel. let (server_rx, server_tx) = mpsc::channel(1); drop(server_tx); process_socket(readhalf, writehalf, server_rx, None, params).await } pub struct SocketStats { rx: usize, tx: usize, } #[allow(clippy::too_many_arguments)] fn make_socket_rpc( log: log::Logger, socket_tx: mpsc::Sender, http_delegated: DelegatedSimpleHttp, launcher_paths: LauncherPaths, code_server_args: CodeServerArgs, port_forwarding: Option, requires_auth: AuthRequired, platform: Platform, http_requests: HttpRequestsMap, ) -> RpcDispatcher { let server_bridges = ServerMultiplexer::new(); let mut rpc = RpcBuilder::new(MsgPackSerializer {}).methods(HandlerContext { did_update: Arc::new(AtomicBool::new(false)), auth_state: Arc::new(std::sync::Mutex::new(match requires_auth { AuthRequired::VSDAWithToken(t) => AuthState::WaitingForChallenge(Some(t)), AuthRequired::VSDA => AuthState::WaitingForChallenge(None), AuthRequired::None => AuthState::Authenticated, })), socket_tx, log: log.clone(), launcher_paths, code_server_args, code_server: Arc::new(Mutex::new(None)), server_bridges, port_forwarding, platform, http: Arc::new(FallbackSimpleHttp::new( ReqwestSimpleHttp::new(), http_delegated, )), http_requests, }); rpc.register_sync("ping", |_: EmptyObject, _| Ok(EmptyObject {})); rpc.register_sync("gethostname", |_: EmptyObject, _| handle_get_hostname()); rpc.register_sync("sys_kill", |p: SysKillRequest, c| { ensure_auth(&c.auth_state)?; handle_sys_kill(p.pid) }); rpc.register_sync("fs_stat", |p: FsSinglePathRequest, c| { ensure_auth(&c.auth_state)?; handle_stat(p.path) }); rpc.register_duplex( "fs_read", 1, move |mut streams, p: FsSinglePathRequest, c| async move { ensure_auth(&c.auth_state)?; handle_fs_read(streams.remove(0), p.path).await }, ); rpc.register_duplex( "fs_write", 1, move |mut streams, p: FsSinglePathRequest, c| async move { ensure_auth(&c.auth_state)?; handle_fs_write(streams.remove(0), p.path).await }, ); rpc.register_duplex( "fs_connect", 1, move |mut streams, p: FsSinglePathRequest, c| async move { ensure_auth(&c.auth_state)?; handle_fs_connect(streams.remove(0), p.path).await }, ); rpc.register_duplex( "net_connect", 1, move |mut streams, n: NetConnectRequest, c| async move { ensure_auth(&c.auth_state)?; handle_net_connect(streams.remove(0), n).await }, ); rpc.register_async("fs_rm", move |p: FsSinglePathRequest, c| async move { ensure_auth(&c.auth_state)?; handle_fs_remove(p.path).await }); rpc.register_sync("fs_mkdirp", |p: FsSinglePathRequest, c| { ensure_auth(&c.auth_state)?; handle_fs_mkdirp(p.path) }); rpc.register_sync("fs_rename", |p: FsRenameRequest, c| { ensure_auth(&c.auth_state)?; handle_fs_rename(p.from_path, p.to_path) }); rpc.register_sync("fs_readdir", |p: FsSinglePathRequest, c| { ensure_auth(&c.auth_state)?; handle_fs_readdir(p.path) }); rpc.register_sync("get_env", |_: EmptyObject, c| { ensure_auth(&c.auth_state)?; handle_get_env() }); rpc.register_sync(METHOD_CHALLENGE_ISSUE, |p: ChallengeIssueParams, c| { handle_challenge_issue(p, &c.auth_state) }); rpc.register_sync(METHOD_CHALLENGE_VERIFY, |p: ChallengeVerifyParams, c| { handle_challenge_verify(p.response, &c.auth_state) }); rpc.register_async("serve", move |params: ServeParams, c| async move { ensure_auth(&c.auth_state)?; handle_serve(c, params).await }); rpc.register_async("update", |p: UpdateParams, c| async move { handle_update(&c.http, &c.log, &c.did_update, &p).await }); rpc.register_sync("servermsg", |m: ServerMessageParams, c| { if let Err(e) = handle_server_message(&c.log, &c.server_bridges, m) { warning!(c.log, "error handling call: {:?}", e); } Ok(EmptyObject {}) }); rpc.register_sync("prune", |_: EmptyObject, c| handle_prune(&c.launcher_paths)); rpc.register_async("callserverhttp", |p: CallServerHttpParams, c| async move { let code_server = c.code_server.lock().await.clone(); handle_call_server_http(code_server, p).await }); rpc.register_async("forward", |p: ForwardParams, c| async move { ensure_auth(&c.auth_state)?; handle_forward(&c.log, &c.port_forwarding, p).await }); rpc.register_async("unforward", |p: UnforwardParams, c| async move { ensure_auth(&c.auth_state)?; handle_unforward(&c.log, &c.port_forwarding, p).await }); rpc.register_async("acquire_cli", |p: AcquireCliParams, c| async move { ensure_auth(&c.auth_state)?; handle_acquire_cli(&c.launcher_paths, &c.http, &c.log, p).await }); rpc.register_duplex("spawn", 3, |mut streams, p: SpawnParams, c| async move { ensure_auth(&c.auth_state)?; handle_spawn( &c.log, p, Some(streams.remove(0)), Some(streams.remove(0)), Some(streams.remove(0)), ) .await }); rpc.register_duplex( "spawn_cli", 3, |mut streams, p: SpawnParams, c| async move { ensure_auth(&c.auth_state)?; handle_spawn_cli( &c.log, p, streams.remove(0), streams.remove(0), streams.remove(0), ) .await }, ); rpc.register_sync("httpheaders", |p: HttpHeadersParams, c| { if let Some(req) = c.http_requests.lock().unwrap().get(&p.req_id) { trace!(c.log, "got {} response for req {}", p.status_code, p.req_id); req.initial_response(p.status_code, p.headers); } else { warning!(c.log, "got response for unknown req {}", p.req_id); } Ok(EmptyObject {}) }); rpc.register_sync("httpbody", move |p: HttpBodyParams, c| { let mut reqs = c.http_requests.lock().unwrap(); if let Some(req) = reqs.get(&p.req_id) { if !p.segment.is_empty() { req.body(p.segment); } if p.complete { trace!(c.log, "delegated request {} completed", p.req_id); reqs.remove(&p.req_id); } } Ok(EmptyObject {}) }); rpc.register_sync( "version", |_: EmptyObject, _| Ok(VersionResponse::default()), ); rpc.build(log) } fn ensure_auth(is_authed: &Arc>) -> Result<(), AnyError> { if let AuthState::Authenticated = &*is_authed.lock().unwrap() { Ok(()) } else { Err(CodeError::ServerAuthRequired.into()) } } #[allow(clippy::too_many_arguments)] // necessary here async fn process_socket( readhalf: impl AsyncRead + Send + Unpin + 'static, mut writehalf: impl AsyncWrite + Unpin, server_tx: mpsc::Sender, port_forwarding: Option, params: ServeStreamParams, ) -> SocketStats { let ServeStreamParams { mut exit_barrier, log, launcher_paths, code_server_args, platform, requires_auth, } = params; let (http_delegated, mut http_rx) = DelegatedSimpleHttp::new(log.clone()); let (socket_tx, mut socket_rx) = mpsc::channel(4); let rx_counter = Arc::new(AtomicUsize::new(0)); let http_requests = Arc::new(std::sync::Mutex::new(HashMap::new())); let already_authed = matches!(requires_auth, AuthRequired::None); let rpc = make_socket_rpc( log.clone(), socket_tx.clone(), http_delegated, launcher_paths, code_server_args, port_forwarding, requires_auth, platform, http_requests.clone(), ); { let log = log.clone(); let rx_counter = rx_counter.clone(); let socket_tx = socket_tx.clone(); let exit_barrier = exit_barrier.clone(); tokio::spawn(async move { if already_authed { send_version(&socket_tx).await; } if let Err(e) = handle_socket_read(&log, readhalf, exit_barrier, &socket_tx, rx_counter, &rpc).await { debug!(log, "closing socket reader: {}", e); socket_tx .send(SocketSignal::CloseWith(CloseReason(format!("{e}")))) .await .ok(); } let ctx = rpc.context(); // The connection is now closed, asked to respawn if needed if ctx.did_update.load(Ordering::SeqCst) { server_tx.send(ServerSignal::Respawn).await.ok(); } ctx.dispose().await; let _ = socket_tx .send(SocketSignal::CloseWith(CloseReason("eof".to_string()))) .await; }); } let mut tx_counter = 0; loop { tokio::select! { _ = exit_barrier.wait() => { writehalf.shutdown().await.ok(); break; }, Some(r) = http_rx.recv() => { let id = next_message_id(); let serialized = rmp_serde::to_vec_named(&ToClientRequest { id: None, params: ClientRequestMethod::makehttpreq(HttpRequestParams { url: &r.url, method: r.method, req_id: id, }), }) .unwrap(); http_requests.lock().unwrap().insert(id, r); tx_counter += serialized.len(); if let Err(e) = writehalf.write_all(&serialized).await { debug!(log, "Closing connection: {}", e); break; } } recv = socket_rx.recv() => match recv { None => break, Some(message) => match message { SocketSignal::Send(bytes) => { tx_counter += bytes.len(); if let Err(e) = writehalf.write_all(&bytes).await { debug!(log, "Closing connection: {}", e); break; } } SocketSignal::CloseWith(reason) => { debug!(log, "Closing connection: {}", reason.0); break; } } } } } SocketStats { tx: tx_counter, rx: rx_counter.load(Ordering::Acquire), } } async fn send_version(tx: &mpsc::Sender) { tx.send(SocketSignal::from_message(&ToClientRequest { id: None, params: ClientRequestMethod::version(VersionResponse::default()), })) .await .ok(); } async fn handle_socket_read( _log: &log::Logger, readhalf: impl AsyncRead + Unpin, mut closer: Barrier, socket_tx: &mpsc::Sender, rx_counter: Arc, rpc: &RpcDispatcher, ) -> Result<(), std::io::Error> { let mut readhalf = BufReader::new(readhalf); let mut decoder = MsgPackCodec::new(); let mut decoder_buf = bytes::BytesMut::new(); loop { let read_len = tokio::select! { r = readhalf.read_buf(&mut decoder_buf) => r, _ = closer.wait() => Err(std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "eof")), }?; if read_len == 0 { return Ok(()); } rx_counter.fetch_add(read_len, Ordering::Relaxed); while let Some(frame) = decoder.decode(&mut decoder_buf)? { match rpc.dispatch_with_partial(&frame.vec, frame.obj) { MaybeSync::Sync(Some(v)) => { if socket_tx.send(SocketSignal::Send(v)).await.is_err() { return Ok(()); } } MaybeSync::Sync(None) => continue, MaybeSync::Future(fut) => { let socket_tx = socket_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { socket_tx.send(SocketSignal::Send(v)).await.ok(); } }); } MaybeSync::Stream((stream, fut)) => { if let Some(stream) = stream { rpc.register_stream(socket_tx.clone(), stream).await; } let socket_tx = socket_tx.clone(); tokio::spawn(async move { if let Some(v) = fut.await { socket_tx.send(SocketSignal::Send(v)).await.ok(); } }); } } } } } #[derive(Clone)] struct ServerOutputSink { tx: mpsc::Sender, } impl log::LogSink for ServerOutputSink { fn write_log(&self, level: log::Level, _prefix: &str, message: &str) { let s = SocketSignal::from_message(&ToClientRequest { id: None, params: ClientRequestMethod::serverlog(ServerLog { line: message, level: level.to_u8(), }), }); self.tx.try_send(s).ok(); } fn write_result(&self, _message: &str) {} } async fn handle_serve( c: Arc, params: ServeParams, ) -> Result { // fill params.extensions into code_server_args.install_extensions let mut csa = c.code_server_args.clone(); csa.connection_token = params.connection_token.or(csa.connection_token); csa.install_extensions.extend(params.extensions.into_iter()); let params_raw = ServerParamsRaw { commit_id: params.commit_id, quality: params.quality, code_server_args: csa, headless: true, platform: c.platform, }; let resolved = if params.use_local_download { params_raw .resolve(&c.log, Arc::new(c.http.delegated())) .await } else { params_raw.resolve(&c.log, c.http.clone()).await }?; let mut server_ref = c.code_server.lock().await; let server = match &*server_ref { Some(o) => o.clone(), None => { let install_log = c.log.tee(ServerOutputSink { tx: c.socket_tx.clone(), }); macro_rules! do_setup { ($sb:expr) => { match $sb.get_running().await? { Some(AnyCodeServer::Socket(s)) => ($sb, Ok(s)), Some(_) => return Err(AnyError::from(MismatchedLaunchModeError())), None => { $sb.setup().await?; let r = $sb.listen_on_default_socket().await; ($sb, r) } } }; } let (sb, server) = if params.use_local_download { let sb = ServerBuilder::new( &install_log, &resolved, &c.launcher_paths, Arc::new(c.http.delegated()), ); do_setup!(sb) } else { let sb = ServerBuilder::new(&install_log, &resolved, &c.launcher_paths, c.http.clone()); do_setup!(sb) }; let server = match server { Ok(s) => s, Err(e) => { // we don't loop to avoid doing so infinitely: allow the client to reconnect in this case. if let AnyError::CodeError(CodeError::ServerUnexpectedExit(ref e)) = e { warning!( c.log, "({}), removing server due to possible corruptions", e ); if let Err(e) = sb.evict().await { warning!(c.log, "Failed to evict server: {}", e); } } return Err(e); } }; server_ref.replace(server.clone()); server } }; attach_server_bridge( &c.log, server, c.socket_tx.clone(), c.server_bridges.clone(), params.socket_id, params.compress, ) .await?; Ok(EmptyObject {}) } async fn attach_server_bridge( log: &log::Logger, code_server: SocketCodeServer, socket_tx: mpsc::Sender, multiplexer: ServerMultiplexer, socket_id: u16, compress: bool, ) -> Result { let (server_messages, decoder) = if compress { ( ServerMessageSink::new_compressed( multiplexer.clone(), socket_id, ServerMessageDestination::Channel(socket_tx), ), ClientMessageDecoder::new_compressed(), ) } else { ( ServerMessageSink::new_plain( multiplexer.clone(), socket_id, ServerMessageDestination::Channel(socket_tx), ), ClientMessageDecoder::new_plain(), ) }; let attached_fut = ServerBridge::new(&code_server.socket, server_messages, decoder).await; match attached_fut { Ok(a) => { multiplexer.register(socket_id, a); trace!(log, "Attached to server"); Ok(socket_id) } Err(e) => Err(e), } } /// Handle an incoming server message. This is synchronous and uses a 'write loop' /// to ensure message order is preserved exactly, which is necessary for compression. fn handle_server_message( log: &log::Logger, multiplexer: &ServerMultiplexer, params: ServerMessageParams, ) -> Result { if multiplexer.write_message(log, params.i, params.body) { Ok(EmptyObject {}) } else { Err(AnyError::from(NoAttachedServerError())) } } fn handle_prune(paths: &LauncherPaths) -> Result, AnyError> { prune_stopped_servers(paths).map(|v| { v.iter() .map(|p| p.server_dir.display().to_string()) .collect() }) } async fn handle_update( http: &Arc, log: &log::Logger, did_update: &AtomicBool, params: &UpdateParams, ) -> Result { if matches!(is_integrated_cli(), Ok(true)) || did_update.load(Ordering::SeqCst) { return Ok(UpdateResult { up_to_date: true, did_update: false, }); } let update_service = UpdateService::new(log.clone(), http.clone()); let updater = SelfUpdate::new(&update_service)?; let latest_release = updater.get_current_release().await?; let up_to_date = updater.is_up_to_date_with(&latest_release); let _ = updater.cleanup_old_update(); if !params.do_update || up_to_date { return Ok(UpdateResult { up_to_date, did_update: false, }); } if did_update .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) .is_err() { return Ok(UpdateResult { up_to_date: true, did_update: true, // well, another thread did, but same difference... }); } info!(log, "Updating CLI to {}", latest_release); let r = updater .do_update(&latest_release, SilentCopyProgress()) .await; if let Err(e) = r { did_update.store(false, Ordering::SeqCst); return Err(e); } Ok(UpdateResult { up_to_date: true, did_update: true, }) } fn handle_get_hostname() -> Result { Ok(GetHostnameResponse { value: gethostname::gethostname().to_string_lossy().into_owned(), }) } fn handle_stat(path: String) -> Result { Ok(std::fs::metadata(path) .map(|m| FsStatResponse { exists: true, size: Some(m.len()), kind: Some(m.file_type().into()), }) .unwrap_or_default()) } async fn handle_fs_read(mut out: DuplexStream, path: String) -> Result { let mut f = tokio::fs::File::open(path) .await .map_err(|e| wrap(e, "file not found"))?; tokio::io::copy(&mut f, &mut out) .await .map_err(|e| wrap(e, "error reading file"))?; Ok(EmptyObject {}) } async fn handle_fs_write(mut input: DuplexStream, path: String) -> Result { let mut f = tokio::fs::File::create(path) .await .map_err(|e| wrap(e, "file not found"))?; tokio::io::copy(&mut input, &mut f) .await .map_err(|e| wrap(e, "error writing file"))?; Ok(EmptyObject {}) } async fn handle_net_connect( mut stream: DuplexStream, req: NetConnectRequest, ) -> Result { let mut s = TcpStream::connect((req.host, req.port)) .await .map_err(|e| wrap(e, "could not connect to address"))?; tokio::io::copy_bidirectional(&mut stream, &mut s) .await .map_err(|e| wrap(e, "error copying stream data"))?; Ok(EmptyObject {}) } async fn handle_fs_connect( mut stream: DuplexStream, path: String, ) -> Result { let mut s = get_socket_rw_stream(&PathBuf::from(path)) .await .map_err(|e| wrap(e, "could not connect to socket"))?; tokio::io::copy_bidirectional(&mut stream, &mut s) .await .map_err(|e| wrap(e, "error copying stream data"))?; Ok(EmptyObject {}) } async fn handle_fs_remove(path: String) -> Result { tokio::fs::remove_dir_all(path) .await .map_err(|e| wrap(e, "error removing directory"))?; Ok(EmptyObject {}) } fn handle_fs_rename(from_path: String, to_path: String) -> Result { std::fs::rename(from_path, to_path).map_err(|e| wrap(e, "error renaming"))?; Ok(EmptyObject {}) } fn handle_fs_mkdirp(path: String) -> Result { std::fs::create_dir_all(path).map_err(|e| wrap(e, "error creating directory"))?; Ok(EmptyObject {}) } fn handle_fs_readdir(path: String) -> Result { let mut entries = std::fs::read_dir(path).map_err(|e| wrap(e, "error listing directory"))?; let mut contents = Vec::new(); while let Some(Ok(child)) = entries.next() { contents.push(FsReadDirEntry { name: child.file_name().to_string_lossy().into_owned(), kind: child.file_type().ok().map(|v| v.into()), }); } Ok(FsReadDirResponse { contents }) } fn handle_sys_kill(pid: u32) -> Result { Ok(SysKillResponse { success: kill_pid(pid), }) } fn handle_get_env() -> Result { Ok(GetEnvResponse { env: std::env::vars().collect(), os_release: os_release().unwrap_or_else(|_| "unknown".to_string()), #[cfg(windows)] os_platform: "win32", #[cfg(target_os = "linux")] os_platform: "linux", #[cfg(target_os = "macos")] os_platform: "darwin", }) } fn handle_challenge_issue( params: ChallengeIssueParams, auth_state: &Arc>, ) -> Result { let challenge = create_challenge(); let mut auth_state = auth_state.lock().unwrap(); if let AuthState::WaitingForChallenge(Some(s)) = &*auth_state { match ¶ms.token { Some(t) if s != t => return Err(CodeError::AuthChallengeBadToken.into()), None => return Err(CodeError::AuthChallengeBadToken.into()), _ => {} } } *auth_state = AuthState::ChallengeIssued(challenge.clone()); Ok(ChallengeIssueResponse { challenge }) } fn handle_challenge_verify( response: String, auth_state: &Arc>, ) -> Result { let mut auth_state = auth_state.lock().unwrap(); match &*auth_state { AuthState::Authenticated => Ok(EmptyObject {}), AuthState::WaitingForChallenge(_) => Err(CodeError::AuthChallengeNotIssued.into()), AuthState::ChallengeIssued(c) => match verify_challenge(c, &response) { false => Err(CodeError::AuthChallengeNotIssued.into()), true => { *auth_state = AuthState::Authenticated; Ok(EmptyObject {}) } }, } } async fn handle_forward( log: &log::Logger, port_forwarding: &Option, params: ForwardParams, ) -> Result { let port_forwarding = port_forwarding .as_ref() .ok_or(CodeError::PortForwardingNotAvailable)?; info!( log, "Forwarding port {} (public={})", params.port, params.public ); let privacy = match params.public { true => PortPrivacy::Public, false => PortPrivacy::Private, }; let uri = port_forwarding.forward(params.port, privacy).await?; Ok(ForwardResult { uri }) } async fn handle_unforward( log: &log::Logger, port_forwarding: &Option, params: UnforwardParams, ) -> Result { let port_forwarding = port_forwarding .as_ref() .ok_or(CodeError::PortForwardingNotAvailable)?; info!(log, "Unforwarding port {}", params.port); port_forwarding.unforward(params.port).await?; Ok(EmptyObject {}) } async fn handle_call_server_http( code_server: Option, params: CallServerHttpParams, ) -> Result { use hyper::{body, client::conn::Builder, Body, Request}; // We use Hyper directly here since reqwest doesn't support sockets/pipes. // See https://github.com/seanmonstar/reqwest/issues/39 let socket = match &code_server { Some(cs) => &cs.socket, None => return Err(AnyError::from(NoAttachedServerError())), }; let rw = get_socket_rw_stream(socket).await?; let (mut request_sender, connection) = Builder::new() .handshake(rw) .await .map_err(|e| wrap(e, "error establishing connection"))?; // start the connection processing; it's shut down when the sender is dropped tokio::spawn(connection); let mut request_builder = Request::builder() .method::<&str>(params.method.as_ref()) .uri(format!("http://127.0.0.1{}", params.path)) .header("Host", "127.0.0.1"); for (k, v) in params.headers { request_builder = request_builder.header(k, v); } let request = request_builder .body(Body::from(params.body.unwrap_or_default())) .map_err(|e| wrap(e, "invalid request"))?; let response = request_sender .send_request(request) .await .map_err(|e| wrap(e, "error sending request"))?; Ok(CallServerHttpResult { status: response.status().as_u16(), headers: response .headers() .into_iter() .map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string())) .collect(), body: body::to_bytes(response) .await .map_err(|e| wrap(e, "error reading response body"))? .to_vec(), }) } async fn handle_acquire_cli( paths: &LauncherPaths, http: &Arc, log: &log::Logger, params: AcquireCliParams, ) -> Result { let update_service = UpdateService::new(log.clone(), http.clone()); let release = match params.commit_id { Some(commit) => Release { name: format!("{PRODUCT_NAME_LONG} CLI"), commit, platform: params.platform, quality: params.quality, target: TargetKind::Cli, }, None => { update_service .get_latest_commit(params.platform, TargetKind::Cli, params.quality) .await? } }; let cli = download_cli_into_cache(&paths.cli_cache, &release, &update_service).await?; let file = tokio::fs::File::open(cli) .await .map_err(|e| wrap(e, "error opening cli file"))?; handle_spawn::<_, DuplexStream>(log, params.spawn, Some(file), None, None).await } async fn handle_spawn( log: &log::Logger, params: SpawnParams, stdin: Option, stdout: Option, stderr: Option, ) -> Result where Stdin: AsyncRead + Unpin + Send + 'static, StdoutAndErr: AsyncWrite + Unpin + Send + 'static, { debug!( log, "requested to spawn {} with args {:?}", params.command, params.args ); macro_rules! pipe_if { ($e: expr) => { if $e { Stdio::piped() } else { Stdio::null() } }; } let mut p = new_tokio_command(¶ms.command); p.args(¶ms.args); p.envs(¶ms.env); p.stdin(pipe_if!(stdin.is_some())); p.stdout(pipe_if!(stdin.is_some())); p.stderr(pipe_if!(stderr.is_some())); if let Some(cwd) = ¶ms.cwd { p.current_dir(cwd); } #[cfg(target_os = "windows")] p.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW); let mut p = p.spawn().map_err(CodeError::ProcessSpawnFailed)?; let block_futs = FuturesUnordered::new(); let poll_futs = FuturesUnordered::new(); if let (Some(mut a), Some(mut b)) = (p.stdout.take(), stdout) { block_futs.push(async move { tokio::io::copy(&mut a, &mut b).await }.boxed()); } if let (Some(mut a), Some(mut b)) = (p.stderr.take(), stderr) { block_futs.push(async move { tokio::io::copy(&mut a, &mut b).await }.boxed()); } if let (Some(mut b), Some(mut a)) = (p.stdin.take(), stdin) { poll_futs.push(async move { tokio::io::copy(&mut a, &mut b).await }.boxed()); } wait_for_process_exit(log, ¶ms.command, p, block_futs, poll_futs).await } async fn handle_spawn_cli( log: &log::Logger, params: SpawnParams, mut protocol_in: DuplexStream, mut protocol_out: DuplexStream, mut log_out: DuplexStream, ) -> Result { debug!( log, "requested to spawn cli {} with args {:?}", params.command, params.args ); let mut p = new_tokio_command(¶ms.command); p.args(¶ms.args); // CLI args to spawn a server; contracted with clients that they should _not_ provide these. p.arg("--verbose"); p.arg("command-shell"); p.envs(¶ms.env); p.stdin(Stdio::piped()); p.stdout(Stdio::piped()); p.stderr(Stdio::piped()); if let Some(cwd) = ¶ms.cwd { p.current_dir(cwd); } let mut p = p.spawn().map_err(CodeError::ProcessSpawnFailed)?; let mut stdin = p.stdin.take().unwrap(); let mut stdout = p.stdout.take().unwrap(); let mut stderr = p.stderr.take().unwrap(); // Start handling logs while doing the handshake in case there's some kind of error let log_pump = tokio::spawn(async move { tokio::io::copy(&mut stdout, &mut log_out).await }); // note: intentionally do not wrap stdin in a bufreader, since we don't // want to read anything other than our handshake messages. if let Err(e) = spawn_do_child_authentication(log, &mut stdin, &mut stderr).await { warning!(log, "failed to authenticate with child process {}", e); let _ = p.kill().await; return Err(e.into()); } debug!(log, "cli authenticated, attaching stdio"); let block_futs = FuturesUnordered::new(); let poll_futs = FuturesUnordered::new(); poll_futs.push(async move { tokio::io::copy(&mut protocol_in, &mut stdin).await }.boxed()); block_futs.push(async move { tokio::io::copy(&mut stderr, &mut protocol_out).await }.boxed()); block_futs.push(async move { log_pump.await.unwrap() }.boxed()); wait_for_process_exit(log, ¶ms.command, p, block_futs, poll_futs).await } type TokioCopyFuture = dyn futures::Future> + Send; async fn get_joined_result( mut process: tokio::process::Child, block_futs: FuturesUnordered>>, ) -> Result { let (_, r) = tokio::join!(futures::future::join_all(block_futs), process.wait()); r } /// Wait for the process to exit and sends the spawn result. Waits until the /// `block_futs` and the process have exited, and polls the `poll_futs` while /// doing so. async fn wait_for_process_exit( log: &log::Logger, command: &str, process: tokio::process::Child, block_futs: FuturesUnordered>>, poll_futs: FuturesUnordered>>, ) -> Result { let joined = get_joined_result(process, block_futs); pin!(joined); let r = tokio::select! { _ = futures::future::join_all(poll_futs) => joined.await, r = &mut joined => r, }; let r = match r { Ok(e) => SpawnResult { message: e.to_string(), exit_code: e.code().unwrap_or(-1), }, Err(e) => SpawnResult { message: e.to_string(), exit_code: -1, }, }; debug!( log, "spawned cli {} exited with code {}", command, r.exit_code ); Ok(r) } async fn spawn_do_child_authentication( log: &log::Logger, stdin: &mut ChildStdin, stdout: &mut ChildStderr, ) -> Result<(), CodeError> { let (msg_tx, msg_rx) = mpsc::unbounded_channel(); let (shutdown_rx, shutdown) = new_barrier(); let mut rpc = new_msgpack_rpc(); let caller = rpc.get_caller(msg_tx); let challenge_response = do_challenge_response_flow(caller, shutdown); let rpc = start_msgpack_rpc( rpc.methods(()).build(log.prefixed("client-auth")), stdout, stdin, msg_rx, shutdown_rx, ); pin!(rpc); tokio::select! { r = &mut rpc => { match r { // means shutdown happened cleanly already, we're good Ok(_) => Ok(()), Err(e) => Err(CodeError::ProcessSpawnHandshakeFailed(e)) } }, r = challenge_response => { r?; rpc.await.map(|_| ()).map_err(CodeError::ProcessSpawnFailed) } } } async fn do_challenge_response_flow( caller: RpcCaller, shutdown: BarrierOpener<()>, ) -> Result<(), CodeError> { let challenge: ChallengeIssueResponse = caller .call(METHOD_CHALLENGE_ISSUE, EmptyObject {}) .await .unwrap() .map_err(CodeError::TunnelRpcCallFailed)?; let _: EmptyObject = caller .call( METHOD_CHALLENGE_VERIFY, ChallengeVerifyParams { response: sign_challenge(&challenge.challenge), }, ) .await .unwrap() .map_err(CodeError::TunnelRpcCallFailed)?; shutdown.open(()); Ok(()) } ================================================ FILE: cli/src/tunnels/dev_tunnels.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::protocol::{self, PortPrivacy, PortProtocol}; use crate::auth; use crate::constants::{IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, TUNNEL_SERVICE_USER_AGENT}; use crate::state::{LauncherPaths, PersistedState}; use crate::util::errors::{ wrap, AnyError, CodeError, DevTunnelError, InvalidTunnelName, TunnelCreationFailed, WrappedError, }; use crate::util::input::prompt_placeholder; use crate::{debug, info, log, spanf, trace, warning}; use async_trait::async_trait; use futures::future::BoxFuture; use futures::{FutureExt, TryFutureExt}; use lazy_static::lazy_static; use rand::prelude::IteratorRandom; use regex::Regex; use reqwest::StatusCode; use serde::{Deserialize, Serialize}; use std::sync::{Arc, Mutex}; use std::time::Duration; use tokio::sync::{mpsc, watch}; use tunnels::connections::{ForwardedPortConnection, RelayTunnelHost}; use tunnels::contracts::{ Tunnel, TunnelAccessControl, TunnelPort, TunnelRelayTunnelEndpoint, PORT_TOKEN, TUNNEL_ACCESS_SCOPES_CONNECT, TUNNEL_PROTOCOL_AUTO, }; use tunnels::management::{ new_tunnel_management, HttpError, TunnelLocator, TunnelManagementClient, TunnelRequestOptions, NO_REQUEST_OPTIONS, }; static TUNNEL_COUNT_LIMIT_NAME: &str = "TunnelsPerUserPerLocation"; #[allow(dead_code)] mod tunnel_flags { use crate::{log, tunnels::wsl_detect::is_wsl_installed}; pub const IS_WSL_INSTALLED: u32 = 1 << 0; pub const IS_WINDOWS: u32 = 1 << 1; pub const IS_LINUX: u32 = 1 << 2; pub const IS_MACOS: u32 = 1 << 3; /// Creates a flag string for the tunnel pub fn create(log: &log::Logger) -> String { let mut flags = 0; #[cfg(windows)] { flags |= IS_WINDOWS; } #[cfg(target_os = "linux")] { flags |= IS_LINUX; } #[cfg(target_os = "macos")] { flags |= IS_MACOS; } if is_wsl_installed(log) { flags |= IS_WSL_INSTALLED; } format!("_flag{flags}") } } #[derive(Clone, Serialize, Deserialize)] pub struct PersistedTunnel { pub name: String, pub id: String, pub cluster: String, } impl PersistedTunnel { pub fn into_locator(self) -> TunnelLocator { TunnelLocator::ID { cluster: self.cluster, id: self.id, } } pub fn locator(&self) -> TunnelLocator { TunnelLocator::ID { cluster: self.cluster.clone(), id: self.id.clone(), } } } #[async_trait] trait AccessTokenProvider: Send + Sync { /// Gets the current access token. async fn refresh_token(&self) -> Result; /// Maintains the stored credential by refreshing it against the service /// to ensure its stays current. Returns a future that should be polled and /// only completes if a refresh fails in a consistent way. fn keep_alive(&self) -> BoxFuture<'static, Result<(), AnyError>>; } /// Access token provider that provides a fixed token without refreshing. struct StaticAccessTokenProvider(String); impl StaticAccessTokenProvider { pub fn new(token: String) -> Self { Self(token) } } #[async_trait] impl AccessTokenProvider for StaticAccessTokenProvider { async fn refresh_token(&self) -> Result { Ok(self.0.clone()) } fn keep_alive(&self) -> BoxFuture<'static, Result<(), AnyError>> { futures::future::pending().boxed() } } /// Access token provider that looks up the token from the tunnels API. struct LookupAccessTokenProvider { auth: auth::Auth, client: TunnelManagementClient, locator: TunnelLocator, log: log::Logger, initial_token: Arc>>, } impl LookupAccessTokenProvider { pub fn new( auth: auth::Auth, client: TunnelManagementClient, locator: TunnelLocator, log: log::Logger, initial_token: Option, ) -> Self { Self { auth, client, locator, log, initial_token: Arc::new(Mutex::new(initial_token)), } } } #[async_trait] impl AccessTokenProvider for LookupAccessTokenProvider { async fn refresh_token(&self) -> Result { if let Some(token) = self.initial_token.lock().unwrap().take() { return Ok(token); } let tunnel_lookup = spanf!( self.log, self.log.span("dev-tunnel.tag.get"), self.client.get_tunnel( &self.locator, &TunnelRequestOptions { token_scopes: vec!["host".to_string()], ..Default::default() } ) ); trace!(self.log, "Successfully refreshed access token"); match tunnel_lookup { Ok(tunnel) => Ok(get_host_token_from_tunnel(&tunnel)), Err(e) => Err(wrap(e, "failed to lookup tunnel for host token")), } } fn keep_alive(&self) -> BoxFuture<'static, Result<(), AnyError>> { let auth = self.auth.clone(); auth.keep_token_alive().boxed() } } #[derive(Clone)] pub struct DevTunnels { auth: auth::Auth, log: log::Logger, launcher_tunnel: PersistedState>, client: TunnelManagementClient, tag: &'static str, } /// Representation of a tunnel returned from the `start` methods. pub struct ActiveTunnel { /// Name of the tunnel pub name: String, /// Underlying dev tunnels ID pub id: String, manager: ActiveTunnelManager, } impl ActiveTunnel { /// Closes and unregisters the tunnel. pub async fn close(&mut self) -> Result<(), AnyError> { self.manager.kill().await?; Ok(()) } /// Forwards a port to local connections. pub async fn add_port_direct( &mut self, port_number: u16, ) -> Result, AnyError> { let port = self.manager.add_port_direct(port_number).await?; Ok(port) } /// Forwards a port over TCP. pub async fn add_port_tcp( &self, port_number: u16, privacy: PortPrivacy, protocol: PortProtocol, ) -> Result<(), AnyError> { self.manager .add_port_tcp(port_number, privacy, protocol) .await?; Ok(()) } /// Removes a forwarded port TCP. pub async fn remove_port(&self, port_number: u16) -> Result<(), AnyError> { self.manager.remove_port(port_number).await?; Ok(()) } /// Gets the template string for forming forwarded port web URIs.. pub fn get_port_format(&self) -> Result { if let Some(details) = &*self.manager.endpoint_rx.borrow() { return details .as_ref() .map(|r| { r.base .port_uri_format .clone() .expect("expected to have port format") }) .map_err(|e| e.clone().into()); } Err(CodeError::NoTunnelEndpoint.into()) } /// Gets the public URI on which a forwarded port can be access in browser. pub fn get_port_uri(&self, port: u16) -> Result { self.get_port_format() .map(|f| f.replace(PORT_TOKEN, &port.to_string())) } /// Gets an object to read the current tunnel status. pub fn status(&self) -> StatusLock { self.manager.get_status() } } const VSCODE_CLI_TUNNEL_TAG: &str = "vscode-server-launcher"; const VSCODE_CLI_FORWARDING_TAG: &str = "vscode-port-forward"; const OWNED_TUNNEL_TAGS: &[&str] = &[VSCODE_CLI_TUNNEL_TAG, VSCODE_CLI_FORWARDING_TAG]; const MAX_TUNNEL_NAME_LENGTH: usize = 20; fn get_host_token_from_tunnel(tunnel: &Tunnel) -> String { tunnel .access_tokens .as_ref() .expect("expected to have access tokens") .get("host") .expect("expected to have host token") .to_string() } fn is_valid_name(name: &str) -> Result<(), InvalidTunnelName> { if name.len() > MAX_TUNNEL_NAME_LENGTH { return Err(InvalidTunnelName(format!( "Names cannot be longer than {MAX_TUNNEL_NAME_LENGTH} characters. Please try a different name." ))); } let re = Regex::new(r"^([\w-]+)$").unwrap(); if !re.is_match(name) { return Err(InvalidTunnelName( "Names can only contain letters, numbers, and '-'. Spaces, commas, and all other special characters are not allowed. Please try a different name.".to_string() )); } Ok(()) } lazy_static! { static ref HOST_TUNNEL_REQUEST_OPTIONS: TunnelRequestOptions = TunnelRequestOptions { include_ports: true, token_scopes: vec!["host".to_string()], ..Default::default() }; } /// Structure optionally passed into `start_existing_tunnel` to forward an existing tunnel. #[derive(Clone, Debug)] pub struct ExistingTunnel { /// Name you'd like to assign preexisting tunnel to use to connect to the VS Code Server pub tunnel_name: Option, /// Token to authenticate and use preexisting tunnel pub host_token: String, /// Id of preexisting tunnel to use to connect to the VS Code Server pub tunnel_id: String, /// Cluster of preexisting tunnel to use to connect to the VS Code Server pub cluster: String, } impl DevTunnels { /// Creates a new DevTunnels client used for port forwarding. pub fn new_port_forwarding( log: &log::Logger, auth: auth::Auth, paths: &LauncherPaths, ) -> DevTunnels { let mut client = new_tunnel_management(&TUNNEL_SERVICE_USER_AGENT); client.authorization_provider(auth.clone()); DevTunnels { auth, log: log.clone(), client: client.into(), launcher_tunnel: PersistedState::new(paths.root().join("port_forwarding_tunnel.json")), tag: VSCODE_CLI_FORWARDING_TAG, } } /// Creates a new DevTunnels client used for the Remote Tunnels extension to access the VS Code Server. pub fn new_remote_tunnel( log: &log::Logger, auth: auth::Auth, paths: &LauncherPaths, ) -> DevTunnels { let mut client = new_tunnel_management(&TUNNEL_SERVICE_USER_AGENT); client.authorization_provider(auth.clone()); DevTunnels { auth, log: log.clone(), client: client.into(), launcher_tunnel: PersistedState::new(paths.root().join("code_tunnel.json")), tag: VSCODE_CLI_TUNNEL_TAG, } } pub async fn remove_tunnel(&mut self) -> Result<(), AnyError> { let tunnel = match self.launcher_tunnel.load() { Some(t) => t, None => { return Ok(()); } }; spanf!( self.log, self.log.span("dev-tunnel.delete"), self.client .delete_tunnel(&tunnel.into_locator(), NO_REQUEST_OPTIONS) ) .map_err(|e| wrap(e, "failed to execute `tunnel delete`"))?; self.launcher_tunnel.save(None)?; Ok(()) } /// Renames the current tunnel to the new name. pub async fn rename_tunnel(&mut self, name: &str) -> Result<(), AnyError> { self.update_tunnel_name(self.launcher_tunnel.load(), name) .await .map(|_| ()) } /// Updates the name of the existing persisted tunnel to the new name. /// Gracefully creates a new tunnel if the previous one was deleted. async fn update_tunnel_name( &mut self, persisted: Option, name: &str, ) -> Result<(Tunnel, PersistedTunnel), AnyError> { let name = name.to_ascii_lowercase(); let (mut full_tunnel, mut persisted, is_new) = match persisted { Some(persisted) => { debug!( self.log, "Found a persisted tunnel, seeing if the name matches..." ); self.get_or_create_tunnel(persisted, Some(&name), NO_REQUEST_OPTIONS) .await } None => { debug!(self.log, "Creating a new tunnel with the requested name"); self.create_tunnel(&name, NO_REQUEST_OPTIONS) .await .map(|(pt, t)| (t, pt, true)) } }?; let desired_tags = self.get_labels(&name); if is_new || vec_eq_as_set(&full_tunnel.labels, &desired_tags) { return Ok((full_tunnel, persisted)); } debug!(self.log, "Tunnel name changed, applying updates..."); full_tunnel.labels = desired_tags; let updated_tunnel = spanf!( self.log, self.log.span("dev-tunnel.tag.update"), self.client.update_tunnel(&full_tunnel, NO_REQUEST_OPTIONS) ) .map_err(|e| wrap(e, "failed to rename tunnel"))?; persisted.name = name; self.launcher_tunnel.save(Some(persisted.clone()))?; Ok((updated_tunnel, persisted)) } /// Gets the persisted tunnel from the service, or creates a new one. /// If `create_with_new_name` is given, the new tunnel has that name /// instead of the one previously persisted. async fn get_or_create_tunnel( &mut self, persisted: PersistedTunnel, create_with_new_name: Option<&str>, options: &TunnelRequestOptions, ) -> Result<(Tunnel, PersistedTunnel, /* is_new */ bool), AnyError> { let tunnel_lookup = spanf!( self.log, self.log.span("dev-tunnel.tag.get"), self.client.get_tunnel(&persisted.locator(), options) ); match tunnel_lookup { Ok(ft) => Ok((ft, persisted, false)), Err(HttpError::ResponseError(e)) if e.status_code == StatusCode::NOT_FOUND || e.status_code == StatusCode::FORBIDDEN => { let (persisted, tunnel) = self .create_tunnel(create_with_new_name.unwrap_or(&persisted.name), options) .await?; Ok((tunnel, persisted, true)) } Err(e) => Err(wrap(e, "failed to lookup tunnel").into()), } } /// Starts a new tunnel for the code server on the port. Unlike `start_new_tunnel`, /// this attempts to reuse or create a tunnel of a preferred name or of a generated friendly tunnel name. pub async fn start_new_launcher_tunnel( &mut self, preferred_name: Option<&str>, use_random_name: bool, preserve_ports: &[u16], ) -> Result { let (mut tunnel, persisted) = match self.launcher_tunnel.load() { Some(mut persisted) => { if let Some(preferred_name) = preferred_name.map(|n| n.to_ascii_lowercase()) { if persisted.name.to_ascii_lowercase() != preferred_name { (_, persisted) = self .update_tunnel_name(Some(persisted), &preferred_name) .await?; } } let (tunnel, persisted, _) = self .get_or_create_tunnel(persisted, None, &HOST_TUNNEL_REQUEST_OPTIONS) .await?; (tunnel, persisted) } None => { debug!(self.log, "No code server tunnel found, creating new one"); let name = self .get_name_for_tunnel(preferred_name, use_random_name) .await?; let (persisted, full_tunnel) = self .create_tunnel(&name, &HOST_TUNNEL_REQUEST_OPTIONS) .await?; (full_tunnel, persisted) } }; tunnel = self .sync_tunnel_tags( &self.client, &persisted.name, tunnel, &HOST_TUNNEL_REQUEST_OPTIONS, ) .await?; let locator = TunnelLocator::try_from(&tunnel).unwrap(); let host_token = get_host_token_from_tunnel(&tunnel); for port_to_delete in tunnel .ports .iter() .filter(|p: &&TunnelPort| !preserve_ports.contains(&p.port_number)) { let output_fut = self.client.delete_tunnel_port( &locator, port_to_delete.port_number, NO_REQUEST_OPTIONS, ); spanf!( self.log, self.log.span("dev-tunnel.port.delete"), output_fut ) .map_err(|e| wrap(e, "failed to delete port"))?; } // cleanup any old trailing tunnel endpoints for endpoint in tunnel.endpoints { let fut = self.client.delete_tunnel_endpoints( &locator, &endpoint.host_id, NO_REQUEST_OPTIONS, ); spanf!(self.log, self.log.span("dev-tunnel.endpoint.prune"), fut) .map_err(|e| wrap(e, "failed to prune tunnel endpoint"))?; } self.start_tunnel( locator.clone(), &persisted, self.client.clone(), LookupAccessTokenProvider::new( self.auth.clone(), self.client.clone(), locator, self.log.clone(), Some(host_token), ), ) .await } async fn create_tunnel( &mut self, name: &str, options: &TunnelRequestOptions, ) -> Result<(PersistedTunnel, Tunnel), AnyError> { info!(self.log, "Creating tunnel with the name: {}", name); let tunnel = match self.get_existing_tunnel_with_name(name).await? { Some(e) => { if tunnel_has_host_connection(&e) { return Err(CodeError::TunnelActiveAndInUse(name.to_string()).into()); } let loc = TunnelLocator::try_from(&e).unwrap(); info!(self.log, "Adopting existing tunnel (ID={:?})", loc); spanf!( self.log, self.log.span("dev-tunnel.tag.get"), self.client.get_tunnel(&loc, &HOST_TUNNEL_REQUEST_OPTIONS) ) .map_err(|e| wrap(e, "failed to lookup tunnel"))? } None => loop { let result = spanf!( self.log, self.log.span("dev-tunnel.create"), self.client.create_tunnel( Tunnel { labels: self.get_labels(name), ..Default::default() }, options ) ); match result { Err(HttpError::ResponseError(e)) if e.status_code == StatusCode::TOO_MANY_REQUESTS => { if let Some(d) = e.get_details() { let detail = d.detail.unwrap_or_else(|| "unknown".to_string()); if detail.contains(TUNNEL_COUNT_LIMIT_NAME) && self.try_recycle_tunnel().await? { continue; } return Err(AnyError::from(TunnelCreationFailed( name.to_string(), detail, ))); } return Err(AnyError::from(TunnelCreationFailed( name.to_string(), "You have exceeded a limit for the port fowarding service. Please remove other machines before trying to add this machine.".to_string(), ))); } Err(e) => { return Err(AnyError::from(TunnelCreationFailed( name.to_string(), format!("{e:?}"), ))) } Ok(t) => break t, } }, }; let pt = PersistedTunnel { cluster: tunnel.cluster_id.clone().unwrap(), id: tunnel.tunnel_id.clone().unwrap(), name: name.to_string(), }; self.launcher_tunnel.save(Some(pt.clone()))?; Ok((pt, tunnel)) } /// Gets the expected tunnel tags fn get_labels(&self, name: &str) -> Vec { vec![ name.to_string(), PROTOCOL_VERSION_TAG.to_string(), self.tag.to_string(), tunnel_flags::create(&self.log), ] } /// Ensures the tunnel contains a tag for the current PROTCOL_VERSION, and no /// other version tags. async fn sync_tunnel_tags( &self, client: &TunnelManagementClient, name: &str, tunnel: Tunnel, options: &TunnelRequestOptions, ) -> Result { let new_labels = self.get_labels(name); if vec_eq_as_set(&tunnel.labels, &new_labels) { return Ok(tunnel); } debug!( self.log, "Updating tunnel tags {} -> {}", tunnel.labels.join(", "), new_labels.join(", ") ); let tunnel_update = Tunnel { labels: new_labels, tunnel_id: tunnel.tunnel_id.clone(), cluster_id: tunnel.cluster_id.clone(), ..Default::default() }; let result = spanf!( self.log, self.log.span("dev-tunnel.protocol-tag-update"), client.update_tunnel(&tunnel_update, options) ); result.map_err(|e| wrap(e, "tunnel tag update failed").into()) } /// Tries to delete an unused tunnel, and then creates a tunnel with the /// given `new_name`. async fn try_recycle_tunnel(&mut self) -> Result { trace!( self.log, "Tunnel limit hit, trying to recycle an old tunnel" ); let existing_tunnels = self.list_tunnels_with_tag(OWNED_TUNNEL_TAGS).await?; let recyclable = existing_tunnels .iter() .filter(|t| !tunnel_has_host_connection(t)) .choose(&mut rand::thread_rng()); match recyclable { Some(tunnel) => { trace!(self.log, "Recycling tunnel ID {:?}", tunnel.tunnel_id); spanf!( self.log, self.log.span("dev-tunnel.delete"), self.client .delete_tunnel(&tunnel.try_into().unwrap(), NO_REQUEST_OPTIONS) ) .map_err(|e| wrap(e, "failed to execute `tunnel delete`"))?; Ok(true) } None => { trace!(self.log, "No tunnels available to recycle"); Ok(false) } } } async fn list_tunnels_with_tag( &mut self, tags: &[&'static str], ) -> Result, AnyError> { let tunnels = spanf!( self.log, self.log.span("dev-tunnel.listall"), self.client.list_all_tunnels(&TunnelRequestOptions { labels: tags.iter().map(|t| t.to_string()).collect(), ..Default::default() }) ) .map_err(|e| wrap(e, "error listing current tunnels"))?; Ok(tunnels) } async fn get_existing_tunnel_with_name(&self, name: &str) -> Result, AnyError> { let existing: Vec = spanf!( self.log, self.log.span("dev-tunnel.rename.search"), self.client.list_all_tunnels(&TunnelRequestOptions { labels: vec![self.tag.to_string(), name.to_string()], require_all_labels: true, limit: 1, include_ports: true, token_scopes: vec!["host".to_string()], ..Default::default() }) ) .map_err(|e| wrap(e, "failed to list existing tunnels"))?; Ok(existing.into_iter().next()) } fn get_placeholder_name() -> String { let mut n = clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); n.make_ascii_lowercase(); n.truncate(MAX_TUNNEL_NAME_LENGTH); n } async fn get_name_for_tunnel( &mut self, preferred_name: Option<&str>, mut use_random_name: bool, ) -> Result { let existing_tunnels = self.list_tunnels_with_tag(&[self.tag]).await?; let is_name_free = |n: &str| { !existing_tunnels .iter() .any(|v| tunnel_has_host_connection(v) && v.labels.iter().any(|t| t == n)) }; if let Some(machine_name) = preferred_name { let name = machine_name.to_ascii_lowercase(); if let Err(e) = is_valid_name(&name) { info!(self.log, "{} is an invalid name", e); return Err(AnyError::from(wrap(e, "invalid name"))); } if is_name_free(&name) { return Ok(name); } info!( self.log, "{} is already taken, using a random name instead", &name ); use_random_name = true; } let mut placeholder_name = Self::get_placeholder_name(); if !is_name_free(&placeholder_name) { for i in 2.. { let fixed_name = format!("{placeholder_name}{i}"); if is_name_free(&fixed_name) { placeholder_name = fixed_name; break; } } } if use_random_name || !*IS_INTERACTIVE_CLI { return Ok(placeholder_name); } loop { let mut name = prompt_placeholder( "What would you like to call this machine?", &placeholder_name, )?; name.make_ascii_lowercase(); if let Err(e) = is_valid_name(&name) { info!(self.log, "{}", e); continue; } if is_name_free(&name) { return Ok(name); } info!(self.log, "The name {} is already in use", name); } } /// Hosts an existing tunnel, where the tunnel ID and host token are given. pub async fn start_existing_tunnel( &mut self, tunnel: ExistingTunnel, ) -> Result { let tunnel_details = PersistedTunnel { name: match tunnel.tunnel_name { Some(n) => n, None => Self::get_placeholder_name(), }, id: tunnel.tunnel_id, cluster: tunnel.cluster, }; let mut mgmt = self.client.build(); mgmt.authorization(tunnels::management::Authorization::Tunnel( tunnel.host_token.clone(), )); let client = mgmt.into(); self.sync_tunnel_tags( &client, &tunnel_details.name, Tunnel { cluster_id: Some(tunnel_details.cluster.clone()), tunnel_id: Some(tunnel_details.id.clone()), ..Default::default() }, &HOST_TUNNEL_REQUEST_OPTIONS, ) .await?; self.start_tunnel( tunnel_details.locator(), &tunnel_details, client, StaticAccessTokenProvider::new(tunnel.host_token), ) .await } async fn start_tunnel( &mut self, locator: TunnelLocator, tunnel_details: &PersistedTunnel, client: TunnelManagementClient, access_token: impl AccessTokenProvider + 'static, ) -> Result { let mut manager = ActiveTunnelManager::new(self.log.clone(), client, locator, access_token); let endpoint_result = spanf!( self.log, self.log.span("dev-tunnel.serve.callback"), manager.get_endpoint() ); let endpoint = match endpoint_result { Ok(endpoint) => endpoint, Err(e) => { error!(self.log, "Error connecting to tunnel endpoint: {}", e); manager.kill().await.ok(); return Err(e); } }; debug!(self.log, "Connected to tunnel endpoint: {:?}", endpoint); Ok(ActiveTunnel { name: tunnel_details.name.clone(), id: tunnel_details.id.clone(), manager, }) } } #[derive(Clone, Default)] pub struct StatusLock(Arc>); impl StatusLock { fn succeed(&self) { let mut status = self.0.lock().unwrap(); status.tunnel = protocol::singleton::TunnelState::Connected; status.last_connected_at = Some(chrono::Utc::now()); } fn fail(&self, reason: String) { let mut status = self.0.lock().unwrap(); if let protocol::singleton::TunnelState::Connected = status.tunnel { status.last_disconnected_at = Some(chrono::Utc::now()); status.tunnel = protocol::singleton::TunnelState::Disconnected; } status.last_fail_reason = Some(reason); } pub fn read(&self) -> protocol::singleton::Status { let status = self.0.lock().unwrap(); status.clone() } } struct ActiveTunnelManager { close_tx: Option>, endpoint_rx: watch::Receiver>>, relay: Arc>, status: StatusLock, } impl ActiveTunnelManager { pub fn new( log: log::Logger, mgmt: TunnelManagementClient, locator: TunnelLocator, access_token: impl AccessTokenProvider + 'static, ) -> ActiveTunnelManager { let (endpoint_tx, endpoint_rx) = watch::channel(None); let (close_tx, close_rx) = mpsc::channel(1); let relay = Arc::new(tokio::sync::Mutex::new(RelayTunnelHost::new(locator, mgmt))); let relay_spawned = relay.clone(); let status = StatusLock::default(); let status_spawned = status.clone(); tokio::spawn(async move { ActiveTunnelManager::spawn_tunnel( log, relay_spawned, close_rx, endpoint_tx, access_token, status_spawned, ) .await; }); ActiveTunnelManager { endpoint_rx, relay, close_tx: Some(close_tx), status, } } /// Gets a copy of the current tunnel status information pub fn get_status(&self) -> StatusLock { self.status.clone() } /// Adds a port for TCP/IP forwarding. pub async fn add_port_tcp( &self, port_number: u16, privacy: PortPrivacy, protocol: PortProtocol, ) -> Result<(), WrappedError> { self.relay .lock() .await .add_port(&TunnelPort { port_number, protocol: Some(protocol.to_contract_str().to_string()), access_control: Some(privacy_to_tunnel_acl(privacy)), ..Default::default() }) .await .map_err(|e| wrap(e, "error adding port to relay"))?; Ok(()) } /// Adds a port for TCP/IP forwarding. pub async fn add_port_direct( &self, port_number: u16, ) -> Result, WrappedError> { self.relay .lock() .await .add_port_raw(&TunnelPort { port_number, protocol: Some(TUNNEL_PROTOCOL_AUTO.to_owned()), access_control: Some(privacy_to_tunnel_acl(PortPrivacy::Private)), ..Default::default() }) .await .map_err(|e| wrap(e, "error adding port to relay")) } /// Removes a port from TCP/IP forwarding. pub async fn remove_port(&self, port_number: u16) -> Result<(), WrappedError> { self.relay .lock() .await .remove_port(port_number) .await .map_err(|e| wrap(e, "error remove port from relay")) } /// Gets the most recent details from the tunnel process. Returns None if /// the process exited before providing details. pub async fn get_endpoint(&mut self) -> Result { loop { if let Some(details) = &*self.endpoint_rx.borrow() { return details.clone().map_err(AnyError::from); } if self.endpoint_rx.changed().await.is_err() { return Err(DevTunnelError("tunnel creation cancelled".to_string()).into()); } } } /// Kills the process, and waits for it to exit. /// See https://tokio.rs/tokio/topics/shutdown#waiting-for-things-to-finish-shutting-down for how this works pub async fn kill(&mut self) -> Result<(), AnyError> { if let Some(tx) = self.close_tx.take() { drop(tx); } self.relay .lock() .await .unregister() .await .map_err(|e| wrap(e, "error unregistering relay"))?; while self.endpoint_rx.changed().await.is_ok() {} Ok(()) } async fn spawn_tunnel( log: log::Logger, relay: Arc>, mut close_rx: mpsc::Receiver<()>, endpoint_tx: watch::Sender>>, access_token_provider: impl AccessTokenProvider + 'static, status: StatusLock, ) { let mut token_ka = access_token_provider.keep_alive(); let mut backoff = Backoff::new(Duration::from_secs(5), Duration::from_secs(120)); macro_rules! fail { ($e: expr, $msg: expr) => { let fmt = format!("{}: {}", $msg, $e); warning!(log, &fmt); status.fail(fmt); endpoint_tx.send(Some(Err($e))).ok(); backoff.delay().await; }; } loop { debug!(log, "Starting tunnel to server..."); let access_token = match access_token_provider.refresh_token().await { Ok(t) => t, Err(e) => { fail!(e, "Error refreshing access token, will retry"); continue; } }; // we don't bother making a client that can refresh the token, since // the tunnel won't be able to host as soon as the access token expires. let handle_res = { let mut relay = relay.lock().await; relay .connect(&access_token) .await .map_err(|e| wrap(e, "error connecting to tunnel")) }; let mut handle = match handle_res { Ok(handle) => handle, Err(e) => { fail!(e, "Error connecting to relay, will retry"); continue; } }; backoff.reset(); status.succeed(); endpoint_tx.send(Some(Ok(handle.endpoint().clone()))).ok(); tokio::select! { // error is mapped like this prevent it being used across an await, // which Rust dislikes since there's a non-sendable dyn Error in there res = (&mut handle).map_err(|e| wrap(e, "error from tunnel connection")) => { if let Err(e) = res { fail!(e, "Tunnel exited unexpectedly, reconnecting"); } else { warning!(log, "Tunnel exited unexpectedly but gracefully, reconnecting"); backoff.delay().await; } }, Err(e) = &mut token_ka => { error!(log, "access token is no longer valid, exiting: {}", e); return; }, _ = close_rx.recv() => { trace!(log, "Tunnel closing gracefully"); trace!(log, "Tunnel closed with result: {:?}", handle.close().await); break; } } } } } struct Backoff { failures: u32, base_duration: Duration, max_duration: Duration, } impl Backoff { pub fn new(base_duration: Duration, max_duration: Duration) -> Self { Self { failures: 0, base_duration, max_duration, } } pub async fn delay(&mut self) { tokio::time::sleep(self.next()).await } pub fn next(&mut self) -> Duration { self.failures += 1; let duration = self .base_duration .checked_mul(self.failures) .unwrap_or(self.max_duration); std::cmp::min(duration, self.max_duration) } pub fn reset(&mut self) { self.failures = 0; } } /// Cleans up the hostname so it can be used as a tunnel name. /// See TUNNEL_NAME_PATTERN in the tunnels SDK for the rules we try to use. fn clean_hostname_for_tunnel(hostname: &str) -> String { let mut out = String::new(); for char in hostname.chars().take(60) { match char { '-' | '_' | ' ' => { out.push('-'); } '0'..='9' | 'a'..='z' | 'A'..='Z' => { out.push(char); } _ => {} } } let trimmed = out.trim_matches('-'); if trimmed.len() < 2 { "remote-machine".to_string() // placeholder if the result was empty } else { trimmed.to_owned() } } fn vec_eq_as_set(a: &[String], b: &[String]) -> bool { if a.len() != b.len() { return false; } for item in a { if !b.contains(item) { return false; } } true } fn privacy_to_tunnel_acl(privacy: PortPrivacy) -> TunnelAccessControl { TunnelAccessControl { entries: vec![match privacy { PortPrivacy::Public => tunnels::contracts::TunnelAccessControlEntry { kind: tunnels::contracts::TunnelAccessControlEntryType::Anonymous, provider: None, is_inherited: false, is_deny: false, is_inverse: false, organization: None, expiration: None, subjects: vec![], scopes: vec![TUNNEL_ACCESS_SCOPES_CONNECT.to_string()], }, // Ensure private ports are actually private and do not inherit any // default visibility that may be set on the tunnel: PortPrivacy::Private => tunnels::contracts::TunnelAccessControlEntry { kind: tunnels::contracts::TunnelAccessControlEntryType::Anonymous, provider: None, is_inherited: false, is_deny: true, is_inverse: false, organization: None, expiration: None, subjects: vec![], scopes: vec![TUNNEL_ACCESS_SCOPES_CONNECT.to_string()], }, }], } } fn tunnel_has_host_connection(tunnel: &Tunnel) -> bool { tunnel .status .as_ref() .and_then(|s| s.host_connection_count.as_ref().map(|c| c.get_count() > 0)) .unwrap_or_default() } #[cfg(test)] mod test { use super::*; #[test] fn test_clean_hostname_for_tunnel() { assert_eq!( clean_hostname_for_tunnel("hello123"), "hello123".to_string() ); assert_eq!( clean_hostname_for_tunnel("-cool-name-"), "cool-name".to_string() ); assert_eq!( clean_hostname_for_tunnel("cool!name with_chars"), "coolname-with-chars".to_string() ); assert_eq!(clean_hostname_for_tunnel("z"), "remote-machine".to_string()); } } ================================================ FILE: cli/src/tunnels/legal.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::constants::IS_INTERACTIVE_CLI; use crate::state::{LauncherPaths, PersistedState}; use crate::util::errors::{AnyError, CodeError}; use crate::util::input::prompt_yn; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; lazy_static! { static ref LICENSE_TEXT: Option> = option_env!("VSCODE_CLI_SERVER_LICENSE").and_then(|s| serde_json::from_str(s).unwrap()); } const LICENSE_PROMPT: Option<&'static str> = option_env!("VSCODE_CLI_REMOTE_LICENSE_PROMPT"); #[derive(Clone, Default, Serialize, Deserialize)] struct PersistedConsent { pub consented: Option, } pub fn require_consent( paths: &LauncherPaths, accept_server_license_terms: bool, ) -> Result<(), AnyError> { match &*LICENSE_TEXT { Some(t) => println!("{}", t.join("\r\n")), None => return Ok(()), } let prompt = match LICENSE_PROMPT { Some(p) => p, None => return Ok(()), }; let license: PersistedState = PersistedState::new(paths.root().join("license_consent.json")); let mut load = license.load(); if let Some(true) = load.consented { return Ok(()); } if accept_server_license_terms { load.consented = Some(true); } else if !*IS_INTERACTIVE_CLI { return Err(CodeError::NeedsInteractiveLegalConsent.into()); } else { match prompt_yn(prompt) { Ok(true) => { load.consented = Some(true); } Ok(false) => return Err(CodeError::DeniedLegalConset.into()), Err(_) => return Err(CodeError::NeedsInteractiveLegalConsent.into()), } } license.save(load)?; Ok(()) } ================================================ FILE: cli/src/tunnels/local_forwarding.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ collections::HashMap, ops::{Index, IndexMut}, sync::{Arc, Mutex}, }; use tokio::{ pin, sync::{mpsc, watch}, }; use crate::{ async_pipe::{socket_stream_split, AsyncPipe}, json_rpc::{new_json_rpc, start_json_rpc}, log, singleton::SingletonServer, util::{errors::CodeError, sync::Barrier}, }; use super::{ dev_tunnels::ActiveTunnel, protocol::{ self, forward_singleton::{PortList, SetPortsResponse}, PortPrivacy, PortProtocol, }, shutdown_signal::ShutdownSignal, }; #[derive(Default, Clone)] struct PortCount { public: u32, private: u32, } impl Index for PortCount { type Output = u32; fn index(&self, privacy: PortPrivacy) -> &Self::Output { match privacy { PortPrivacy::Public => &self.public, PortPrivacy::Private => &self.private, } } } impl IndexMut for PortCount { fn index_mut(&mut self, privacy: PortPrivacy) -> &mut Self::Output { match privacy { PortPrivacy::Public => &mut self.public, PortPrivacy::Private => &mut self.private, } } } impl PortCount { fn is_empty(&self) -> bool { self.public == 0 && self.private == 0 } fn primary_privacy(&self) -> PortPrivacy { if self.public > 0 { PortPrivacy::Public } else { PortPrivacy::Private } } } #[derive(Clone)] struct PortMapRec { count: PortCount, protocol: PortProtocol, } type PortMap = HashMap; /// The PortForwardingHandle is given out to multiple consumers to allow /// them to set_ports that they want to be forwarded. struct PortForwardingSender { /// Todo: when `SyncUnsafeCell` is no longer nightly, we can use it here with /// the following comment: /// /// SyncUnsafeCell is used and safe here because PortForwardingSender is used /// exclusively in synchronous dispatch *and* we create a new sender in the /// context for each connection, in `serve_singleton_rpc`. /// /// If PortForwardingSender is ever used in a different context, this should /// be refactored, e.g. to use locks or `&mut self` in set_ports` /// /// see https://doc.rust-lang.org/stable/std/cell/struct.SyncUnsafeCell.html current: Mutex, sender: Arc>>, } impl PortForwardingSender { pub fn set_ports(&self, ports: PortList) { let mut current = self.current.lock().unwrap(); self.sender.lock().unwrap().send_modify(|v| { for p in current.iter() { if !ports.contains(p) { let n = v.get_mut(&p.number).expect("expected port in map"); n.count[p.privacy] -= 1; if n.count.is_empty() { v.remove(&p.number); } } } for p in ports.iter() { if !current.contains(p) { match v.get_mut(&p.number) { Some(n) => { n.count[p.privacy] += 1; n.protocol = p.protocol; } None => { let mut count = PortCount::default(); count[p.privacy] += 1; v.insert( p.number, PortMapRec { count, protocol: p.protocol, }, ); } }; } } current.splice(.., ports); }); } } impl Clone for PortForwardingSender { fn clone(&self) -> Self { Self { current: Mutex::new(vec![]), sender: self.sender.clone(), } } } impl Drop for PortForwardingSender { fn drop(&mut self) { self.set_ports(vec![]); } } struct PortForwardingReceiver { receiver: watch::Receiver, } impl PortForwardingReceiver { pub fn new() -> (PortForwardingSender, Self) { let (sender, receiver) = watch::channel(HashMap::new()); let handle = PortForwardingSender { current: Mutex::new(vec![]), sender: Arc::new(Mutex::new(sender)), }; let tracker = Self { receiver }; (handle, tracker) } /// Applies all changes from PortForwardingHandles to the tunnel. pub async fn apply_to(&mut self, log: log::Logger, tunnel: Arc) { let mut current: PortMap = HashMap::new(); while self.receiver.changed().await.is_ok() { let next = self.receiver.borrow().clone(); for (port, rec) in current.iter() { let privacy = rec.count.primary_privacy(); if !matches!(next.get(port), Some(n) if n.count.primary_privacy() == privacy) { match tunnel.remove_port(*port).await { Ok(_) => info!( log, "stopped forwarding {} port {} at {:?}", rec.protocol, *port, privacy ), Err(e) => error!( log, "failed to stop forwarding {} port {}: {}", rec.protocol, port, e ), } } } for (port, rec) in next.iter() { let privacy = rec.count.primary_privacy(); if !matches!(current.get(port), Some(n) if n.count.primary_privacy() == privacy) { match tunnel.add_port_tcp(*port, privacy, rec.protocol).await { Ok(_) => info!( log, "forwarding {} port {} at {:?}", rec.protocol, port, privacy ), Err(e) => error!( log, "failed to forward {} port {}: {}", rec.protocol, port, e ), } } } current = next; } } } pub struct SingletonClientArgs { pub log: log::Logger, pub stream: AsyncPipe, pub shutdown: Barrier, pub port_requests: watch::Receiver, } #[derive(Clone)] struct SingletonServerContext { log: log::Logger, handle: PortForwardingSender, tunnel: Arc, } /// Serves a client singleton for port forwarding. pub async fn client(args: SingletonClientArgs) -> Result<(), std::io::Error> { let mut rpc = new_json_rpc(); let (msg_tx, msg_rx) = mpsc::unbounded_channel(); let SingletonClientArgs { log, shutdown, stream, mut port_requests, } = args; debug!( log, "An existing port forwarding process is running on this machine, connecting to it..." ); let caller = rpc.get_caller(msg_tx); let rpc = rpc.methods(()).build(log.clone()); let (read, write) = socket_stream_split(stream); let serve = start_json_rpc(rpc, read, write, msg_rx, shutdown); let forward = async move { while port_requests.changed().await.is_ok() { let ports = port_requests.borrow().clone(); let r = caller .call::<_, _, protocol::forward_singleton::SetPortsResponse>( protocol::forward_singleton::METHOD_SET_PORTS, protocol::forward_singleton::SetPortsParams { ports }, ) .await .unwrap(); match r { Err(e) => error!(log, "failed to set ports: {:?}", e), Ok(r) => print_forwarding_addr(&r), }; } }; tokio::select! { r = serve => r.map(|_| ()), _ = forward => Ok(()), } } /// Serves a port-forwarding singleton. pub async fn server( log: log::Logger, tunnel: ActiveTunnel, server: SingletonServer, mut port_requests: watch::Receiver, shutdown_rx: Barrier, ) -> Result<(), CodeError> { let tunnel = Arc::new(tunnel); let (forward_tx, mut forward_rx) = PortForwardingReceiver::new(); let forward_own_tunnel = tunnel.clone(); let forward_own_tx = forward_tx.clone(); let forward_own = async move { while port_requests.changed().await.is_ok() { forward_own_tx.set_ports(port_requests.borrow().clone()); print_forwarding_addr(&SetPortsResponse { port_format: forward_own_tunnel.get_port_format().ok(), }); } }; tokio::select! { _ = forward_own => Ok(()), _ = forward_rx.apply_to(log.clone(), tunnel.clone()) => Ok(()), r = serve_singleton_rpc(server, log, tunnel, forward_tx, shutdown_rx) => r, } } async fn serve_singleton_rpc( mut server: SingletonServer, log: log::Logger, tunnel: Arc, forward_tx: PortForwardingSender, shutdown_rx: Barrier, ) -> Result<(), CodeError> { let mut own_shutdown = shutdown_rx.clone(); let shutdown_fut = own_shutdown.wait(); pin!(shutdown_fut); loop { let cnx = tokio::select! { c = server.accept() => c?, _ = &mut shutdown_fut => return Ok(()), }; let (read, write) = socket_stream_split(cnx); let shutdown_rx = shutdown_rx.clone(); let handle = forward_tx.clone(); let log = log.clone(); let tunnel = tunnel.clone(); tokio::spawn(async move { // we make an rpc for the connection instead of re-using a dispatcher // so that we can have the "handle" drop when the connection drops. let rpc = new_json_rpc(); let mut rpc = rpc.methods(SingletonServerContext { log: log.clone(), handle, tunnel, }); rpc.register_sync( protocol::forward_singleton::METHOD_SET_PORTS, |p: protocol::forward_singleton::SetPortsParams, ctx| { info!(ctx.log, "client setting ports to {:?}", p.ports); ctx.handle.set_ports(p.ports); Ok(SetPortsResponse { port_format: ctx.tunnel.get_port_format().ok(), }) }, ); let _ = start_json_rpc(rpc.build(log), read, write, (), shutdown_rx).await; }); } } fn print_forwarding_addr(r: &SetPortsResponse) { eprintln!("{}\n", serde_json::to_string(r).unwrap()); } ================================================ FILE: cli/src/tunnels/nosleep.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ #[cfg(target_os = "windows")] pub type SleepInhibitor = super::nosleep_windows::SleepInhibitor; #[cfg(target_os = "linux")] pub type SleepInhibitor = super::nosleep_linux::SleepInhibitor; #[cfg(target_os = "macos")] pub type SleepInhibitor = super::nosleep_macos::SleepInhibitor; ================================================ FILE: cli/src/tunnels/nosleep_linux.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use zbus::{dbus_proxy, Connection}; use crate::{ constants::APPLICATION_NAME, util::errors::{wrap, AnyError}, }; /// An basically undocumented API, but seems widely implemented, and is what /// browsers use for sleep inhibition. The downside is that it also *may* /// disable the screensaver. A much better and more granular API is available /// on `org.freedesktop.login1.Manager`, but this requires administrative /// permission to request inhibition, which is not possible here. /// /// See https://source.chromium.org/chromium/chromium/src/+/main:services/device/wake_lock/power_save_blocker/power_save_blocker_linux.cc;l=54;drc=2e85357a8b76996981cc6f783853a49df2cedc3a #[dbus_proxy( interface = "org.freedesktop.PowerManagement.Inhibit", gen_blocking = false, default_service = "org.freedesktop.PowerManagement.Inhibit", default_path = "/org/freedesktop/PowerManagement/Inhibit" )] trait PMInhibitor { #[dbus_proxy(name = "Inhibit")] fn inhibit(&self, what: &str, why: &str) -> zbus::Result; } /// A slightly better documented version which seems commonly used. #[dbus_proxy( interface = "org.freedesktop.ScreenSaver", gen_blocking = false, default_service = "org.freedesktop.ScreenSaver", default_path = "/org/freedesktop/ScreenSaver" )] trait ScreenSaver { #[dbus_proxy(name = "Inhibit")] fn inhibit(&self, what: &str, why: &str) -> zbus::Result; } pub struct SleepInhibitor { _connection: Connection, // Inhibition is released when the connection is closed } impl SleepInhibitor { pub async fn new() -> Result { let connection = Connection::session() .await .map_err(|e| wrap(e, "error creating dbus session"))?; macro_rules! try_inhibit { ($proxy:ident) => { match $proxy::new(&connection).await { Ok(proxy) => proxy.inhibit(APPLICATION_NAME, "running tunnel").await, Err(e) => Err(e), } }; } if let Err(e1) = try_inhibit!(PMInhibitorProxy) { if let Err(e2) = try_inhibit!(ScreenSaverProxy) { return Err(wrap( e2, format!( "error requesting sleep inhibition, pminhibitor gave {e1}, screensaver gave" ), ) .into()); } } Ok(SleepInhibitor { _connection: connection, }) } } ================================================ FILE: cli/src/tunnels/nosleep_macos.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::io; use core_foundation::base::TCFType; use core_foundation::string::{CFString, CFStringRef}; use libc::c_int; use crate::constants::TUNNEL_ACTIVITY_NAME; extern "C" { pub fn IOPMAssertionCreateWithName( assertion_type: CFStringRef, assertion_level: u32, assertion_name: CFStringRef, assertion_id: &mut u32, ) -> c_int; pub fn IOPMAssertionRelease(assertion_id: u32) -> c_int; } const NUM_ASSERTIONS: usize = 2; const ASSERTIONS: [&str; NUM_ASSERTIONS] = ["PreventUserIdleSystemSleep", "PreventSystemSleep"]; struct Assertion(u32); impl Assertion { pub fn make(typ: &CFString, name: &CFString) -> io::Result { let mut assertion_id = 0; let result = unsafe { IOPMAssertionCreateWithName( typ.as_concrete_TypeRef(), 255, name.as_concrete_TypeRef(), &mut assertion_id, ) }; if result != 0 { Err(io::Error::last_os_error()) } else { Ok(Self(assertion_id)) } } } impl Drop for Assertion { fn drop(&mut self) { unsafe { IOPMAssertionRelease(self.0); } } } pub struct SleepInhibitor { _assertions: Vec, } impl SleepInhibitor { pub async fn new() -> io::Result { let mut assertions = Vec::with_capacity(NUM_ASSERTIONS); let assertion_name = CFString::from_static_string(TUNNEL_ACTIVITY_NAME); for typ in ASSERTIONS { assertions.push(Assertion::make( &CFString::from_static_string(typ), &assertion_name, )?); } Ok(Self { _assertions: assertions, }) } } ================================================ FILE: cli/src/tunnels/nosleep_windows.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::io; use winapi::{ ctypes::c_void, um::{ handleapi::CloseHandle, minwinbase::REASON_CONTEXT, winbase::{PowerClearRequest, PowerCreateRequest, PowerSetRequest}, winnt::{ PowerRequestSystemRequired, POWER_REQUEST_CONTEXT_SIMPLE_STRING, POWER_REQUEST_CONTEXT_VERSION, POWER_REQUEST_TYPE, }, }, }; use crate::constants::TUNNEL_ACTIVITY_NAME; struct Request(*mut c_void); impl Request { pub fn new() -> io::Result { let mut reason: Vec = TUNNEL_ACTIVITY_NAME.encode_utf16().chain([0u16]).collect(); let mut context = REASON_CONTEXT { Version: POWER_REQUEST_CONTEXT_VERSION, Flags: POWER_REQUEST_CONTEXT_SIMPLE_STRING, Reason: unsafe { std::mem::zeroed() }, }; unsafe { *context.Reason.SimpleReasonString_mut() = reason.as_mut_ptr() }; let request = unsafe { PowerCreateRequest(&mut context) }; if request.is_null() { return Err(io::Error::last_os_error()); } Ok(Self(request)) } pub fn set(&self, request_type: POWER_REQUEST_TYPE) -> io::Result<()> { let result = unsafe { PowerSetRequest(self.0, request_type) }; if result == 0 { return Err(io::Error::last_os_error()); } Ok(()) } } impl Drop for Request { fn drop(&mut self) { unsafe { CloseHandle(self.0); } } } pub struct SleepInhibitor { request: Request, } impl SleepInhibitor { pub async fn new() -> io::Result { let request = Request::new()?; request.set(PowerRequestSystemRequired)?; Ok(Self { request }) } } impl Drop for SleepInhibitor { fn drop(&mut self) { unsafe { PowerClearRequest(self.request.0, PowerRequestSystemRequired); } } } ================================================ FILE: cli/src/tunnels/paths.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ fs::{read_dir, read_to_string, remove_dir_all, write}, path::PathBuf, }; use serde::{Deserialize, Serialize}; use crate::{ options::{self, Quality}, state::LauncherPaths, util::{ errors::{wrap, AnyError, WrappedError}, machine, }, }; pub const SERVER_FOLDER_NAME: &str = "server"; pub struct ServerPaths { // Directory into which the server is downloaded pub server_dir: PathBuf, // Executable path, within the server_id pub executable: PathBuf, // File where logs for the server should be written. pub logfile: PathBuf, // File where the process ID for the server should be written. pub pidfile: PathBuf, } impl ServerPaths { // Queries the system to determine the process ID of the running server. // Returns the process ID, if the server is running. pub fn get_running_pid(&self) -> Option { if let Some(pid) = self.read_pid() { return match machine::process_at_path_exists(pid, &self.executable) { true => Some(pid), false => None, }; } if let Some(pid) = machine::find_running_process(&self.executable) { // attempt to backfill process ID: self.write_pid(pid).ok(); return Some(pid); } None } /// Delete the server directory pub fn delete(&self) -> Result<(), WrappedError> { remove_dir_all(&self.server_dir).map_err(|e| { wrap( e, format!("error deleting server dir {}", self.server_dir.display()), ) }) } // VS Code Server pid pub fn write_pid(&self, pid: u32) -> Result<(), WrappedError> { write(&self.pidfile, format!("{pid}")).map_err(|e| { wrap( e, format!("error writing process id into {}", self.pidfile.display()), ) }) } fn read_pid(&self) -> Option { read_to_string(&self.pidfile) .ok() .and_then(|s| s.parse::().ok()) } } #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] pub struct InstalledServer { pub quality: options::Quality, pub commit: String, pub headless: bool, } impl InstalledServer { /// Gets path information about where a specific server should be stored. pub fn server_paths(&self, p: &LauncherPaths) -> ServerPaths { let server_dir = self.get_install_folder(p); ServerPaths { // allow using the OSS server in development via an override executable: if let Some(p) = option_env!("VSCODE_CLI_OVERRIDE_SERVER_PATH") { PathBuf::from(p) } else { server_dir .join(SERVER_FOLDER_NAME) .join("bin") .join(self.quality.server_entrypoint()) }, logfile: server_dir.join("log.txt"), pidfile: server_dir.join("pid.txt"), server_dir, } } fn get_install_folder(&self, p: &LauncherPaths) -> PathBuf { p.server_cache.path().join(if !self.headless { format!("{}-web", get_server_folder_name(self.quality, &self.commit)) } else { get_server_folder_name(self.quality, &self.commit) }) } } /// Prunes servers not currently running, and returns the deleted servers. pub fn prune_stopped_servers(launcher_paths: &LauncherPaths) -> Result, AnyError> { get_all_servers(launcher_paths) .into_iter() .map(|s| s.server_paths(launcher_paths)) .filter(|s| s.get_running_pid().is_none()) .map(|s| s.delete().map(|_| s)) .collect::>() .map_err(AnyError::from) } // Gets a list of all servers which look like they might be running. pub fn get_all_servers(lp: &LauncherPaths) -> Vec { let mut servers: Vec = vec![]; if let Ok(children) = read_dir(lp.server_cache.path()) { for child in children.flatten() { let fname = child.file_name(); let fname = fname.to_string_lossy(); let (quality, commit) = match fname.split_once('-') { Some(r) => r, None => continue, }; let quality = match options::Quality::try_from(quality) { Ok(q) => q, Err(_) => continue, }; servers.push(InstalledServer { quality, commit: commit.to_string(), headless: true, }); } } servers } pub fn get_server_folder_name(quality: Quality, commit: &str) -> String { format!("{quality}-{commit}") } ================================================ FILE: cli/src/tunnels/port_forwarder.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::collections::HashSet; use tokio::sync::{mpsc, oneshot}; use crate::{ constants::CONTROL_PORT, util::errors::{AnyError, CannotForwardControlPort, ServerHasClosed}, }; use super::{ dev_tunnels::ActiveTunnel, protocol::{PortPrivacy, PortProtocol}, }; pub enum PortForwardingRec { Forward(u16, PortPrivacy, oneshot::Sender>), Unforward(u16, oneshot::Sender>), } /// Provides a port forwarding service for connected clients. Clients can make /// requests on it, which are (and *must be*) processed by calling the `.process()` /// method on the forwarder. pub struct PortForwardingProcessor { tx: mpsc::Sender, rx: mpsc::Receiver, forwarded: HashSet, } impl PortForwardingProcessor { pub fn new() -> Self { let (tx, rx) = mpsc::channel(8); Self { tx, rx, forwarded: HashSet::new(), } } /// Gets a handle that can be passed off to consumers of port forwarding. pub fn handle(&self) -> PortForwarding { PortForwarding { tx: self.tx.clone(), } } /// Receives port forwarding requests. Consumers MUST call `process()` /// with the received requests. pub async fn recv(&mut self) -> Option { self.rx.recv().await } /// Processes the incoming forwarding request. pub async fn process(&mut self, req: PortForwardingRec, tunnel: &mut ActiveTunnel) { match req { PortForwardingRec::Forward(port, privacy, tx) => { tx.send(self.process_forward(port, privacy, tunnel).await) .ok(); } PortForwardingRec::Unforward(port, tx) => { tx.send(self.process_unforward(port, tunnel).await).ok(); } } } async fn process_unforward( &mut self, port: u16, tunnel: &mut ActiveTunnel, ) -> Result<(), AnyError> { if port == CONTROL_PORT { return Err(CannotForwardControlPort().into()); } tunnel.remove_port(port).await?; self.forwarded.remove(&port); Ok(()) } async fn process_forward( &mut self, port: u16, privacy: PortPrivacy, tunnel: &mut ActiveTunnel, ) -> Result { if port == CONTROL_PORT { return Err(CannotForwardControlPort().into()); } if !self.forwarded.contains(&port) { tunnel .add_port_tcp(port, privacy, PortProtocol::Auto) .await?; self.forwarded.insert(port); } tunnel.get_port_uri(port) } } #[derive(Clone)] pub struct PortForwarding { tx: mpsc::Sender, } impl PortForwarding { pub async fn forward(&self, port: u16, privacy: PortPrivacy) -> Result { let (tx, rx) = oneshot::channel(); let req = PortForwardingRec::Forward(port, privacy, tx); if self.tx.send(req).await.is_err() { return Err(ServerHasClosed().into()); } match rx.await { Ok(r) => r, Err(_) => Err(ServerHasClosed().into()), } } pub async fn unforward(&self, port: u16) -> Result<(), AnyError> { let (tx, rx) = oneshot::channel(); let req = PortForwardingRec::Unforward(port, tx); if self.tx.send(req).await.is_err() { return Err(ServerHasClosed().into()); } match rx.await { Ok(r) => r, Err(_) => Err(ServerHasClosed().into()), } } } ================================================ FILE: cli/src/tunnels/protocol.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::collections::HashMap; use crate::{ constants::{PROTOCOL_VERSION, VSCODE_CLI_VERSION}, options::Quality, update_service::Platform, }; use serde::{Deserialize, Serialize}; #[derive(Serialize, Debug)] #[serde(tag = "method", content = "params", rename_all = "camelCase")] #[allow(non_camel_case_types)] pub enum ClientRequestMethod<'a> { servermsg(RefServerMessageParams<'a>), serverclose(ServerClosedParams), serverlog(ServerLog<'a>), makehttpreq(HttpRequestParams<'a>), version(VersionResponse), } #[derive(Deserialize, Debug)] pub struct HttpBodyParams { #[serde(with = "serde_bytes")] pub segment: Vec, pub complete: bool, pub req_id: u32, } #[derive(Serialize, Debug)] pub struct HttpRequestParams<'a> { pub url: &'a str, pub method: &'static str, pub req_id: u32, } #[derive(Deserialize, Debug)] pub struct HttpHeadersParams { pub status_code: u16, pub headers: Vec<(String, String)>, pub req_id: u32, } #[derive(Deserialize, Debug)] pub struct ForwardParams { pub port: u16, #[serde(default)] pub public: bool, } #[derive(Deserialize, Debug)] pub struct UnforwardParams { pub port: u16, } #[derive(Serialize)] pub struct ForwardResult { pub uri: String, } #[derive(Deserialize, Debug)] pub struct ServeParams { pub socket_id: u16, pub commit_id: Option, pub quality: Quality, pub extensions: Vec, /// Optional preferred connection token. #[serde(default)] pub connection_token: Option, #[serde(default)] pub use_local_download: bool, /// If true, the client and server should gzip servermsg's sent in either direction. #[serde(default)] pub compress: bool, } #[derive(Deserialize, Serialize, Debug)] pub struct EmptyObject {} #[derive(Serialize, Deserialize, Debug)] pub struct UpdateParams { pub do_update: bool, } #[derive(Deserialize, Debug)] pub struct ServerMessageParams { pub i: u16, #[serde(with = "serde_bytes")] pub body: Vec, } #[derive(Serialize, Debug)] pub struct ServerClosedParams { pub i: u16, } #[derive(Serialize, Debug)] pub struct RefServerMessageParams<'a> { pub i: u16, #[serde(with = "serde_bytes")] pub body: &'a [u8], } #[derive(Serialize)] pub struct UpdateResult { pub up_to_date: bool, pub did_update: bool, } #[derive(Serialize, Debug)] pub struct ToClientRequest<'a> { pub id: Option, #[serde(flatten)] pub params: ClientRequestMethod<'a>, } #[derive(Debug, Default, Serialize)] pub struct ServerLog<'a> { pub line: &'a str, pub level: u8, } #[derive(Serialize)] pub struct GetHostnameResponse { pub value: String, } #[derive(Serialize)] pub struct GetEnvResponse { pub env: HashMap, pub os_platform: &'static str, pub os_release: String, } /// Method: `kill`. Sends a generic, platform-specific kill command to the process. #[derive(Deserialize)] pub struct SysKillRequest { pub pid: u32, } #[derive(Serialize)] pub struct SysKillResponse { pub success: bool, } /// Methods: `fs_read`/`fs_write`/`fs_rm`/`fs_mkdirp`/`fs_stat` /// - fs_read: reads into a stream returned from the method, /// - fs_write: writes from a stream passed to the method. /// - fs_rm: recursively removes the file /// - fs_mkdirp: recursively creates the directory /// - fs_readdir: reads directory contents /// - fs_stat: stats the given path /// - fs_connect: connect to the given unix or named pipe socket, streaming /// data in and out from the method's stream. #[derive(Deserialize)] pub struct FsSinglePathRequest { pub path: String, } #[derive(Serialize)] pub enum FsFileKind { #[serde(rename = "dir")] Directory, #[serde(rename = "file")] File, #[serde(rename = "link")] Link, } impl From for FsFileKind { fn from(kind: std::fs::FileType) -> Self { if kind.is_dir() { Self::Directory } else if kind.is_file() { Self::File } else if kind.is_symlink() { Self::Link } else { unreachable!() } } } #[derive(Serialize, Default)] pub struct FsStatResponse { pub exists: bool, pub size: Option, #[serde(rename = "type")] pub kind: Option, } #[derive(Serialize)] pub struct FsReadDirResponse { pub contents: Vec, } #[derive(Serialize)] pub struct FsReadDirEntry { pub name: String, #[serde(rename = "type")] pub kind: Option, } /// Method: `fs_reaname`. Renames a file. #[derive(Deserialize)] pub struct FsRenameRequest { pub from_path: String, pub to_path: String, } /// Method: `net_connect`. Connects to a port. #[derive(Deserialize)] pub struct NetConnectRequest { pub port: u16, pub host: String, } #[derive(Deserialize, Debug)] pub struct CallServerHttpParams { pub path: String, pub method: String, pub headers: HashMap, pub body: Option>, } #[derive(Serialize)] pub struct CallServerHttpResult { pub status: u16, #[serde(with = "serde_bytes")] pub body: Vec, pub headers: HashMap, } #[derive(Serialize, Debug)] pub struct VersionResponse { pub version: &'static str, pub protocol_version: u32, } impl Default for VersionResponse { fn default() -> Self { Self { version: VSCODE_CLI_VERSION.unwrap_or("dev"), protocol_version: PROTOCOL_VERSION, } } } #[derive(Deserialize)] pub struct SpawnParams { pub command: String, pub args: Vec, #[serde(default)] pub cwd: Option, #[serde(default)] pub env: HashMap, } #[derive(Deserialize)] pub struct AcquireCliParams { pub platform: Platform, pub quality: Quality, pub commit_id: Option, #[serde(flatten)] pub spawn: SpawnParams, } #[derive(Serialize)] pub struct SpawnResult { pub message: String, pub exit_code: i32, } pub const METHOD_CHALLENGE_ISSUE: &str = "challenge_issue"; pub const METHOD_CHALLENGE_VERIFY: &str = "challenge_verify"; #[derive(Serialize, Deserialize)] pub struct ChallengeIssueParams { pub token: Option, } #[derive(Serialize, Deserialize)] pub struct ChallengeIssueResponse { pub challenge: String, } #[derive(Deserialize, Serialize)] pub struct ChallengeVerifyParams { pub response: String, } #[derive(Serialize, Deserialize, PartialEq, Eq, Copy, Clone, Debug)] #[serde(rename_all = "lowercase")] pub enum PortPrivacy { Public, Private, } #[derive(Serialize, Deserialize, PartialEq, Copy, Eq, Clone, Debug)] #[serde(rename_all = "lowercase")] pub enum PortProtocol { Auto, Http, Https, } impl std::fmt::Display for PortProtocol { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_contract_str()) } } impl Default for PortProtocol { fn default() -> Self { Self::Auto } } impl PortProtocol { pub fn to_contract_str(&self) -> &'static str { match *self { Self::Auto => tunnels::contracts::TUNNEL_PROTOCOL_AUTO, Self::Http => tunnels::contracts::TUNNEL_PROTOCOL_HTTP, Self::Https => tunnels::contracts::TUNNEL_PROTOCOL_HTTPS, } } } pub mod forward_singleton { use serde::{Deserialize, Serialize}; use super::{PortPrivacy, PortProtocol}; pub const METHOD_SET_PORTS: &str = "set_ports"; #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] pub struct PortRec { pub number: u16, pub privacy: PortPrivacy, pub protocol: PortProtocol, } pub type PortList = Vec; #[derive(Serialize, Deserialize)] pub struct SetPortsParams { pub ports: PortList, } #[derive(Serialize, Deserialize)] pub struct SetPortsResponse { pub port_format: Option, } } pub mod singleton { use crate::log; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; pub const METHOD_RESTART: &str = "restart"; pub const METHOD_SHUTDOWN: &str = "shutdown"; pub const METHOD_STATUS: &str = "status"; pub const METHOD_LOG: &str = "log"; pub const METHOD_LOG_REPLY_DONE: &str = "log_done"; #[derive(Serialize)] pub struct LogMessage<'a> { pub level: Option, pub prefix: &'a str, pub message: &'a str, } #[derive(Deserialize)] pub struct LogMessageOwned { pub level: Option, pub prefix: String, pub message: String, } #[derive(Serialize, Deserialize, Clone, Default)] pub struct StatusWithTunnelName { pub name: Option, #[serde(flatten)] pub status: Status, } #[derive(Serialize, Deserialize, Clone)] pub struct Status { pub started_at: DateTime, pub tunnel: TunnelState, pub last_connected_at: Option>, pub last_disconnected_at: Option>, pub last_fail_reason: Option, } impl Default for Status { fn default() -> Self { Self { started_at: Utc::now(), tunnel: TunnelState::Disconnected, last_connected_at: None, last_disconnected_at: None, last_fail_reason: None, } } } #[derive(Deserialize, Serialize, Debug)] pub struct LogReplayFinished {} #[derive(Deserialize, Serialize, Debug, Default, Clone)] pub enum TunnelState { #[default] Disconnected, Connected, } } ================================================ FILE: cli/src/tunnels/server_bridge.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::socket_signal::{ClientMessageDecoder, ServerMessageSink}; use crate::{ async_pipe::{get_socket_rw_stream, socket_stream_split, AsyncPipeWriteHalf}, util::errors::AnyError, }; use std::path::Path; use tokio::io::{AsyncReadExt, AsyncWriteExt}; pub struct ServerBridge { write: AsyncPipeWriteHalf, decoder: ClientMessageDecoder, } const BUFFER_SIZE: usize = 65536; impl ServerBridge { pub async fn new( path: &Path, mut target: ServerMessageSink, decoder: ClientMessageDecoder, ) -> Result { let stream = get_socket_rw_stream(path).await?; let (mut read, write) = socket_stream_split(stream); tokio::spawn(async move { let mut read_buf = vec![0; BUFFER_SIZE]; loop { match read.read(&mut read_buf).await { Err(_) => return, Ok(0) => { let _ = target.server_closed().await; return; // EOF } Ok(s) => { let send = target.server_message(&read_buf[..s]).await; if send.is_err() { return; } } } } }); Ok(ServerBridge { write, decoder }) } pub async fn write(&mut self, b: Vec) -> std::io::Result<()> { let dec = self.decoder.decode(&b)?; if !dec.is_empty() { self.write.write_all(dec).await?; } Ok(()) } pub async fn close(mut self) -> std::io::Result<()> { self.write.shutdown().await?; Ok(()) } } ================================================ FILE: cli/src/tunnels/server_multiplexer.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::sync::Arc; use futures::future::join_all; use crate::log; use super::server_bridge::ServerBridge; type Inner = Arc>>>; struct ServerBridgeRec { id: u16, // bridge is removed when there's a write loop currently active bridge: Option, write_queue: Vec>, } /// The ServerMultiplexer manages multiple server bridges and allows writing /// to them in a thread-safe way. It is copy, sync, and clone. #[derive(Clone)] pub struct ServerMultiplexer { inner: Inner, } impl ServerMultiplexer { pub fn new() -> Self { Self { inner: Arc::new(std::sync::Mutex::new(Some(Vec::new()))), } } /// Adds a new bridge to the multiplexer. pub fn register(&self, id: u16, bridge: ServerBridge) { let bridge_rec = ServerBridgeRec { id, bridge: Some(bridge), write_queue: vec![], }; let mut lock = self.inner.lock().unwrap(); match &mut *lock { Some(server_bridges) => (*server_bridges).push(bridge_rec), None => *lock = Some(vec![bridge_rec]), } } /// Removes a server bridge by ID. pub fn remove(&self, id: u16) { let mut lock = self.inner.lock().unwrap(); if let Some(bridges) = &mut *lock { bridges.retain(|sb| sb.id != id); } } /// Handle an incoming server message. This is synchronous and uses a 'write loop' /// to ensure message order is preserved exactly, which is necessary for compression. /// Returns false if there was no server with the given bridge_id. pub fn write_message(&self, log: &log::Logger, bridge_id: u16, message: Vec) -> bool { let mut lock = self.inner.lock().unwrap(); let bridges = match &mut *lock { Some(sb) => sb, None => return false, }; let record = match bridges.iter_mut().find(|b| b.id == bridge_id) { Some(sb) => sb, None => return false, }; record.write_queue.push(message); if let Some(bridge) = record.bridge.take() { let bridges_lock = self.inner.clone(); let log = log.clone(); tokio::spawn(write_loop(log, record.id, bridge, bridges_lock)); } true } /// Disposes all running server bridges. pub async fn dispose(&self) { let bridges = { let mut lock = self.inner.lock().unwrap(); lock.take() }; let bridges = match bridges { Some(b) => b, None => return, }; join_all( bridges .into_iter() .filter_map(|b| b.bridge) .map(|b| b.close()), ) .await; } } /// Write loop started by `handle_server_message`. It takes the ServerBridge, and /// runs until there's no more items in the 'write queue'. At that point, if the /// record still exists in the bridges_lock (i.e. we haven't shut down), it'll /// return the ServerBridge so that the next handle_server_message call starts /// the loop again. Otherwise, it'll close the bridge. async fn write_loop(log: log::Logger, id: u16, mut bridge: ServerBridge, bridges_lock: Inner) { let mut items_vec = vec![]; loop { { let mut lock = bridges_lock.lock().unwrap(); let server_bridges = match &mut *lock { Some(sb) => sb, None => break, }; let bridge_rec = match server_bridges.iter_mut().find(|b| id == b.id) { Some(b) => b, None => break, }; if bridge_rec.write_queue.is_empty() { bridge_rec.bridge = Some(bridge); return; } std::mem::swap(&mut bridge_rec.write_queue, &mut items_vec); } for item in items_vec.drain(..) { if let Err(e) = bridge.write(item).await { warning!(log, "Error writing to server: {:?}", e); break; } } } bridge.close().await.ok(); // got here from `break` above, meaning our record got cleared. Close the bridge if so } ================================================ FILE: cli/src/tunnels/service.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::path::{Path, PathBuf}; use async_trait::async_trait; use crate::log; use crate::state::LauncherPaths; use crate::util::errors::{wrap, AnyError}; use crate::util::io::{tailf, TailEvent}; pub const SERVICE_LOG_FILE_NAME: &str = "tunnel-service.log"; #[async_trait] pub trait ServiceContainer: Send { async fn run_service( &mut self, log: log::Logger, launcher_paths: LauncherPaths, ) -> Result<(), AnyError>; } #[async_trait] pub trait ServiceManager { /// Registers the current executable as a service to run with the given set /// of arguments. async fn register(&self, exe: PathBuf, args: &[&str]) -> Result<(), AnyError>; /// Runs the service using the given handle. The executable *must not* take /// any action which may fail prior to calling this to ensure service /// states may update. async fn run( self, launcher_paths: LauncherPaths, handle: impl 'static + ServiceContainer, ) -> Result<(), AnyError>; /// Show logs from the running service to standard out. async fn show_logs(&self) -> Result<(), AnyError>; /// Gets whether the tunnel service is installed. async fn is_installed(&self) -> Result; /// Unregisters the current executable as a service. async fn unregister(&self) -> Result<(), AnyError>; } #[cfg(target_os = "windows")] pub type ServiceManagerImpl = super::service_windows::WindowsService; #[cfg(target_os = "linux")] pub type ServiceManagerImpl = super::service_linux::SystemdService; #[cfg(target_os = "macos")] pub type ServiceManagerImpl = super::service_macos::LaunchdService; #[allow(unreachable_code)] #[allow(unused_variables)] pub fn create_service_manager(log: log::Logger, paths: &LauncherPaths) -> ServiceManagerImpl { #[cfg(target_os = "macos")] { super::service_macos::LaunchdService::new(log, paths) } #[cfg(target_os = "windows")] { super::service_windows::WindowsService::new(log, paths) } #[cfg(target_os = "linux")] { super::service_linux::SystemdService::new(log, paths.clone()) } } #[allow(dead_code)] // unused on Linux pub(crate) async fn tail_log_file(log_file: &Path) -> Result<(), AnyError> { if !log_file.exists() { println!("The tunnel service has not started yet."); return Ok(()); } let file = std::fs::File::open(log_file).map_err(|e| wrap(e, "error opening log file"))?; let mut rx = tailf(file, 20); while let Some(line) = rx.recv().await { match line { TailEvent::Line(l) => print!("{l}"), TailEvent::Reset => println!("== Tunnel service restarted =="), TailEvent::Err(e) => return Err(wrap(e, "error reading log file").into()), } } Ok(()) } ================================================ FILE: cli/src/tunnels/service_linux.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ fs::File, io::{self, Write}, path::PathBuf, process::Command, }; use async_trait::async_trait; use zbus::{dbus_proxy, zvariant, Connection}; use crate::{ constants::{APPLICATION_NAME, PRODUCT_NAME_LONG}, log, state::LauncherPaths, util::errors::{wrap, AnyError, DbusConnectFailedError}, }; use super::ServiceManager; pub struct SystemdService { log: log::Logger, service_file: PathBuf, } impl SystemdService { pub fn new(log: log::Logger, paths: LauncherPaths) -> Self { Self { log, service_file: paths.root().join(SystemdService::service_name_string()), } } } impl SystemdService { async fn connect() -> Result { let connection = Connection::session() .await .map_err(|e| DbusConnectFailedError(e.to_string()))?; Ok(connection) } async fn proxy(connection: &Connection) -> Result, AnyError> { let proxy = SystemdManagerDbusProxy::new(connection) .await .map_err(|e| { wrap( e, "error connecting to systemd, you may need to re-run with sudo:", ) })?; Ok(proxy) } fn service_path_string(&self) -> String { self.service_file.as_os_str().to_string_lossy().to_string() } fn service_name_string() -> String { format!("{APPLICATION_NAME}-tunnel.service") } } #[async_trait] impl ServiceManager for SystemdService { async fn register( &self, exe: std::path::PathBuf, args: &[&str], ) -> Result<(), crate::util::errors::AnyError> { let connection = SystemdService::connect().await?; let proxy = SystemdService::proxy(&connection).await?; write_systemd_service_file(&self.service_file, exe, args) .map_err(|e| wrap(e, "error creating service file"))?; proxy .link_unit_files( vec![self.service_path_string()], /* 'runtime only'= */ false, /* replace existing = */ true, ) .await .map_err(|e| wrap(e, "error registering service"))?; info!(self.log, "Successfully registered service..."); if let Err(e) = proxy.reload().await { warning!(self.log, "Error issuing reload(): {}", e); } // note: enablement is implicit in recent systemd version, but required for older systems // https://github.com/microsoft/vscode/issues/167489#issuecomment-1331222826 proxy .enable_unit_files( vec![SystemdService::service_name_string()], /* 'runtime only'= */ false, /* replace existing = */ true, ) .await .map_err(|e| wrap(e, "error enabling unit files for service"))?; info!(self.log, "Successfully enabled unit files..."); proxy .start_unit(SystemdService::service_name_string(), "replace".to_string()) .await .map_err(|e| wrap(e, "error starting service"))?; info!(self.log, "Tunnel service successfully started"); if std::env::var("SSH_CLIENT").is_ok() || std::env::var("SSH_TTY").is_ok() { info!(self.log, "Tip: run `sudo loginctl enable-linger $USER` to ensure the service stays running after you disconnect."); } Ok(()) } async fn is_installed(&self) -> Result { let connection = SystemdService::connect().await?; let proxy = SystemdService::proxy(&connection).await?; let state = proxy .get_unit_file_state(SystemdService::service_name_string()) .await; if let Ok(s) = state { Ok(s == "enabled") } else { Ok(false) } } async fn run( self, launcher_paths: crate::state::LauncherPaths, mut handle: impl 'static + super::ServiceContainer, ) -> Result<(), crate::util::errors::AnyError> { handle.run_service(self.log, launcher_paths).await } async fn show_logs(&self) -> Result<(), AnyError> { // show the systemctl status header... Command::new("systemctl") .args([ "--user", "status", "-n", "0", &SystemdService::service_name_string(), ]) .status() .map(|s| s.code().unwrap_or(1)) .map_err(|e| wrap(e, "error running systemctl"))?; // then follow log files Command::new("journalctl") .args(["--user", "-f", "-u", &SystemdService::service_name_string()]) .status() .map(|s| s.code().unwrap_or(1)) .map_err(|e| wrap(e, "error running journalctl"))?; Ok(()) } async fn unregister(&self) -> Result<(), crate::util::errors::AnyError> { let connection = SystemdService::connect().await?; let proxy = SystemdService::proxy(&connection).await?; proxy .stop_unit(SystemdService::service_name_string(), "replace".to_string()) .await .map_err(|e| wrap(e, "error unregistering service"))?; info!(self.log, "Successfully stopped service..."); proxy .disable_unit_files( vec![SystemdService::service_name_string()], /* 'runtime only'= */ false, ) .await .map_err(|e| wrap(e, "error unregistering service"))?; info!(self.log, "Tunnel service uninstalled"); Ok(()) } } fn write_systemd_service_file( path: &PathBuf, exe: std::path::PathBuf, args: &[&str], ) -> io::Result<()> { let mut f = File::create(path)?; write!( &mut f, "[Unit]\n\ Description={} Tunnel\n\ After=network.target\n\ StartLimitIntervalSec=0\n\ \n\ [Service]\n\ Type=simple\n\ Restart=always\n\ RestartSec=10\n\ ExecStart={} \"{}\"\n\ \n\ [Install]\n\ WantedBy=default.target\n\ ", PRODUCT_NAME_LONG, exe.into_os_string().to_string_lossy(), args.join("\" \"") )?; Ok(()) } /// Minimal implementation of systemd types for the services we need. The full /// definition can be found on any systemd machine with the command: /// /// gdbus introspect --system --dest org.freedesktop.systemd1 --object-path /org/freedesktop/systemd1 /// /// See docs here: https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html #[dbus_proxy( interface = "org.freedesktop.systemd1.Manager", gen_blocking = false, default_service = "org.freedesktop.systemd1", default_path = "/org/freedesktop/systemd1" )] trait SystemdManagerDbus { #[dbus_proxy(name = "EnableUnitFiles")] fn enable_unit_files( &self, files: Vec, runtime: bool, force: bool, ) -> zbus::Result<(bool, Vec<(String, String, String)>)>; fn get_unit_file_state(&self, file: String) -> zbus::Result; fn link_unit_files( &self, files: Vec, runtime: bool, force: bool, ) -> zbus::Result>; fn disable_unit_files( &self, files: Vec, runtime: bool, ) -> zbus::Result>; #[dbus_proxy(name = "StartUnit")] fn start_unit(&self, name: String, mode: String) -> zbus::Result; #[dbus_proxy(name = "StopUnit")] fn stop_unit(&self, name: String, mode: String) -> zbus::Result; #[dbus_proxy(name = "Reload")] fn reload(&self) -> zbus::Result<()>; } ================================================ FILE: cli/src/tunnels/service_macos.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ fs::{remove_file, File}, io::{self, Write}, path::{Path, PathBuf}, }; use async_trait::async_trait; use crate::{ constants::APPLICATION_NAME, log, state::LauncherPaths, util::{ command::capture_command_and_check_status, errors::{wrap, AnyError, CodeError, MissingHomeDirectory}, }, }; use super::{service::tail_log_file, ServiceManager}; pub struct LaunchdService { log: log::Logger, log_file: PathBuf, } impl LaunchdService { pub fn new(log: log::Logger, paths: &LauncherPaths) -> Self { Self { log, log_file: paths.service_log_file(), } } } #[async_trait] impl ServiceManager for LaunchdService { async fn register( &self, exe: std::path::PathBuf, args: &[&str], ) -> Result<(), crate::util::errors::AnyError> { let service_file = get_service_file_path()?; write_service_file(&service_file, &self.log_file, exe, args) .map_err(|e| wrap(e, "error creating service file"))?; info!(self.log, "Successfully registered service..."); capture_command_and_check_status( "launchctl", &["load", service_file.as_os_str().to_string_lossy().as_ref()], ) .await?; capture_command_and_check_status("launchctl", &["start", &get_service_label()]).await?; info!(self.log, "Tunnel service successfully started"); Ok(()) } async fn show_logs(&self) -> Result<(), AnyError> { tail_log_file(&self.log_file).await } async fn run( self, launcher_paths: crate::state::LauncherPaths, mut handle: impl 'static + super::ServiceContainer, ) -> Result<(), crate::util::errors::AnyError> { handle.run_service(self.log, launcher_paths).await } async fn is_installed(&self) -> Result { let cmd = capture_command_and_check_status("launchctl", &["list"]).await?; Ok(String::from_utf8_lossy(&cmd.stdout).contains(&get_service_label())) } async fn unregister(&self) -> Result<(), crate::util::errors::AnyError> { let service_file = get_service_file_path()?; match capture_command_and_check_status("launchctl", &["stop", &get_service_label()]).await { Ok(_) => {} // status 3 == "no such process" Err(CodeError::CommandFailed { code: 3, .. }) => {} Err(e) => return Err(wrap(e, "error stopping service").into()), }; info!(self.log, "Successfully stopped service..."); capture_command_and_check_status( "launchctl", &[ "unload", service_file.as_os_str().to_string_lossy().as_ref(), ], ) .await?; info!(self.log, "Tunnel service uninstalled"); if let Ok(f) = get_service_file_path() { remove_file(f).ok(); } Ok(()) } } fn get_service_label() -> String { format!("com.visualstudio.{}.tunnel", APPLICATION_NAME) } fn get_service_file_path() -> Result { match dirs::home_dir() { Some(mut d) => { d.push(format!("{}.plist", get_service_label())); Ok(d) } None => Err(MissingHomeDirectory()), } } fn write_service_file( path: &PathBuf, log_file: &Path, exe: std::path::PathBuf, args: &[&str], ) -> io::Result<()> { let mut f = File::create(path)?; let log_file = log_file.as_os_str().to_string_lossy(); // todo: we may be able to skip file logging and use the ASL instead // if/when we no longer need to support older macOS versions. write!( &mut f, "\n\ \n\ \n\ \n\ Label\n\ {}\n\ LimitLoadToSessionType\n\ Aqua\n\ ProgramArguments\n\ \n\ {}\n\ {}\n\ \n\ KeepAlive\n\ \n\ StandardErrorPath\n\ {}\n\ StandardOutPath\n\ {}\n\ \n\ ", get_service_label(), exe.into_os_string().to_string_lossy(), args.join(""), log_file, log_file )?; Ok(()) } ================================================ FILE: cli/src/tunnels/service_windows.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use async_trait::async_trait; use shell_escape::windows::escape as shell_escape; use std::os::windows::process::CommandExt; use std::{path::PathBuf, process::Stdio}; use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, DETACHED_PROCESS}; use winreg::{enums::HKEY_CURRENT_USER, RegKey}; use crate::util::command::new_std_command; use crate::{ constants::TUNNEL_ACTIVITY_NAME, log, state::LauncherPaths, tunnels::{protocol, singleton_client::do_single_rpc_call}, util::errors::{wrap, wrapdbg, AnyError}, }; use super::service::{tail_log_file, ServiceContainer, ServiceManager as CliServiceManager}; const DID_LAUNCH_AS_HIDDEN_PROCESS: &str = "VSCODE_CLI_DID_LAUNCH_AS_HIDDEN_PROCESS"; pub struct WindowsService { log: log::Logger, tunnel_lock: PathBuf, log_file: PathBuf, } impl WindowsService { pub fn new(log: log::Logger, paths: &LauncherPaths) -> Self { Self { log, tunnel_lock: paths.tunnel_lockfile(), log_file: paths.service_log_file(), } } fn open_key() -> Result { RegKey::predef(HKEY_CURRENT_USER) .create_subkey(r"Software\Microsoft\Windows\CurrentVersion\Run") .map_err(|e| wrap(e, "error opening run registry key").into()) .map(|(key, _)| key) } } #[async_trait] impl CliServiceManager for WindowsService { async fn register(&self, exe: std::path::PathBuf, args: &[&str]) -> Result<(), AnyError> { let key = WindowsService::open_key()?; let mut reg_str = String::new(); let mut cmd = new_std_command(&exe); reg_str.push_str(shell_escape(exe.to_string_lossy()).as_ref()); let mut add_arg = |arg: &str| { reg_str.push(' '); reg_str.push_str(shell_escape((*arg).into()).as_ref()); cmd.arg(arg); }; for arg in args { add_arg(arg); } add_arg("--log-to-file"); add_arg(self.log_file.to_string_lossy().as_ref()); key.set_value(TUNNEL_ACTIVITY_NAME, ®_str) .map_err(|e| AnyError::from(wrapdbg(e, "error setting registry key")))?; info!(self.log, "Successfully registered service..."); cmd.stderr(Stdio::null()); cmd.stdout(Stdio::null()); cmd.stdin(Stdio::null()); cmd.creation_flags(CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); cmd.spawn() .map_err(|e| wrapdbg(e, "error starting service"))?; info!(self.log, "Tunnel service successfully started"); Ok(()) } async fn show_logs(&self) -> Result<(), AnyError> { tail_log_file(&self.log_file).await } async fn run( self, launcher_paths: LauncherPaths, mut handle: impl 'static + ServiceContainer, ) -> Result<(), AnyError> { if std::env::var(DID_LAUNCH_AS_HIDDEN_PROCESS).is_ok() { return handle.run_service(self.log, launcher_paths).await; } // Start as a hidden subprocess to avoid showing cmd.exe on startup. // Fixes https://github.com/microsoft/vscode/issues/184058 // I also tried the winapi ShowWindow, but that didn't yield fruit. new_std_command(std::env::current_exe().unwrap()) .args(std::env::args().skip(1)) .env(DID_LAUNCH_AS_HIDDEN_PROCESS, "1") .stderr(Stdio::null()) .stdout(Stdio::null()) .stdin(Stdio::null()) .creation_flags(CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS) .spawn() .map_err(|e| wrap(e, "error starting nested process"))?; Ok(()) } async fn is_installed(&self) -> Result { let key = WindowsService::open_key()?; Ok(key.get_raw_value(TUNNEL_ACTIVITY_NAME).is_ok()) } async fn unregister(&self) -> Result<(), AnyError> { let key = WindowsService::open_key()?; match key.delete_value(TUNNEL_ACTIVITY_NAME) { Ok(_) => {} Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => return Err(wrap(e, "error deleting registry key").into()), } info!(self.log, "Tunnel service uninstalled"); let r = do_single_rpc_call::<_, ()>( &self.tunnel_lock, self.log.clone(), protocol::singleton::METHOD_SHUTDOWN, protocol::EmptyObject {}, ) .await; if r.is_err() { warning!(self.log, "The tunnel service has been unregistered, but we couldn't find a running tunnel process. You may need to restart or log out and back in to fully stop the tunnel."); } else { info!(self.log, "Successfully shut down running tunnel."); } Ok(()) } } ================================================ FILE: cli/src/tunnels/shutdown_signal.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use futures::{stream::FuturesUnordered, StreamExt}; use std::{fmt, path::PathBuf}; use sysinfo::Pid; use crate::util::{ machine::{wait_until_exe_deleted, wait_until_process_exits}, sync::{new_barrier, Barrier, Receivable}, }; /// Describes the signal to manully stop the server #[derive(Copy, Clone)] pub enum ShutdownSignal { CtrlC, ParentProcessKilled(Pid), ExeUninstalled, ServiceStopped, RpcShutdownRequested, RpcRestartRequested, } impl fmt::Display for ShutdownSignal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { ShutdownSignal::CtrlC => write!(f, "Ctrl-C received"), ShutdownSignal::ParentProcessKilled(p) => { write!(f, "Parent process {p} no longer exists") } ShutdownSignal::ExeUninstalled => { write!(f, "Executable no longer exists") } ShutdownSignal::ServiceStopped => write!(f, "Service stopped"), ShutdownSignal::RpcShutdownRequested => write!(f, "RPC client requested shutdown"), ShutdownSignal::RpcRestartRequested => { write!(f, "RPC client requested a tunnel restart") } } } } pub enum ShutdownRequest { CtrlC, ParentProcessKilled(Pid), ExeUninstalled(PathBuf), Derived(Box + Send>), } impl ShutdownRequest { async fn wait(self) -> Option { match self { ShutdownRequest::CtrlC => { let ctrl_c = tokio::signal::ctrl_c(); ctrl_c.await.ok(); Some(ShutdownSignal::CtrlC) } ShutdownRequest::ParentProcessKilled(pid) => { wait_until_process_exits(pid, 2000).await; Some(ShutdownSignal::ParentProcessKilled(pid)) } ShutdownRequest::ExeUninstalled(exe_path) => { wait_until_exe_deleted(&exe_path, 2000).await; Some(ShutdownSignal::ExeUninstalled) } ShutdownRequest::Derived(mut rx) => rx.recv_msg().await, } } /// Creates a receiver channel sent to once any of the signals are received. /// Note: does not handle ServiceStopped pub fn create_rx( signals: impl IntoIterator, ) -> Barrier { let (barrier, opener) = new_barrier(); let futures = signals .into_iter() .map(|s| s.wait()) .collect::>(); tokio::spawn(async move { if let Some(s) = futures.filter_map(futures::future::ready).next().await { opener.open(s); } }); barrier } } ================================================ FILE: cli/src/tunnels/singleton_client.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ path::Path, sync::{ atomic::{AtomicBool, Ordering}, Arc, }, thread, }; use const_format::concatcp; use tokio::sync::mpsc; use crate::{ async_pipe::{socket_stream_split, AsyncPipe}, constants::IS_INTERACTIVE_CLI, json_rpc::{new_json_rpc, start_json_rpc, JsonRpcSerializer}, log, rpc::RpcCaller, singleton::connect_as_client, tunnels::{code_server::print_listening, protocol::EmptyObject}, util::{errors::CodeError, sync::Barrier}, }; use super::{ protocol, shutdown_signal::{ShutdownRequest, ShutdownSignal}, }; pub struct SingletonClientArgs { pub log: log::Logger, pub stream: AsyncPipe, pub shutdown: Barrier, } struct SingletonServerContext { log: log::Logger, exit_entirely: Arc, caller: RpcCaller, } const CONTROL_INSTRUCTIONS_COMMON: &str = "Connected to an existing tunnel process running on this machine."; const CONTROL_INSTRUCTIONS_INTERACTIVE: &str = concatcp!( CONTROL_INSTRUCTIONS_COMMON, " You can press: - \"x\" + Enter to stop the tunnel and exit - \"r\" + Enter to restart the tunnel - Ctrl+C to detach " ); /// Serves a client singleton. Returns true if the process should exit after /// this returns, instead of trying to start a tunnel. pub async fn start_singleton_client(args: SingletonClientArgs) -> bool { let mut rpc = new_json_rpc(); let (msg_tx, msg_rx) = mpsc::unbounded_channel(); let exit_entirely = Arc::new(AtomicBool::new(false)); debug!( args.log, "An existing tunnel is running on this machine, connecting to it..." ); if *IS_INTERACTIVE_CLI { let stdin_handle = rpc.get_caller(msg_tx.clone()); thread::spawn(move || { let mut input = String::new(); loop { input.truncate(0); match std::io::stdin().read_line(&mut input) { Err(_) | Ok(0) => return, // EOF or not a tty _ => {} }; match input.chars().next().map(|c| c.to_ascii_lowercase()) { Some('x') => { stdin_handle.notify(protocol::singleton::METHOD_SHUTDOWN, EmptyObject {}); return; } Some('r') => { stdin_handle.notify(protocol::singleton::METHOD_RESTART, EmptyObject {}); } Some(_) | None => {} } } }); } let caller = rpc.get_caller(msg_tx); let mut rpc = rpc.methods(SingletonServerContext { log: args.log.clone(), exit_entirely: exit_entirely.clone(), caller, }); rpc.register_sync(protocol::singleton::METHOD_SHUTDOWN, |_: EmptyObject, c| { c.exit_entirely.store(true, Ordering::SeqCst); Ok(()) }); rpc.register_async( protocol::singleton::METHOD_LOG_REPLY_DONE, |_: EmptyObject, c| async move { c.log.result(if *IS_INTERACTIVE_CLI { CONTROL_INSTRUCTIONS_INTERACTIVE } else { CONTROL_INSTRUCTIONS_COMMON }); let res = c .caller .call::<_, _, protocol::singleton::StatusWithTunnelName>( protocol::singleton::METHOD_STATUS, protocol::EmptyObject {}, ); // we want to ensure the "listening" string always gets printed for // consumers (i.e. VS Code). Ask for it. If the tunnel is not currently // connected though, it will be soon, and that'll be in the log replays. if let Ok(Ok(s)) = res.await { if let Some(name) = s.name { print_listening(&c.log, &name); } } Ok(()) }, ); rpc.register_sync( protocol::singleton::METHOD_LOG, |log: protocol::singleton::LogMessageOwned, c| { match log.level { Some(level) => c.log.emit(level, &format!("{}{}", log.prefix, log.message)), None => c.log.result(format!("{}{}", log.prefix, log.message)), } Ok(()) }, ); let (read, write) = socket_stream_split(args.stream); let _ = start_json_rpc(rpc.build(args.log), read, write, msg_rx, args.shutdown).await; exit_entirely.load(Ordering::SeqCst) } pub async fn do_single_rpc_call< P: serde::Serialize + 'static, R: serde::de::DeserializeOwned + Send + 'static, >( lock_file: &Path, log: log::Logger, method: &'static str, params: P, ) -> Result { let client = match connect_as_client(lock_file).await { Ok(p) => p, Err(CodeError::SingletonLockfileOpenFailed(_)) | Err(CodeError::SingletonLockedProcessExited(_)) => { return Err(CodeError::NoRunningTunnel); } Err(e) => return Err(e), }; let (msg_tx, msg_rx) = mpsc::unbounded_channel(); let mut rpc = new_json_rpc(); let caller = rpc.get_caller(msg_tx); let (read, write) = socket_stream_split(client); let rpc = tokio::spawn(async move { start_json_rpc( rpc.methods(()).build(log), read, write, msg_rx, ShutdownRequest::create_rx([ShutdownRequest::CtrlC]), ) .await .unwrap(); }); let r = caller.call(method, params).await.unwrap(); rpc.abort(); r.map_err(CodeError::TunnelRpcCallFailed) } ================================================ FILE: cli/src/tunnels/singleton_server.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ pin::Pin, sync::{Arc, Mutex}, }; use super::{ code_server::CodeServerArgs, control_server::ServerTermination, dev_tunnels::{ActiveTunnel, StatusLock}, protocol, shutdown_signal::{ShutdownRequest, ShutdownSignal}, }; use crate::{ async_pipe::socket_stream_split, json_rpc::{new_json_rpc, start_json_rpc, JsonRpcSerializer}, log, rpc::{RpcCaller, RpcDispatcher}, singleton::SingletonServer, state::LauncherPaths, tunnels::code_server::print_listening, update_service::Platform, util::{ errors::{AnyError, CodeError}, ring_buffer::RingBuffer, sync::{Barrier, ConcatReceivable}, }, }; use futures::future::Either; use tokio::{ pin, sync::{broadcast, mpsc}, task::JoinHandle, }; pub struct SingletonServerArgs<'a> { pub server: &'a mut RpcServer, pub log: log::Logger, pub tunnel: ActiveTunnel, pub paths: &'a LauncherPaths, pub code_server_args: &'a CodeServerArgs, pub platform: Platform, pub shutdown: Barrier, pub log_broadcast: &'a BroadcastLogSink, } struct StatusInfo { name: String, lock: StatusLock, } #[derive(Clone)] struct SingletonServerContext { log: log::Logger, shutdown_tx: broadcast::Sender, broadcast_tx: broadcast::Sender>, // ugly: a lock in a lock. current_status needs to be provided only // after we set up the tunnel, however the tunnel is created after the // singleton server starts to avoid a gap in singleton availability. // However, this should be safe, as the lock is only used for immediate // data reads (in the `status` method). current_status: Arc>>, } pub struct RpcServer { fut: JoinHandle>, shutdown_broadcast: broadcast::Sender, current_status: Arc>>, } pub fn make_singleton_server( log_broadcast: BroadcastLogSink, log: log::Logger, server: SingletonServer, shutdown_rx: Barrier, ) -> RpcServer { let (shutdown_broadcast, _) = broadcast::channel(4); let rpc = new_json_rpc(); let current_status = Arc::new(Mutex::default()); let mut rpc = rpc.methods(SingletonServerContext { log: log.clone(), shutdown_tx: shutdown_broadcast.clone(), broadcast_tx: log_broadcast.get_brocaster(), current_status: current_status.clone(), }); rpc.register_sync( protocol::singleton::METHOD_RESTART, |_: protocol::EmptyObject, ctx| { info!(ctx.log, "restarting tunnel after client request"); let _ = ctx.shutdown_tx.send(ShutdownSignal::RpcRestartRequested); Ok(()) }, ); rpc.register_sync( protocol::singleton::METHOD_STATUS, |_: protocol::EmptyObject, c| { Ok(c.current_status .lock() .unwrap() .as_ref() .map(|s| protocol::singleton::StatusWithTunnelName { name: Some(s.name.clone()), status: s.lock.read(), }) .unwrap_or_default()) }, ); rpc.register_sync( protocol::singleton::METHOD_SHUTDOWN, |_: protocol::EmptyObject, ctx| { info!( ctx.log, "closing tunnel and all clients after a shutdown request" ); let _ = ctx.broadcast_tx.send(RpcCaller::serialize_notify( &JsonRpcSerializer {}, protocol::singleton::METHOD_SHUTDOWN, protocol::EmptyObject {}, )); let _ = ctx.shutdown_tx.send(ShutdownSignal::RpcShutdownRequested); Ok(()) }, ); // we tokio spawn instead of keeping a future, since we want it to progress // even outside of the start_singleton_server loop (i.e. while the tunnel restarts) let fut = tokio::spawn(async move { serve_singleton_rpc(log_broadcast, server, rpc.build(log), shutdown_rx).await }); RpcServer { shutdown_broadcast, current_status, fut, } } pub async fn start_singleton_server( args: SingletonServerArgs<'_>, ) -> Result { let shutdown_rx = ShutdownRequest::create_rx([ ShutdownRequest::Derived(Box::new(args.server.shutdown_broadcast.subscribe())), ShutdownRequest::Derived(Box::new(args.shutdown.clone())), ]); { print_listening(&args.log, &args.tunnel.name); let mut status = args.server.current_status.lock().unwrap(); *status = Some(StatusInfo { name: args.tunnel.name.clone(), lock: args.tunnel.status(), }) } let serve_fut = super::serve( &args.log, args.tunnel, args.paths, args.code_server_args, args.platform, shutdown_rx, ); pin!(serve_fut); match futures::future::select(Pin::new(&mut args.server.fut), &mut serve_fut).await { Either::Left((rpc_result, fut)) => { // the rpc server will only end as a result of a graceful shutdown, or // with an error. Return the result of the eventual shutdown of the // control server. rpc_result.unwrap()?; fut.await } Either::Right((ctrl_result, _)) => ctrl_result, } } async fn serve_singleton_rpc( log_broadcast: BroadcastLogSink, mut server: SingletonServer, dispatcher: RpcDispatcher, shutdown_rx: Barrier, ) -> Result<(), CodeError> { let mut own_shutdown = shutdown_rx.clone(); let shutdown_fut = own_shutdown.wait(); pin!(shutdown_fut); loop { let cnx = tokio::select! { c = server.accept() => c?, _ = &mut shutdown_fut => return Ok(()), }; let (read, write) = socket_stream_split(cnx); let dispatcher = dispatcher.clone(); let msg_rx = log_broadcast.replay_and_subscribe(); let shutdown_rx = shutdown_rx.clone(); tokio::spawn(async move { let _ = start_json_rpc(dispatcher.clone(), read, write, msg_rx, shutdown_rx).await; }); } } /// Log sink that can broadcast and replay log events. Used for transmitting /// logs from the singleton to all clients. This should be created and injected /// into other services, like the tunnel, before `start_singleton_server` /// is called. #[derive(Clone)] pub struct BroadcastLogSink { recent: Arc>>>, tx: broadcast::Sender>, } impl Default for BroadcastLogSink { fn default() -> Self { Self::new() } } impl BroadcastLogSink { pub fn new() -> Self { let (tx, _) = broadcast::channel(64); Self { tx, recent: Arc::new(Mutex::new(RingBuffer::new(50))), } } pub fn get_brocaster(&self) -> broadcast::Sender> { self.tx.clone() } fn replay_and_subscribe( &self, ) -> ConcatReceivable, mpsc::UnboundedReceiver>, broadcast::Receiver>> { let (log_replay_tx, log_replay_rx) = mpsc::unbounded_channel(); for log in self.recent.lock().unwrap().iter() { let _ = log_replay_tx.send(log.clone()); } let _ = log_replay_tx.send(RpcCaller::serialize_notify( &JsonRpcSerializer {}, protocol::singleton::METHOD_LOG_REPLY_DONE, protocol::EmptyObject {}, )); ConcatReceivable::new(log_replay_rx, self.tx.subscribe()) } } impl log::LogSink for BroadcastLogSink { fn write_log(&self, level: log::Level, prefix: &str, message: &str) { let s = JsonRpcSerializer {}; let serialized = RpcCaller::serialize_notify( &s, protocol::singleton::METHOD_LOG, protocol::singleton::LogMessage { level: Some(level), prefix, message, }, ); let _ = self.tx.send(serialized.clone()); self.recent.lock().unwrap().push(serialized); } fn write_result(&self, message: &str) { self.write_log(log::Level::Info, "", message); } } ================================================ FILE: cli/src/tunnels/socket_signal.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use serde::Serialize; use tokio::sync::mpsc; use crate::msgpack_rpc::MsgPackCaller; use super::{ protocol::{ClientRequestMethod, RefServerMessageParams, ServerClosedParams, ToClientRequest}, server_multiplexer::ServerMultiplexer, }; pub struct CloseReason(pub String); pub enum SocketSignal { /// Signals bytes to send to the socket. Send(Vec), /// Closes the socket (e.g. as a result of an error) CloseWith(CloseReason), } impl From> for SocketSignal { fn from(v: Vec) -> Self { SocketSignal::Send(v) } } impl SocketSignal { pub fn from_message(msg: &T) -> Self where T: Serialize + ?Sized, { SocketSignal::Send(rmp_serde::to_vec_named(msg).unwrap()) } } /// todo@connor4312: cleanup once everything is moved to rpc standard interfaces #[allow(dead_code)] pub enum ServerMessageDestination { Channel(mpsc::Sender), Rpc(MsgPackCaller), } /// Struct that handling sending or closing a connected server socket. pub struct ServerMessageSink { id: u16, tx: Option, multiplexer: ServerMultiplexer, flate: Option>, } impl ServerMessageSink { pub fn new_plain( multiplexer: ServerMultiplexer, id: u16, tx: ServerMessageDestination, ) -> Self { Self { tx: Some(tx), id, multiplexer, flate: None, } } pub fn new_compressed( multiplexer: ServerMultiplexer, id: u16, tx: ServerMessageDestination, ) -> Self { Self { tx: Some(tx), id, multiplexer, flate: Some(FlateStream::new(CompressFlateAlgorithm( flate2::Compress::new(flate2::Compression::new(2), false), ))), } } pub async fn server_closed(&mut self) -> Result<(), mpsc::error::SendError> { self.server_message_or_closed(None).await } pub async fn server_message( &mut self, body: &[u8], ) -> Result<(), mpsc::error::SendError> { self.server_message_or_closed(Some(body)).await } async fn server_message_or_closed( &mut self, body_or_end: Option<&[u8]>, ) -> Result<(), mpsc::error::SendError> { let i = self.id; let mut tx = self.tx.take().unwrap(); if let Some(b) = body_or_end { let body = self.get_server_msg_content(b, false); let r = send_data_or_close_if_none(i, &mut tx, Some(RefServerMessageParams { i, body })) .await; self.tx = Some(tx); return r; } let tail = self.get_server_msg_content(&[], true); if !tail.is_empty() { let _ = send_data_or_close_if_none( i, &mut tx, Some(RefServerMessageParams { i, body: tail }), ) .await; } let r = send_data_or_close_if_none(i, &mut tx, None).await; self.tx = Some(tx); r } pub(crate) fn get_server_msg_content<'a: 'b, 'b>( &'a mut self, body: &'b [u8], finish: bool, ) -> &'b [u8] { if let Some(flate) = &mut self.flate { if let Ok(compressed) = flate.process(body, finish) { return compressed; } } body } } async fn send_data_or_close_if_none( i: u16, tx: &mut ServerMessageDestination, msg: Option>, ) -> Result<(), mpsc::error::SendError> { match tx { ServerMessageDestination::Channel(tx) => { tx.send(SocketSignal::from_message(&ToClientRequest { id: None, params: match msg { Some(msg) => ClientRequestMethod::servermsg(msg), None => ClientRequestMethod::serverclose(ServerClosedParams { i }), }, })) .await } ServerMessageDestination::Rpc(caller) => { match msg { Some(msg) => caller.notify("servermsg", msg), None => caller.notify("serverclose", ServerClosedParams { i }), }; Ok(()) } } } impl Drop for ServerMessageSink { fn drop(&mut self) { self.multiplexer.remove(self.id); } } pub struct ClientMessageDecoder { dec: Option>, } impl ClientMessageDecoder { pub fn new_plain() -> Self { ClientMessageDecoder { dec: None } } pub fn new_compressed() -> Self { ClientMessageDecoder { dec: Some(FlateStream::new(DecompressFlateAlgorithm( flate2::Decompress::new(false), ))), } } pub fn decode<'a: 'b, 'b>(&'a mut self, message: &'b [u8]) -> std::io::Result<&'b [u8]> { match &mut self.dec { // todo@connor4312 do we ever need to actually 'finish' the client message stream? Some(d) => d.process(message, false), None => Ok(message), } } } trait FlateAlgorithm { fn total_in(&self) -> u64; fn total_out(&self) -> u64; fn process( &mut self, contents: &[u8], output: &mut [u8], finish: bool, ) -> Result; } struct DecompressFlateAlgorithm(flate2::Decompress); impl FlateAlgorithm for DecompressFlateAlgorithm { fn total_in(&self) -> u64 { self.0.total_in() } fn total_out(&self) -> u64 { self.0.total_out() } fn process( &mut self, contents: &[u8], output: &mut [u8], finish: bool, ) -> Result { let mode = match finish { true => flate2::FlushDecompress::Finish, false => flate2::FlushDecompress::None, }; self.0 .decompress(contents, output, mode) .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e)) } } struct CompressFlateAlgorithm(flate2::Compress); impl FlateAlgorithm for CompressFlateAlgorithm { fn total_in(&self) -> u64 { self.0.total_in() } fn total_out(&self) -> u64 { self.0.total_out() } fn process( &mut self, contents: &[u8], output: &mut [u8], finish: bool, ) -> Result { let mode = match finish { true => flate2::FlushCompress::Finish, false => flate2::FlushCompress::Sync, }; self.0 .compress(contents, output, mode) .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e)) } } struct FlateStream where A: FlateAlgorithm, { flate: A, output: Vec, } impl FlateStream where A: FlateAlgorithm, { pub fn new(alg: A) -> Self { Self { flate: alg, output: vec![0; 4096], } } pub fn process(&mut self, contents: &[u8], finish: bool) -> std::io::Result<&[u8]> { let mut out_offset = 0; let mut in_offset = 0; loop { let in_before = self.flate.total_in(); let out_before = self.flate.total_out(); match self.flate.process( &contents[in_offset..], &mut self.output[out_offset..], finish, ) { Ok(flate2::Status::Ok | flate2::Status::BufError) => { let processed_len = in_offset + (self.flate.total_in() - in_before) as usize; let output_len = out_offset + (self.flate.total_out() - out_before) as usize; if processed_len < contents.len() || output_len == self.output.len() { // If we filled the output buffer but there's more data to compress, // or the output got filled after processing all input, extend // the output buffer and keep compressing. out_offset = output_len; in_offset = processed_len; if output_len == self.output.len() { self.output.resize(self.output.len() * 2, 0); } continue; } return Ok(&self.output[..output_len]); } Ok(flate2::Status::StreamEnd) => { return Err(std::io::Error::new( std::io::ErrorKind::UnexpectedEof, "unexpected stream end", )) } Err(e) => return Err(e), } } } } #[cfg(test)] mod tests { use super::*; use base64::{engine::general_purpose, Engine as _}; #[test] fn test_round_trips_compression() { let (tx, _) = mpsc::channel(1); let mut sink = ServerMessageSink::new_compressed( ServerMultiplexer::new(), 0, ServerMessageDestination::Channel(tx), ); let mut decompress = ClientMessageDecoder::new_compressed(); // 3000 and 30000 test resizing the buffer for msg_len in [3, 30, 300, 3000, 30000] { let vals = (0..msg_len).map(|v| v as u8).collect::>(); let compressed = sink.get_server_msg_content(&vals, false); assert_ne!(compressed, vals); let decompressed = decompress.decode(compressed).unwrap(); assert_eq!(decompressed.len(), vals.len()); assert_eq!(decompressed, vals); } } const TEST_191501_BUFS: [&str; 3] = [ "TMzLSsQwFIDhfSDv0NXsYs2kubQQXIgX0IUwHVyfpCdjaSYZmkjRpxdEBnf/5vufHsZmK0PbxuwhfuRS2zmVecKVBd1rEYTUqL3gCoxBY7g2RoWOg+nE7Z4H1N3dij6nhL7OOY15wWTBeN87IVkACayTijMXcGJagevkxJ3i/e4/swFiwV1Z5ss7ukP2C9bHFc5YbF0/sXkex7eW33BK7q9maI6X0woTUvIXQ7OhK7+YkgN6dn2xF/wamhTgVM8xHl8Tr2kvvv2SymYtJZT8AAAA//8=", "YmJAgIhqpZLKglQlK6XE0pIMJR0IZaVUlJqbX5JaXAwSSkksSQQK+WUkung5BWam6TumVaWEFhQHJBuUGrg4WUY4eQV4GOTnhwVkWJiX5lRmOdoq1QIAAAD//w==", "jHdTdCZQk23UsW3btpOObeuLbdu2bdvs2E46tm17+p+71ty5b/ect13aVbte6n8XmfmfIv9rev8BaP8BNjYWzv8s/78S/ItxsjCzNTEW/T+s2DhZaNSE5Bi41B0kFBjZ2VjYtAzlzTWUHJWtJC2dPFUclDmZPW2EFQEAGkN3Rb7/tGPiZOFoYizy/1LhZvnXu6OZEzG3F/F/duNf6v/Zk39B9naO/yAuRi5GHx8FeWUVQob/JZTEPx9uQiZmDnrGf5/pv93+KeX0b7OEzExs/9kALo7WDBz0nEz0/wxCAICJ/T+QmoH6v0V2/udCJ2Nia+Zs/i8L47/3f+H/cOMmNLS3t7YAGP6HLIM7nZubG52pnaMN3b+kJrYAO2MT4//IGvKquY+4Oly7Z01ajWRItkE1jacYu9tcSU339/OnBkYgUbBD9rHonA9pvJV7heYuoFUpRcnKi8RwoJrSkW7ePD6N3ANHPr1UW7wPu5907dLnd4hlXwziROJkDgejfKv5ztZzPgXoUaEPEsM6y752iLyMJdkKwrSo+LAiaFp4HSRvSAnMT2Ck9JHIyQNuaFslDhaLQMIP+B7AGRyZFXeqpFF8HvfFVkQHqGejNjdizFvRHkndAl8AtfEqRHfxPFAit0twsNMyaONmusi/YHvmbQhpTRnyOV0gg+tXzisWmDsLBFAutCcGRHR0Cigere6p3A7NDGmBxHAZSmK/LGHKCeyUqN9fyBIUmyCtV99ptMaQWt4KAny5Fg+nTU1gBvBq4RvHlGCF9WL+2ZxKDfB2gr2GQaUY76Tv7x79VKbxwC5GITg2q02XPy6ZNFnLryVCGskiYPFPQLAsU+LrTvbyQTk7KNUFHwzBUTP1MiKg9LCdWAs8BZx3FHYaJyvIPw4nJpUAP3rP8GPdJeb3iIJ7i8xf15F71iT47rNv+qCXaQD9NBo8PcRVqnEy3vyrPG5SO8HwSDk9PhQJe2xo4Q52soIDB3v1jYYmR8ZkuoNq3Moy6BDjR1WBCTFJEHjdSSADxzRJ2hnozSOLmzTLuKgwWnFU1aGpQ5S8Ry7ME7gVb+CwnFvVtrpofL+DXvE3CY9Fhqe0y4Sq1yLyn/vcgA7ShFG+QnTB5zaKS3Ndj6LSCxwiNivY9R9TsAXobw4Exqog7xCAjYxNIbDuo/fC1QKpFUzvxw+7Rjc8J2lJg80YveK++I5fqJVAFu0Gb4SuJAd8ernBkpyy9lbou0enEfQMOjjucNiy+rgpU4pl+ERgt/Be+8G9l0RbeUwthLZp4ARnBHAB2mcB2o1cJIbhXnMiYStLmjwI+i+NOhBvRV8nmAVslkGdsEVU6Q3hYy/cT/QRTbEF0W58bkYPCyx93ESp7/sWkTG5i9GInCwW+zw1NIRfi2zkuz7KIzOlg33b5/R60L2tjlPtcLjZYL9qGWXwgPApKkndbDq0HhRCQYTyEZ1nC4MFi9NuasFm4t4UV4/W4L0A8YwsXH2m8Rh7hl1No5oIIlAGi5Er/amKw5mAA/Hvwbzfd4TGx66MHWA9t6NAA2WPx538griN7LCqE2315o09fNbOumI6fM1CN0AJT2FheQgaG4tdPFPn6uAeDXUDT8OkTdRFNi6Av4rwo6NnyfLnLYxBNdAhHs75bAedI5egbRrWLC48JT7aKsV+VsOmLsk0TGh6ISxI3WzskVbVFr6HGLy8jee1ZiMF0wzd/B4LvlyGIMa6HD+JBsGOH6vukgqV7ywTl6P+Wo8mTZHo12d7u09Z59eyXJcZKnqY4YzEzGUrlGzvO0Rgfgsse3RMPWJSpsETWqo5zMTtzYk9HANeoA5ubNoO/jjtLyModk/iH6XLiFD1591q+nXNb3Ve2v/aHlJQQYaytpOULvnsEYGIQH9+y3eK1Rgqgs7fxD3uzpv06A/afiToieIJpbjLhy3JZBEAmtN5UgJm6SuCbqgKJ+fDsuwMp/m0fCNVqrYORcBpKTvIWFzWF/leWJntKUis0dPrWy5x7Yu2GhqJh3GN2bT8w1uIh1haSlBmhMOzV3yNUmNcjqFV+GziNt6twoPDJ+4m7TE7hP2E9mEhiYihUDjT0X2Q4k0GIqdIl6fpoFPK0zdfRfbEkP2Ulr7fzfVqCYp9iuxtZFqBafBWLNHVjYtIn9/Z6Z3mP8DBfOYrXbMXldLjKW6rHr3w/LACe+LINkxcxQ9rxxBffepkhhj8NQ7vpyXpudfYmfPMsnai+b5VI5QMcyZly26kxMo6KGGilNYyX/hLaowV4GjIEY7kHRCNmJIBNevb1ag4w98wLWMtfyPMLn18o9cFKiJk2kjZmRBFh0S0Bd7AjxiNO8YdDQ83lBGS5JrxmLG+hW2oGYQllWS2UjK3+loONmC6NpPNgUiNhDQ05s24iRJZ/bzrgBskPLGukoMu8NK8CQNKZE8zzmsCrnkU53iPeZd/UT8ox6WMMZOtDv8YyQpTmhbzXCQW9ogbfgqH447dJFZuPkT4MGfKw+0c5L6aLWqAadBU9yLftFVsi8GZOSB9Ctv9/fJZ5SmlNgt25uGvspB9y1PQGEmLQyjFiGK7kveEw4Knn9lv/9GV2YlCdeRTAUyOS56k6G4ajfxNtMHPaDqIWTM1yBem3dShwkhD0nMXit14/wHRHosy59T+nkuvxG1MbTx8GJM45rvrOmUW0nwxNNdsdqFCNPWn+GcYzIdwCNFtHmdSKNOecfZZVJnKzuGbs41wRQIkv1E1p6ITiPxv+zKWflEU76wHOPrDx4rmyw3Z6MqaP316eOcW43JwBvp9hJuMUHr0TFkvjd5KzvmUSrZfYvpPZ2humVwOsjChiFzc7aoBMt8MdXyf2LIhuhBAg8Ue3wLqlg3cEYBS2z+uzrS5bJzmzH3NGmI+M/WbHOkbqcNtSoZjwp4NI5bSpCKWs7BqrK8sfsUC+UpA08Lfc4CpcBmsTyuHncO2gLc9jPMT+SBAgiZxTDncaiM+YG19ntqYSttys+jpASZDwEWjYRN8QURClAIs0G0KKoY0jjWcc0rypYXiCsHD9+kjtnYJHuzeZw2GQ5U5j7acLM8nyuy8bSJaKZXFq8TJkQ/p4lSkKHpVQPi+dWF4jYaQFEGiPAuiLOGzOE/f8B2rePs9zps7QivUyIiM8fsbPx5mwaC7FbjdihjbM198akLx99SpXAF4fh6d/xwLppw2kFrKa0UsTa/emTuV+6l2/8WmVWLd8JJAhcE+qbMrJBrohgGdDNZIRxJOrsFCzSmu2ykTCZnZlPITlbK/hUA/+DwdtJbmzKczEWAS9ENNbxHNSbn4Nqsz0yvhUE2a/FT6tvnBbXm/X2yLQQhxuVyNCsK2TeUNifqlsCEAJAALqqNI/NX+owJEAk+KehT/fpCsXGTsT3kFsUiPNWAkOEuHviK3Nzpu53edKRZgInWOWhGnd8aD6k7kio0tLT8i/PkxVrdZftlNrqPZfiEXkqX3hM526HzLGVzlr+CvTBKxsU8ROxHvBGWzJk4Tt0uDhZessy5BDFVx2xiYxMTXfQyv8NF0Op3CKCFvH1KbE2Z2TGCvpOEH7LKVK5TyTVSP+yah8TkpL1cHorIRxz2a5cMNMZGgdooqszII7PJuT3Ii0GpCCXe3v5mzysGhVKBulynWOeMrlJ4jKA4xzAXIg7ReLCGOntAOvU7qD+5UBufLWxx/3cqhuMcZDnR2dUjJuFG5LuFiwnvboFRMjVTvVJkcNdUc7b+0auIQWC1E3hTQx422OCMuGvayP3WMCGe8IClwSw4f1uA5LkoDYZbVQo1SUzETYNPQUK5BTJy7YRq4ln9vLvDHDImNd3TiWnsL7Zp9qWVSSTfSVSyZTT4fJqKIZ/Kcy7IkXFyv0Frw64R7y0vM+tAu+0kebn9y+DlN2xmi7nmf81iI1xffS5+ehMzQJTIa8SjVc8kCf14eOLiR7TgCnHcJieDFQI9r9K9co2G0hpitdihrbb56XvossnHl8Fu4JRLBPgKXsAQyX3v3BUHuw42rmeQXz74oZzmEIG13oteilg9HOUyoR5NHE94cYtIqP80qheAh9uQA9e3+TSmiLy6dsU625mYOYcPixVm9ZYuiOtLWQ3tT8j2T111qqjqNu6yUSxlIAh0+ANUEhEh9Uoj9v89/WqlGXNWPDmKfRtn+yFVoyggl8PjW0GB7qfreaEuoqouCGoV+lWma6sNZyKYQGIn51nzIyO1uUlRQZq5j8aTQgcXlNYi5rXALJ2Kj8nEbJT8OqXEt0fbWPKaLQZch23yR9RLyaXMpTIzzRBkoFY5g0MfTWFLbcMynydkZITcfLTSDeD/fxSqUzWmgjk9j1aQ07KUBInTRErSbfEhgCVikEENWXpOubo3XV4YBv9CJYSuXnSv0d3jLQdHefqwT7+Gyqy0ZJYicFYw3ma+acapIZw2r4qg4BNKbSbkMKOuWidsr1dxjS9bjSYoNH/VDBdbgXpXTpPJosDIjwMHsV48OfhwZjvnAC0r2yJ3+NPhBP4g/GU14mpdefzvR08OElSHLpZidGsL5GGtpzcohM5sQ48TMsOs6Cy3vvgKR1oanGjGa8dRN+UaaAWm1dieSOjvXzIIVPp3zoKEgVu9zlP2W5NtNSVDfceVy/cA2IFjOlKa5EiLEEA57fuxvGmOvxCB+ZROvg6KOi6EbxLMylQEbvzctlbmEJ0S32x1usYisIWFfCLX/SEETVFuAxZJej9AcvkolOkSLNlohZdKzOYeRMfQM/RMT4JwSfFqHgIq4XeYPtTzMO2ZkTdOjdrrWL0ZMFosuXiKD/9qKKbo1FjqjwiT5a4uIaPdU95J52kiPoS7adOxUFiypbB9SrLFTABESJrPr0qMSVCi9cMME+Vt2Qq9gYFIvXoDRAR0SP04c/2A1r/tvxBu6JRGDB9cwYWOE1g8W+W/vju6WwPvifEO4AQ+KD3bGEhffrUWM1SnsAZBbJOgep/M1iU/HX4uNGb6Dmz+0PQdJAo7TkA2D+Wigyb9CQUfK16vwLvIIvMnylTcOOIAUtbiy2/lcdbmnQcFMt7ZZLQxBemf8S5L8jkyl1WLZyVNGDm5qf/72TQLs6KK4ljCJqMt0F6p8tidu/52WK95lYzKiZy6nlOSKadsCEWX5+eMzpJu8ZjYF5Qf1K54q5wO/T4Y+QYoWlUlXB6MoL0adwXmSs5T7Mht+6k8BO7T5I+3iI54WdYwixTnvlI/TNQSjwGJdxqJOmInihyKgkCx1lUyn/fx6jKZ+1MHPZwvfOg5V9TuCf+aXvjVhcgJHJBilS8ytrZh8FQh23yNbEIMoE6lYyWuYdSKv6831VdffGAP6gvaD3d9aUBJRkHquA1iqVB/ZG+bcJLpeMFJagd95AvGXUIuYwFKFmBtlKkjOuiEbKNKxv+SJ/NQCIGRBxVkm6oqcabuFnskNEhB4FnYnplnCIUZEfsuLirqsm6sSQZ2ZITdUAkmQ308cj5051V8FwogjNmZJyYuNNsOxYzumG33B7Z5k6QHkr2HC4aky5ZHP2bW8quZNaSXEcL5YGfZeTPTOVCv3TA+e4NLZeVocXTUYNWe7pyYjaf6EUeHdXOAMpZk9084KP8PBCwnlNfiZG2fXD+36bvn8sOVcsLvwAT01LEmVgo2E0geZqDPd8OIHJxDVB7VXNeFYIKjKgOjT63Bq49GLdBmwOlTKDljg00eYqLTQO66FPzSTWMc2EMGCae7sVr/OluTg/T4NKFt39gySNurVvPtlXZfqCo3GfCiyTV6iZWeuVMh69PrrozqgCX0mHJ+OyzMtQrTbqUB4BvHZe9Bfo/uyBDmRDWV0vTCz1mz0t+DTOjRkjEiAOFOKSQ5w/L3RgIwmuEgW3kqaQqtwAFIfWb9PxNuLvTLGMttZ3yO5P3aYl9G6jCSrrcr+3m0ICKOTBu8lH/lonRkZOq/08lpP5VtCEak6I+aSIT9tP9LJIZACn/IUe7qE88kjETKmnZT6F1D/1p58pEA0NI4g5CtdHlSXmg0s+zhAKS7tYpvNx96EPw5cCc5+VneGb0RDNvLaa+cEF4M/JuU0PcA9u9gu+PC+byS52tGqNA8yuH7El6JwFI8dXUvX07iAkC2VOvtt4kg0aeiHDyPHJpvvN4TaAH9Bz+WT5FDWNTAz4LC79GO6pQb9j5iojBlt+UUHvr8nfZN6AKa57RMsFTt9m0t0eBVUqR5fgpE/k6+57U9FtAQPZ5ufj66n0Ys1Chyr93K5jhX3GM64JjdryhghfffO150Q+hYrX3a5/fo2ULWBM27UoViPGVCFtmd0Yw1V5F+l8j58Mck1yUYxpU6tg+o1tara6THtW91V2dqC0+ha42qUVZhScMys1ygeqrpwVTvfhsaVH3/e0xXB7cO4UYkBg1ivB9O+90jwFfg1noBWOg7JpyGvPzYuLPz1CzNtVCqtRpqhMbCu4e2xQ++w8gJGD87TjODSjvgsXoDOs/Fs2qzhSatxvKrnW6pmKqwo9j4B12XZ4Sc+4oE2DIquGY8iyYrp9oBkSCQ8kOIkYVD74yj5C+Y/+JkFNVPwwBvarswkuyZUp8gjHCBLFkf0l+yBDWvJ/jZBXyUFSCGDIrpl1USocwndJFH5zst9/ZyaiKGKEO2nEBAuOCo1XTAyPLIjonN2pH7c01ySgFXymnEV0K0UGq78eDfUtxpmcGLtK+75NVraVGD2wNVNrpWJl1al+s+CM4OvabLcM6VnweXcGciDFRmghhWVoE4EqnhFUuFxCB3umtoyn8lKuEy1fmrRsweDOMtUNd0qA6IctHwIM0AOX2Sx0KxqjEhpp+YkfStkyLrzC33yJbUqRbgkDGq1fKfJDAdenpfQOVj6VMCsB208bbzJUcGOWzZtvfnETOnRLxb4LddrcPuP91CawvOVuAphNrIEUsiRon1SrCuL8GVF75tbSHcskqjIVLfycIZlvVjlywu9gBptiORxw/e1CZ7bDeKlTTIK67KQqosSEs1fnc/X0aAxlkqaOEZQdefKhrABuZFa/KTPRhQsFSncg6wI+niscy0rjfkkvg5fe4c17WCpa0eXot7t+4ot9O5+v0H/buYYniE4MzfrsDnJhqu1tLt1z0dNQ60Qz/8RxR7461d9KxJaNTelFLXDQwDHcTCBSk+0BrJVKT9Ls0bHgxr0zDoaDnbnlXjuu9+I+TH6sZYee1kDBqfPV/RKaXBx6yCFxEBosyCqvwmiuHUzItjvCMSpgREhM861FtvcyaGbN1+nFgM0NlPJQdpqz7bpEJcVw8HFp0yAAT61uYy8m51btG5zFKE74t+qEpjkQPOxPzxh52MDHVgMT0vIQcdA2GGXmjLInOlKHy44blBXKhSsvnWk6goe3xaY/vatI9iOJP0zdmqYuV/Z82spbMuwMwDVEEqrn/KPXqWl0G9AIAPPSA/DO5U9NZAn8nW5CcnB359CkSxVmBXbPBph/GvVrjZEiohjaAfRzdYgSBArwPcIhmfsE3ankfWrXOiw0qJgH4UvOuQphVkNCTIDl405MQMo+6Usm6YMkKx93V+wFSt0l6zoNYeELrp5hNwWNc35EVD0YJegiTIgVDqJykV3YM5po2UCDF4a1Ijhgu+mWL/+B3K8OcvmsGG8X/tKBCNPK/0jJT6PKfks/NEJDkcRcfm1ZDp9AFzldq53UZoT4o4zhRSpLA+f6VTIJx4/t78vpyZKMEJmc8RbIp/swFrbSGInwW4NCrovIK+oS5Z3zXeNbGSpuf2oWYAtpQvttaM2LNl4svcEwxvYor7JMy46l1f2SB0Q0PXLIehirHvMLhbfdWLQw0QB7Gq2O0khxvT1LjZ+H+euX7uZmkY9IvXdW0pnDhaNmZKT6nKj9K1bcLT3520W7lrdOzlEMHxtoSMMd9u2LtEkdtO0KIyfVvkXReY+ilkTyBUmcRCEWl27pABXdcl9jZn6A/16Ze1Lv9SFRncN42vpbOS3xkIBPtFwaDftP6IZLtchcxmj3xkeJFH8fFKg5f06HvCjPbxR3US46FTJqo49yM0H1L8wOjSC8wYHb4Mo6Zhh4i48snY9IOVfrIGqFfTsTQ5kxIctBPqGnMO7dl+iu4TUqeHkDk2IkmZSNjB7hp0mmLHKcTAB49JQDsZdlPlcOeADP/r7q/I5vXE8ZHzXqFmxW9v90+JMckU0V0AIrcJK9IQWl4LQR+dRuKRxJwDpy4wa4ymhqnBdjDMqQ/cetUExuVkzntiCPyOz6dMpAx9ZeidxQ02hYjPVqgFg8sCl1lTHTulvk7Nj698usBJMG+IKJorZp7+a97Tr226dW1h++Ic3ERIIDuFrJVY0UvO/vrTZrxZbzT2Ki+UvjN5Ins+P6gU7XLKlAlh4h3u54VXMJO6MqqpSFKXQlRY2fOOn/m5YDfOCvjmhsmrp63Wz9s+kowNsciO+DZa5Mce5qH9/ysvEHv7Sgb3AIZ4+zl1R9px1bU2HI/tcieQUvHkNG0N43uBelEbsrZTfVDAsk7KashZp+QG9k91BWuxlN00Hmaqd3foNx2EwoBe14MbFyJKr0PLJvFrMBQamhlWX31hknK3y9m7F3cIopvO2kIngxuVgZ/c3XOMnJysZcmgeVvouinM2GCcJF5k54InnSO0JJ0g4taICxSdD1NbXw4aVfuPXY2loCOKwXAsHW+vRvIu5yBYsAXeOX1J7LwWwVHOTLjQDRyIwgAsot1J4dr3tRO1u3s72SospfgKrMJdMYtrSJ6zvRQTEDXZcyk3fqtElG55syIjePTyPVPDGCGHVvaqOCWvYDXnsFAy9L3gVg8HaLMerTRuSzj6HjRmyZNheBBZkDOTRmc6yaJVhK/+NCpXgPsW3xyAX6ZGQ44NOAyn9U49Jz5VIUpEfXTK/hDaJeMgl/HmLcfxbBara5U+J5xi9IvwTcMMzxxN/sm/BjLc+34gP33ChIncbfHleQbbQvS6JMkySTA2PCbI/vwYonIZnymVtA3c4fC5zso+ZgTyvnxZkeJdDRPjTUtP6DFIAxMbIotg2e93CXfUp4ciADmTWa4IbuP3n602bqsqzTldZAt7UzolvY0gnTcmZWJC8dCoZhebkdcf9hd+jW/HdVo/YM6s39d1Mqm7PnG2dsXFSCn+yg1redbnDTPpUVi1+T1xd6dGeM7GddroA/qyNLl9dvdvCUGQvRL7BIFQFUZYXRdx27OAStt+iqORvuibZWfLufrRJVM6AoyJNpRo4rALSdtAcfW8d4HJGPEaP1cxl6ErnQz+yDbv+zRMTFCJiuPTJRDXD+ir8hz+eChUN323YpgVJ0Qjl9oqEj9H3SKORfnFaq0337C3oyz0eQ5PedG/d78nJzRP+BfQIOFMDzPSJ40yg+MAgX0P6ZPOiBIW7c/i2j6TQhVyeEUzsjRMYMMiGQl/lgTz9D6Kc/WP4tzbzhRb0Icoy5+sZRiap1rQFjaOVzGUEOXgMoME9voaumyWcTskYTxGdil9CvKBKsHCFx8iZ63V1xcmT2JnOVuYEAqOwD6bSc6KhJznv+nSyG7HNY+ycCXP1NBoG5Z8QgXEcJxUMl0SDUaMAqM4K/NL+ZiQHDbDL38U9eBa9zYaG7xronBtZ7ieC2yMOcMfz4tSvATwPeH+qlTOJQjBtFEzHkFV84bUdVYLaMj8/oM+rVU/4hZCpXR42AXjhfEZBT2M4YZv9ciCjNAo63zbfTv2zt7A6ZYVUkRFW3mRQw0EP7bmK8w4BcVzhy2U0zaJqlBAbc1i/4A+0lmSnyKBISJRF4lrGz1dIsCpZ5AeuDopJNc59Rb7viBjmnA5rBqdrxPhNnReYbJd2k3g7YPAV21Hx4wf7oUsVn8Mu6dgmChDCc1IEc9jxSnHYCWqlCA7YBeUtXTXIJf2qe7knGliksYKnYfX9RnXdeDoIbmKWGsV2mnK+oJPzOlF46TC391bf9GBe8T2rvcXJINCfZBmS60iO+5Yo2NNJQi+Qc9SebaaygxTZOj6rIbNwzdhDEUYCG8zfS9KmEhZKfcz5+9oCIG6mM8oh7q79yxzDIzdpaotBKCgJ9M8jtC/Ee5ZI8adPdXMkB1EEzaGWZBuBvzecpPmTyhzpKBy8FB0kKhEOjY0/utP7JAJKpId0xWuDDsFlSsbCqPgb4wbUqID7Qxu6FUJ1QGCxGYA+u/NXFQesgGrYlWKdm0zY62gtlUv89zV1PwQwB4TNtP16MrfZAuYhqgR2xJ7ON7tWJ49lVyjB5NbzlCGelLKJIkoicwMz1CSQ8b9SO2qk+WMWUPnXqCsHBSU7ews5rZ8ccw539tfEBj9UNPUqW30tjb9BIc5q0ypPa15S8ucZOGEpSGyRLaf8SdSxw1JDsq0vYF04PoWvvYyAIAVNl6ACzWEnCPSzVAb2orLKO2McQpRAY4I762BRDhBt0R6a1Qm9Hx9g0gUfQE6iXBniPe81OUTKzGHNKxHzV2sP3HgVlBmB2M3N2tJTzb65XnRGKLGOgMe2/eVvLj54lK4MRe5vTJG1QvZUKbxnK0YdMNE/N/eTPwJ3tB7tMyVVVDEUQpzKNtWqrbKvtQcxG1Dy42DjnsCW+DNlXdgmIKcG8ZpJT9vTihoR2UAK1ZG1WPhVF2oNNvQGU3z3hIQ8VNmdu0EMJlEu6v4iTlLYi3E68RpLs8Eq1d6csi6nKrJRssSwsm8ApR/yO/p9c7dYj4EsfcwhxzsfgLdpu8SKZUUgHkSs+KWA2F3fHUawrHUZvl4xdkDqC/S4vi8CweW7ed/VvuriZXHgljCahrwhe2YRn0rZl3Kvsc3wz2L8XaRhusY1lT5Xy8rqsCiKFcuevI7DUCV2/c3uuhY08+5+qTihQwGlrJTQo8iTNr39o6lcoalqyKYeXWoQEKpUQP/SvTT5qhq+7NdJoB+q9JkU+q0aEQwqBOF+rdmRUeYEMWXmPiJ7NndcQGuAJg+M5pnbB25DUv2zP2Xqj/PjYypAJMMavI7YgoIlZ6VZ/L1yqU+PlABLp7+A93JgpG0hv221lEPIWY4+RNr3yyhPnCxtGA8obgUDu/6FIHqq+hxm+GfZx2DI2TQjgQs5yJiUyIVoXbmjjoBX0axEn1x3xsa7YlGVeFw1jeqFbgdIFN+KInG4kpJVd07c4BLJiITZFodHExoFD65tsX1SLXpZgdoljKwDo2DkacLCLiaV8PShqJEjo58uXdCu676mtSePbGyW0KZigAPGEpUEZ6zc1l9cZXjeDi2aLJpl6sphMR/B5aiIz6J7Afj3feUuq5qxxFHQC8jR1C1hPV7ZxF7Sub+U5iB+ynvUkt4iJd7kxJDARVbZPBbUSb9/ny0nBbzZmkRE6oi+0ocWxaH4ZnVrsL/NgnFPwKuG2IwbNCHls26kUeON7qS/+j0PLAXzBghwiRgBku1clT/tM30AS1mvJ6cKDjjLPMei7GwGHaJFfQqEjjikb7ktX5O1jVMlZTrNGliwOK1fTh3jE9b5K9AppT5IFuPxhbJ97+HMazBEPtMA9aZBIKXNFIvdPPCs0DHt05HzygjrejibsBA/SS2F+gSlANRlkrJinMIpt/gdlvUbjaxFrMupGmVCoMDfRDrxO053FTh8nto2pA2ActBghuqLM8p91U5FtVhXU+FI8whYX5WdWMmWc2E2wGzFz1aCKYJIC/qr4xzN305xQLxAVb2n0BQedGI+j38cc0ECk1NxJ2isVKvmhk5RyzSc6EPzB1884xko7roUM7NOu0FiPw+Zu4R8OGoHRYqsigkTRxlmL19aGEbBbdK9TmGBvwCd307SHj2GojSWN7DL9olp1+VMMYQ9UG8DTX47r23qkXZ4z3ctQl86rRjpzdj+70XvZb+h0FzgnyJmYSHxIIn2FWNYmvwPjyiBUgHYP5RoHhSJoeI6W+nkFnHijreTncsonIU5FKlqHQFGzzdc8s9U5sfrMFtR1SUYFYWj3C8KP0oQwiXZcn3AcqPkTqVU0o5kRZ2+QS+fJP1ozNeh6hKJSpUVSb2LZ9329cfBOPAJ7u8zYUqJZ8CIzIa26Qy5ADf5bco2Z18IcLHAulDYBXxaBCm2DXpryNEQMYWmMTHA0mVpIFVkmU5dfnNQykdZiAXU1l+Fw6kIjrMJ9AgF0xWiaZnOyTehWtuxU47hvUm8B2A9ociq2x5aFOxazc3YG5IB7IZmXercFhEWIMzMw63jvREmRjCT5ou+MIjmbi1na8d0SaLUudX5pUouPbc+4stjuNveU6cNACO0s+nbAlVyZyCeRMAPk5C+11kHcwSNd8IZugXSih5eJ4xPoIW0knz0365CjhNUfz9+31qYzK0lZNMUCuf2K0vrUBB/i3T3gdXMGSeldKp3Lx+tz/bpKXTHtUzzsvdS9Gs+uMIZ1XK6AxFyeCxOJ+cU9XN1fBnLPe2JYUlJUmCu4tiwsprlamaRzZQNWlUxombEZeKC7q3mwHcZM5wU0ICwEnLfTxW0VL9N10+batqOKxQnIspanPsw1ez2cuwr/hQSPXqoP2gIkFZnmAqUKUX8GZ5ib+C60pulz4Uxz/QvZW7V2SAAGcUwS30VsW6U2Ld2v5UbOfEQCxPdOHJZw75sKgEdyVdN1FDl4JC6s8IUclP+LD6R/CXIEDhbSWuXdTsAinSZLlMH1LzCXp6Cqvih/NReD6FJezE4Hi0sUGxti+4YngNBTWhUOblVY4+ioJs/kpVyXoAksKXh+Fe1j1PG2gbHkCQQWWCDqufQCEypj+dCoj37UreY26CogoUkVCnNUXQ5jZNFOPeXjh336gUEGzTt9qLgRwsxEJpQKH+aCWZALuJHtCVlK1WQMM6eM15EjMtRabejRb7eD3Us4WqESLYxpZ5KCobtmQDzV/4vOlvq0BSClPNORXWKygxQ2J9casayyd9DxvL77P41vt3k3fsT5PB1d6WR+6JZWwYJGZTdxyDyiFJDCKV9TuCeGkZQ26g1V0sV/H5a1xciwxOCNt7GgQOajs3aR4wpXxg4GbU0nOR0c9Ii/Sn27VMt4BqnAj5W4fx8q4ecJlPHlG3tSjqKSUsP0rlyg7JRFXcxCUGv7QMYc2K9WLvLEHbBOcM/ZD87o+UaQ3CvTwOkQTDq8hUeOBRxcerQV5Xi6Y+Hh6Vg4aeMpoGdUV7xXbw5oVh/mkSLP70aWsGQ3UbqZLFHrxQzLeDFkYJX6q069Lp/1X+lGTY+5ykXDRtK1n+GarP5tNWi4nd81eFXdracJWwcYk2GA6MbdjMnoaTrfSHXO3EXgrlq6ko5DABSrMg+9kF88aW5LAVOxGADYFS8bniGvdKVXnEhhQDJVCYKqqWKYGpAek5BGeVRWSbwLCKdQ5BcBnn+oEsmp46uK3k8KO72Pn+1hPMbgE6xWxVYPqAe7HVPPjNRiQS6cQGOxU1gdlAuEJ4V7ip4o+TgDM2/M4bthC6c4SBMQaMfRZfL5ko/uf3U2MXch54RJ2/LQRAy3AHiOI6enjY+L88VIvjU+hnmwro8yEflSD4tEMeFIkrxEW19Gycl1BDXpDVbs9nrU5MMIGx6QxCFw8FibHOtcRcI71o8s+OvDCQFsw7ZVMslGVDaprGZZmJ2j4uTgxrn15ihGv020yixBNktFCYgTyPlxA1f36ciarunxld8CPUVUPV/D/XFX5s/Neg2cdPqmSlO/fpnXxz4UJnIlB6hSl82wNGKJud1KoVyDHmmjI+EKBSUO7kNuvrQ/fY3duE75BX/HUAeUiLFKBZ1O2/mThw8t0Wq782ApG12/Jvza+94ENybWDDpLLmTddfEP7cYjFtZZONpGuxNkP8FAAD//w==" ]; // Test that fixes #191501. Ensures compressed data can be streamed out correctly. #[test] fn test_flatestream_decodes_191501() { let mut dec = ClientMessageDecoder::new_compressed(); let mut len = 0; for b in TEST_191501_BUFS { let b = general_purpose::STANDARD .decode(b) .expect("expected no decode error"); let s = dec.decode(&b).expect("expected no decompress error"); len += s.len(); } assert_eq!(len, 265 + 101 + 10370); } } ================================================ FILE: cli/src/tunnels/wsl_detect.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::log; #[cfg(not(windows))] pub fn is_wsl_installed(_log: &log::Logger) -> bool { false } #[cfg(windows)] pub fn is_wsl_installed(log: &log::Logger) -> bool { use std::path::PathBuf; use crate::util::command::new_std_command; let system32 = { let sys_root = match std::env::var("SystemRoot") { Ok(s) => s, Err(_) => return false, }; let is_32_on_64 = std::env::var("PROCESSOR_ARCHITEW6432").is_ok(); let mut system32 = PathBuf::from(sys_root); system32.push(if is_32_on_64 { "Sysnative" } else { "System32" }); system32 }; // Windows builds < 22000 let mut maybe_lxss = system32.join("lxss"); maybe_lxss.push("LxssManager.dll"); if maybe_lxss.exists() { trace!(log, "wsl availability detected via lxss"); return true; } // Windows builds >= 22000 let maybe_wsl = system32.join("wsl.exe"); if maybe_wsl.exists() { if let Ok(s) = new_std_command(maybe_wsl).arg("--status").output() { if s.status.success() { trace!(log, "wsl availability detected via subprocess"); return true; } } } trace!(log, "wsl not detected"); false } ================================================ FILE: cli/src/tunnels.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ pub mod code_server; pub mod dev_tunnels; pub mod legal; pub mod local_forwarding; pub mod paths; pub mod protocol; pub mod shutdown_signal; pub mod singleton_client; pub mod singleton_server; mod challenge; mod control_server; mod nosleep; #[cfg(target_os = "linux")] mod nosleep_linux; #[cfg(target_os = "macos")] mod nosleep_macos; #[cfg(target_os = "windows")] mod nosleep_windows; mod port_forwarder; mod server_bridge; mod server_multiplexer; mod service; #[cfg(target_os = "linux")] mod service_linux; #[cfg(target_os = "macos")] mod service_macos; #[cfg(target_os = "windows")] mod service_windows; mod socket_signal; mod wsl_detect; pub use control_server::{serve, serve_stream, AuthRequired, Next, ServeStreamParams}; pub use nosleep::SleepInhibitor; pub use service::{ create_service_manager, ServiceContainer, ServiceManager, SERVICE_LOG_FILE_NAME, }; ================================================ FILE: cli/src/update_service.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{fmt, path::Path}; use serde::{Deserialize, Serialize}; use crate::{ constants::VSCODE_CLI_UPDATE_ENDPOINT, debug, log, options, spanf, util::{ errors::{wrap, AnyError, CodeError, WrappedError}, http::{BoxedHttp, SimpleResponse}, io::ReportCopyProgress, tar::{self, has_gzip_header}, zipper, }, }; /// Implementation of the VS Code Update service for use in the CLI. #[derive(Clone)] pub struct UpdateService { client: BoxedHttp, log: log::Logger, } /// Describes a specific release, can be created manually or returned from the update service. #[derive(Clone, Eq, PartialEq)] pub struct Release { pub name: String, pub platform: Platform, pub target: TargetKind, pub quality: options::Quality, pub commit: String, } impl std::fmt::Display for Release { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{} (commit {})", self.name, self.commit) } } #[derive(Deserialize)] struct UpdateServerVersion { pub version: String, pub name: String, } fn quality_download_segment(quality: options::Quality) -> &'static str { match quality { options::Quality::Stable => "stable", options::Quality::Insiders => "insider", options::Quality::Exploration => "exploration", } } fn get_update_endpoint() -> Result<&'static str, CodeError> { VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(|| CodeError::UpdatesNotConfigured("no service url")) } impl UpdateService { pub fn new(log: log::Logger, http: BoxedHttp) -> Self { UpdateService { client: http, log } } pub async fn get_release_by_semver_version( &self, platform: Platform, target: TargetKind, quality: options::Quality, version: &str, ) -> Result { let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; let download_url = format!( "{}/api/versions/{}/{}/{}", update_endpoint, version, download_segment, quality_download_segment(quality), ); let mut response = spanf!( self.log, self.log.span("server.version.resolve"), self.client.make_request("GET", download_url) )?; if !response.status_code.is_success() { return Err(response.into_err().await.into()); } let res = response.json::().await?; debug!(self.log, "Resolved version {} to {}", version, res.version); Ok(Release { target, platform, quality, name: res.name, commit: res.version, }) } /// Gets the latest commit for the target of the given quality. pub async fn get_latest_commit( &self, platform: Platform, target: TargetKind, quality: options::Quality, ) -> Result { let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; let download_url = format!( "{}/api/latest/{}/{}", update_endpoint, download_segment, quality_download_segment(quality), ); let mut response = spanf!( self.log, self.log.span("server.version.resolve"), self.client.make_request("GET", download_url) )?; if !response.status_code.is_success() { return Err(response.into_err().await.into()); } let res = response.json::().await?; debug!(self.log, "Resolved quality {} to {}", quality, res.version); Ok(Release { target, platform, quality, name: res.name, commit: res.version, }) } /// Gets the download stream for the release. pub async fn get_download_stream(&self, release: &Release) -> Result { let update_endpoint = get_update_endpoint()?; let download_segment = release .target .download_segment(release.platform) .ok_or_else(|| CodeError::UnsupportedPlatform(release.platform.to_string()))?; let download_url = format!( "{}/commit:{}/{}/{}", update_endpoint, release.commit, download_segment, quality_download_segment(release.quality), ); let response = self.client.make_request("GET", download_url).await?; if !response.status_code.is_success() { return Err(response.into_err().await.into()); } Ok(response) } } pub fn unzip_downloaded_release( compressed_file: &Path, target_dir: &Path, reporter: T, ) -> Result<(), WrappedError> where T: ReportCopyProgress, { match has_gzip_header(compressed_file) { Ok((f, true)) => tar::decompress_tarball(f, target_dir, reporter), Ok((f, false)) => zipper::unzip_file(f, target_dir, reporter), Err(e) => Err(wrap(e, "error checking for gzip header")), } } #[derive(Eq, PartialEq, Copy, Clone)] pub enum TargetKind { Server, Archive, Web, Cli, } impl TargetKind { fn download_segment(&self, platform: Platform) -> Option { match *self { TargetKind::Server => Some(platform.headless()), TargetKind::Archive => platform.archive(), TargetKind::Web => Some(platform.web()), TargetKind::Cli => Some(platform.cli()), } } } #[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] pub enum Platform { LinuxAlpineX64, LinuxAlpineARM64, LinuxX64, LinuxX64Legacy, LinuxARM64, LinuxARM64Legacy, LinuxARM32, LinuxARM32Legacy, DarwinX64, DarwinARM64, WindowsX64, WindowsX86, WindowsARM64, } impl Platform { pub fn archive(&self) -> Option { match self { Platform::LinuxX64 => Some("linux-x64".to_owned()), Platform::LinuxARM64 => Some("linux-arm64".to_owned()), Platform::LinuxARM32 => Some("linux-armhf".to_owned()), Platform::DarwinX64 => Some("darwin".to_owned()), Platform::DarwinARM64 => Some("darwin-arm64".to_owned()), Platform::WindowsX64 => Some("win32-x64-archive".to_owned()), Platform::WindowsX86 => Some("win32-archive".to_owned()), Platform::WindowsARM64 => Some("win32-arm64-archive".to_owned()), _ => None, } } pub fn headless(&self) -> String { match self { Platform::LinuxAlpineARM64 => "server-alpine-arm64", Platform::LinuxAlpineX64 => "server-linux-alpine", Platform::LinuxX64 => "server-linux-x64", Platform::LinuxX64Legacy => "server-linux-legacy-x64", Platform::LinuxARM64 => "server-linux-arm64", Platform::LinuxARM64Legacy => "server-linux-legacy-arm64", Platform::LinuxARM32 => "server-linux-armhf", Platform::LinuxARM32Legacy => "server-linux-legacy-armhf", Platform::DarwinX64 => "server-darwin", Platform::DarwinARM64 => "server-darwin-arm64", Platform::WindowsX64 => "server-win32-x64", Platform::WindowsX86 => "server-win32", Platform::WindowsARM64 => "server-win32-arm64", } .to_owned() } pub fn cli(&self) -> String { match self { Platform::LinuxAlpineARM64 => "cli-alpine-arm64", Platform::LinuxAlpineX64 => "cli-alpine-x64", Platform::LinuxX64 => "cli-linux-x64", Platform::LinuxX64Legacy => "cli-linux-x64", Platform::LinuxARM64 => "cli-linux-arm64", Platform::LinuxARM64Legacy => "cli-linux-arm64", Platform::LinuxARM32 => "cli-linux-armhf", Platform::LinuxARM32Legacy => "cli-linux-armhf", Platform::DarwinX64 => "cli-darwin-x64", Platform::DarwinARM64 => "cli-darwin-arm64", Platform::WindowsARM64 => "cli-win32-arm64", Platform::WindowsX64 => "cli-win32-x64", Platform::WindowsX86 => "cli-win32", } .to_owned() } pub fn web(&self) -> String { format!("{}-web", self.headless()) } pub fn env_default() -> Option { if cfg!(all( target_os = "linux", target_arch = "x86_64", target_env = "musl" )) { Some(Platform::LinuxAlpineX64) } else if cfg!(all( target_os = "linux", target_arch = "aarch64", target_env = "musl" )) { Some(Platform::LinuxAlpineARM64) } else if cfg!(all(target_os = "linux", target_arch = "x86_64")) { Some(Platform::LinuxX64) } else if cfg!(all(target_os = "linux", target_arch = "arm")) { Some(Platform::LinuxARM32) } else if cfg!(all(target_os = "linux", target_arch = "aarch64")) { Some(Platform::LinuxARM64) } else if cfg!(all(target_os = "macos", target_arch = "x86_64")) { Some(Platform::DarwinX64) } else if cfg!(all(target_os = "macos", target_arch = "aarch64")) { Some(Platform::DarwinARM64) } else if cfg!(all(target_os = "windows", target_arch = "x86_64")) { Some(Platform::WindowsX64) } else if cfg!(all(target_os = "windows", target_arch = "x86")) { Some(Platform::WindowsX86) } else if cfg!(all(target_os = "windows", target_arch = "aarch64")) { Some(Platform::WindowsARM64) } else { None } } } impl fmt::Display for Platform { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match self { Platform::LinuxAlpineARM64 => "LinuxAlpineARM64", Platform::LinuxAlpineX64 => "LinuxAlpineX64", Platform::LinuxX64 => "LinuxX64", Platform::LinuxX64Legacy => "LinuxX64Legacy", Platform::LinuxARM64 => "LinuxARM64", Platform::LinuxARM64Legacy => "LinuxARM64Legacy", Platform::LinuxARM32 => "LinuxARM32", Platform::LinuxARM32Legacy => "LinuxARM32Legacy", Platform::DarwinX64 => "DarwinX64", Platform::DarwinARM64 => "DarwinARM64", Platform::WindowsX64 => "WindowsX64", Platform::WindowsX86 => "WindowsX86", Platform::WindowsARM64 => "WindowsARM64", }) } } ================================================ FILE: cli/src/util/app_lock.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ #[cfg(windows)] use std::{io, ptr}; #[cfg(windows)] use winapi::{ shared::winerror::ERROR_ALREADY_EXISTS, um::{handleapi::CloseHandle, synchapi::CreateMutexA, winnt::HANDLE}, }; use super::errors::CodeError; pub struct AppMutex { #[cfg(windows)] handle: HANDLE, } #[cfg(windows)] // handle is thread-safe, mark it so with this unsafe impl Send for AppMutex {} impl AppMutex { #[cfg(unix)] pub fn new(_name: &str) -> Result { Ok(Self {}) } #[cfg(windows)] pub fn new(name: &str) -> Result { use std::ffi::CString; let cname = CString::new(name).unwrap(); let handle = unsafe { CreateMutexA(ptr::null_mut(), 0, cname.as_ptr() as _) }; if !handle.is_null() { return Ok(Self { handle }); } let err = io::Error::last_os_error(); let raw = err.raw_os_error(); // docs report it should return ERROR_IO_PENDING, but in my testing it actually // returns ERROR_LOCK_VIOLATION. Or maybe winapi is wrong? if raw == Some(ERROR_ALREADY_EXISTS as i32) { return Err(CodeError::AppAlreadyLocked(name.to_string())); } Err(CodeError::AppLockFailed(err)) } } impl Drop for AppMutex { fn drop(&mut self) { #[cfg(windows)] unsafe { CloseHandle(self.handle) }; } } ================================================ FILE: cli/src/util/command.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::errors::CodeError; use std::{ borrow::Cow, ffi::OsStr, process::{Output, Stdio}, }; use tokio::process::Command; pub async fn capture_command_and_check_status( command_str: impl AsRef, args: &[impl AsRef], ) -> Result { let output = capture_command(&command_str, args).await?; check_output_status(output, || { format!( "{} {}", command_str.as_ref().to_string_lossy(), args.iter() .map(|a| a.as_ref().to_string_lossy()) .collect::>>() .join(" ") ) }) } pub fn check_output_status( output: Output, cmd_str: impl FnOnce() -> String, ) -> Result { if !output.status.success() { return Err(CodeError::CommandFailed { command: cmd_str(), code: output.status.code().unwrap_or(-1), output: String::from_utf8_lossy(if output.stderr.is_empty() { &output.stdout } else { &output.stderr }) .into(), }); } Ok(output) } pub async fn capture_command( command_str: A, args: I, ) -> Result where A: AsRef, I: IntoIterator, S: AsRef, { new_tokio_command(&command_str) .args(args) .stdin(Stdio::null()) .stdout(Stdio::piped()) .output() .await .map_err(|e| CodeError::CommandFailed { command: command_str.as_ref().to_string_lossy().to_string(), code: -1, output: e.to_string(), }) } /// Makes a new Command, setting flags to avoid extra windows on win32 #[cfg(windows)] pub fn new_tokio_command(exe: impl AsRef) -> Command { let mut p = tokio::process::Command::new(exe); p.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW); p } /// Makes a new Command, setting flags to avoid extra windows on win32 #[cfg(not(windows))] pub fn new_tokio_command(exe: impl AsRef) -> Command { tokio::process::Command::new(exe) } /// Makes a new command to run the target script. For windows, ensures it's run /// in a cmd.exe context. #[cfg(windows)] pub fn new_script_command(script: impl AsRef) -> Command { let mut cmd = new_tokio_command("cmd"); cmd.arg("/Q"); cmd.arg("/C"); cmd.arg(script); cmd } /// Makes a new command to run the target script. For windows, ensures it's run /// in a cmd.exe context. #[cfg(not(windows))] pub fn new_script_command(script: impl AsRef) -> Command { new_tokio_command(script) // it's assumed scripts are already +x and don't need extra handling } /// Makes a new Command, setting flags to avoid extra windows on win32 #[cfg(windows)] pub fn new_std_command(exe: impl AsRef) -> std::process::Command { let mut p = std::process::Command::new(exe); std::os::windows::process::CommandExt::creation_flags( &mut p, winapi::um::winbase::CREATE_NO_WINDOW, ); p } /// Makes a new Command, setting flags to avoid extra windows on win32 #[cfg(not(windows))] pub fn new_std_command(exe: impl AsRef) -> std::process::Command { std::process::Command::new(exe) } /// Kills and processes and all of its children. #[cfg(windows)] pub async fn kill_tree(process_id: u32) -> Result<(), CodeError> { capture_command("taskkill", &["/t", "/pid", &process_id.to_string()]).await?; Ok(()) } /// Kills and processes and all of its children. #[cfg(not(windows))] pub async fn kill_tree(process_id: u32) -> Result<(), CodeError> { use futures::future::join_all; use tokio::io::{AsyncBufReadExt, BufReader}; async fn kill_single_pid(process_id_str: String) { capture_command("kill", &[&process_id_str]).await.ok(); } // Rusty version of https://github.com/microsoft/vscode-js-debug/blob/main/src/targets/node/terminateProcess.sh let parent_id = process_id.to_string(); let mut prgrep_cmd = Command::new("pgrep") .arg("-P") .arg(&parent_id) .stdin(Stdio::null()) .stdout(Stdio::piped()) .spawn() .map_err(|e| CodeError::CommandFailed { command: format!("pgrep -P {parent_id}"), code: -1, output: e.to_string(), })?; let mut kill_futures = vec![tokio::spawn( async move { kill_single_pid(parent_id).await }, )]; if let Some(stdout) = prgrep_cmd.stdout.take() { let mut reader = BufReader::new(stdout).lines(); while let Some(line) = reader.next_line().await.unwrap_or(None) { kill_futures.push(tokio::spawn(async move { kill_single_pid(line).await })) } } join_all(kill_futures).await; prgrep_cmd.kill().await.ok(); Ok(()) } ================================================ FILE: cli/src/util/errors.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::{ constants::{APPLICATION_NAME, CONTROL_PORT, DOCUMENTATION_URL, QUALITYLESS_PRODUCT_NAME}, rpc::ResponseError, }; use std::fmt::Display; use thiserror::Error; // Wraps another error with additional info. #[derive(Debug, Clone)] pub struct WrappedError { message: String, original: String, } impl std::fmt::Display for WrappedError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}: {}", self.message, self.original) } } impl std::error::Error for WrappedError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } impl WrappedError { // fn new(original: Box, message: String) -> WrappedError { // WrappedError { message, original } // } } impl From for WrappedError { fn from(e: reqwest::Error) -> WrappedError { WrappedError { message: format!( "error requesting {}", e.url().map_or("", |u| u.as_str()) ), original: format!("{e}"), } } } pub fn wrapdbg(original: T, message: S) -> WrappedError where T: std::fmt::Debug, S: Into, { WrappedError { message: message.into(), original: format!("{original:?}"), } } pub fn wrap(original: T, message: S) -> WrappedError where T: Display, S: Into, { WrappedError { message: message.into(), original: format!("{original}"), } } // Error generated by an unsuccessful HTTP response #[derive(Debug)] pub struct StatusError { pub url: String, pub status_code: u16, pub body: String, } impl std::fmt::Display for StatusError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "error requesting {}: {} {}", self.url, self.status_code, self.body ) } } impl StatusError { pub async fn from_res(res: reqwest::Response) -> Result { let status_code = res.status().as_u16(); let url = res.url().to_string(); let body = res.text().await.map_err(|e| { wrap( e, format!("failed to read response body on {status_code} code from {url}"), ) })?; Ok(StatusError { url, status_code, body, }) } } // When the provided connection token doesn't match the one used to set up the original VS Code Server // This is most likely due to a new user joining. #[derive(Debug)] pub struct MismatchConnectionToken(pub String); impl std::fmt::Display for MismatchConnectionToken { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.0) } } // When the VS Code server has an unrecognized extension (rather than zip or gz) #[derive(Debug)] pub struct InvalidServerExtensionError(pub String); impl std::fmt::Display for InvalidServerExtensionError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "invalid server extension '{}'", self.0) } } // When the tunnel fails to open #[derive(Debug, Clone)] pub struct DevTunnelError(pub String); impl std::fmt::Display for DevTunnelError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "could not open tunnel: {}", self.0) } } impl std::error::Error for DevTunnelError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } // When the server was downloaded, but the entrypoint scripts don't exist. #[derive(Debug)] pub struct MissingEntrypointError(); impl std::fmt::Display for MissingEntrypointError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Missing entrypoints in server download. Most likely this is a corrupted download. Please retry") } } #[derive(Debug)] pub struct SetupError(pub String); impl std::fmt::Display for SetupError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{}\n\nMore info at {}/remote/linux", DOCUMENTATION_URL.unwrap_or(""), self.0 ) } } #[derive(Debug)] pub struct NoHomeForLauncherError(); impl std::fmt::Display for NoHomeForLauncherError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "No $HOME variable was found in your environment. Either set it, or specify a `--data-dir` manually when invoking the launcher.", ) } } #[derive(Debug)] pub struct InvalidTunnelName(pub String); impl std::fmt::Display for InvalidTunnelName { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &self.0) } } #[derive(Debug)] pub struct TunnelCreationFailed(pub String, pub String); impl std::fmt::Display for TunnelCreationFailed { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "Could not create tunnel with name: {}\nReason: {}", &self.0, &self.1 ) } } #[derive(Debug)] pub struct TunnelHostFailed(pub String); impl std::fmt::Display for TunnelHostFailed { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &self.0) } } #[derive(Debug)] pub struct ExtensionInstallFailed(pub String); impl std::fmt::Display for ExtensionInstallFailed { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Extension install failed: {}", &self.0) } } #[derive(Debug)] pub struct MismatchedLaunchModeError(); impl std::fmt::Display for MismatchedLaunchModeError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "A server is already running, but it was not launched in the same listening mode (port vs. socket) as this request") } } #[derive(Debug)] pub struct NoAttachedServerError(); impl std::fmt::Display for NoAttachedServerError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "No server is running") } } #[derive(Debug)] pub struct RefreshTokenNotAvailableError(); impl std::fmt::Display for RefreshTokenNotAvailableError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Refresh token not available, authentication is required") } } #[derive(Debug)] pub struct NoInstallInUserProvidedPath(pub String); impl std::fmt::Display for NoInstallInUserProvidedPath { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "No {} installation could be found in {}. You can run `{} --use-quality=stable` to switch to the latest stable version of {}.", QUALITYLESS_PRODUCT_NAME, self.0, APPLICATION_NAME, QUALITYLESS_PRODUCT_NAME ) } } #[derive(Debug)] pub struct InvalidRequestedVersion(); impl std::fmt::Display for InvalidRequestedVersion { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "The reqested version is invalid, expected one of 'stable', 'insiders', version number (x.y.z), or absolute path.", ) } } #[derive(Debug)] pub struct UserCancelledInstallation(); impl std::fmt::Display for UserCancelledInstallation { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Installation aborted.") } } #[derive(Debug)] pub struct CannotForwardControlPort(); impl std::fmt::Display for CannotForwardControlPort { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Cannot forward or unforward port {CONTROL_PORT}.") } } #[derive(Debug)] pub struct ServerHasClosed(); impl std::fmt::Display for ServerHasClosed { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Request cancelled because the server has closed") } } #[derive(Debug)] pub struct ServiceAlreadyRegistered(); impl std::fmt::Display for ServiceAlreadyRegistered { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Already registered the service. Run `{APPLICATION_NAME} tunnel service uninstall` to unregister it first") } } #[derive(Debug)] pub struct WindowsNeedsElevation(pub String); impl std::fmt::Display for WindowsNeedsElevation { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { writeln!(f, "{}", self.0)?; writeln!(f)?; writeln!(f, "You may need to run this command as an administrator:")?; writeln!(f, " 1. Open the start menu and search for Powershell")?; writeln!(f, " 2. Right click and 'Run as administrator'")?; if let Ok(exe) = std::env::current_exe() { writeln!( f, " 3. Run &'{}' '{}'", exe.display(), std::env::args().skip(1).collect::>().join("' '") ) } else { writeln!(f, " 3. Run the same command again",) } } } #[derive(Debug)] pub struct InvalidRpcDataError(pub String); impl std::fmt::Display for InvalidRpcDataError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "parse error: {}", self.0) } } #[derive(Debug)] pub struct CorruptDownload(pub String); impl std::fmt::Display for CorruptDownload { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "Error updating the {} CLI: {}", QUALITYLESS_PRODUCT_NAME, self.0 ) } } #[derive(Debug)] pub struct MissingHomeDirectory(); impl std::fmt::Display for MissingHomeDirectory { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Could not find your home directory. Please ensure this command is running in the context of an normal user.") } } #[derive(Debug)] pub struct OAuthError { pub error: String, pub error_description: Option, } impl std::fmt::Display for OAuthError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "Error getting authorization: {} {}", self.error, self.error_description.as_deref().unwrap_or("") ) } } // Makes an "AnyError" enum that contains any of the given errors, in the form // `enum AnyError { FooError(FooError) }` (when given `makeAnyError!(FooError)`). // Useful to easily deal with application error types without making tons of "From" // clauses. macro_rules! makeAnyError { ($($e:ident),*) => { #[derive(Debug)] #[allow(clippy::enum_variant_names)] pub enum AnyError { $($e($e),)* } impl std::fmt::Display for AnyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { $(AnyError::$e(ref e) => e.fmt(f),)* } } } impl std::error::Error for AnyError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } $(impl From<$e> for AnyError { fn from(e: $e) -> AnyError { AnyError::$e(e) } })* }; } #[derive(Debug)] pub struct DbusConnectFailedError(pub String); impl Display for DbusConnectFailedError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut str = String::new(); str.push_str("Error creating dbus session. This command uses systemd for managing services, you should check that systemd is installed and under your user."); if std::env::var("WSL_DISTRO_NAME").is_ok() { str.push_str("\n\nTo enable systemd on WSL, check out: https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/.\n\n"); } str.push_str("If running `systemctl status` works, systemd is ok, but your session dbus may not be. You might need to:\n\n- Install the `dbus-user-session` package, and reboot if it was not installed\n- Start the user dbus session with `systemctl --user enable dbus --now`.\n\nThe error encountered was: "); str.push_str(&self.0); str.push('\n'); write!(f, "{str}") } } /// Internal errors in the VS Code CLI. /// Note: other error should be migrated to this type gradually #[derive(Error, Debug)] pub enum CodeError { #[error("could not connect to socket/pipe: {0:?}")] AsyncPipeFailed(std::io::Error), #[error("could not listen on socket/pipe: {0:?}")] AsyncPipeListenerFailed(std::io::Error), #[error("could not create singleton lock file: {0:?}")] SingletonLockfileOpenFailed(std::io::Error), #[error("could not read singleton lock file: {0:?}")] SingletonLockfileReadFailed(rmp_serde::decode::Error), #[error("the process holding the singleton lock file (pid={0}) exited")] SingletonLockedProcessExited(u32), #[error("no tunnel process is currently running")] NoRunningTunnel, #[error("rpc call failed: {0:?}")] TunnelRpcCallFailed(ResponseError), #[cfg(windows)] #[error("the windows app lock {0} already exists")] AppAlreadyLocked(String), #[cfg(windows)] #[error("could not get windows app lock: {0:?}")] AppLockFailed(std::io::Error), #[error("failed to run command \"{command}\" (code {code}): {output}")] CommandFailed { command: String, code: i32, output: String, }, #[error("platform not currently supported: {0}")] UnsupportedPlatform(String), #[error("This machine does not meet {name}'s prerequisites, expected either...\n{bullets}")] PrerequisitesFailed { name: &'static str, bullets: String }, #[error("failed to spawn process: {0:?}")] ProcessSpawnFailed(std::io::Error), #[error("failed to handshake spawned process: {0:?}")] ProcessSpawnHandshakeFailed(std::io::Error), #[error("download appears corrupted, please retry ({0})")] CorruptDownload(&'static str), #[error("port forwarding is not available in this context")] PortForwardingNotAvailable, #[error("'auth' call required")] ServerAuthRequired, #[error("challenge not yet issued")] AuthChallengeNotIssued, #[error("challenge token is invalid")] AuthChallengeBadToken, #[error("unauthorized client refused")] AuthMismatch, #[error("keyring communication timed out after 5s")] KeyringTimeout, #[error("no host is connected to the tunnel relay")] NoTunnelEndpoint, #[error("could not parse `host`: {0}")] InvalidHostAddress(std::net::AddrParseError), #[error("could not start server on the given host/port: {0}")] CouldNotListenOnInterface(hyper::Error), #[error( "Run this command again with --accept-server-license-terms to indicate your agreement." )] NeedsInteractiveLegalConsent, #[error("Sorry, you cannot use this CLI without accepting the terms.")] DeniedLegalConset, #[error("The server is not yet downloaded, try again shortly.")] ServerNotYetDownloaded, #[error("An error was encountered downloading the server, please retry: {0}")] ServerDownloadError(String), #[error("Updates are are not available: {0}")] UpdatesNotConfigured(&'static str), // todo: can be specialized when update service is moved to CodeErrors #[error("Could not check for update: {0}")] UpdateCheckFailed(String), #[error("Could not read connection token file: {0}")] CouldNotReadConnectionTokenFile(std::io::Error), #[error("Could not write connection token file: {0}")] CouldNotCreateConnectionTokenFile(std::io::Error), #[error("A tunnel with the name {0} exists and is in-use. Please pick a different name or stop the existing tunnel.")] TunnelActiveAndInUse(String), #[error("Timed out looking for port/socket")] ServerOriginTimeout, #[error("Server exited without writing port/socket: {0}")] ServerUnexpectedExit(String), } makeAnyError!( MismatchConnectionToken, DevTunnelError, StatusError, WrappedError, InvalidServerExtensionError, MissingEntrypointError, SetupError, NoHomeForLauncherError, TunnelCreationFailed, TunnelHostFailed, InvalidTunnelName, ExtensionInstallFailed, MismatchedLaunchModeError, NoAttachedServerError, RefreshTokenNotAvailableError, NoInstallInUserProvidedPath, UserCancelledInstallation, InvalidRequestedVersion, CannotForwardControlPort, ServerHasClosed, ServiceAlreadyRegistered, WindowsNeedsElevation, CorruptDownload, MissingHomeDirectory, OAuthError, InvalidRpcDataError, CodeError, DbusConnectFailedError ); impl From for AnyError { fn from(e: reqwest::Error) -> AnyError { AnyError::WrappedError(WrappedError::from(e)) } } ================================================ FILE: cli/src/util/file_lock.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::util::errors::CodeError; use std::{fs::File, io}; pub struct FileLock { file: File, #[cfg(windows)] overlapped: winapi::um::minwinbase::OVERLAPPED, } #[cfg(windows)] // overlapped is thread-safe, mark it so with this unsafe impl Send for FileLock {} pub enum Lock { Acquired(FileLock), AlreadyLocked(File), } /// Number of locked bytes in the file. On Windows, locking prevents reads, /// but consumers of the lock may still want to read what the locking file /// as written. Thus, only PREFIX_LOCKED_BYTES are locked, and any globally- /// readable content should be written after the prefix. #[cfg(windows)] pub const PREFIX_LOCKED_BYTES: usize = 1; #[cfg(unix)] pub const PREFIX_LOCKED_BYTES: usize = 0; impl FileLock { #[cfg(windows)] pub fn acquire(file: File) -> Result { use std::os::windows::prelude::AsRawHandle; use winapi::{ shared::winerror::{ERROR_IO_PENDING, ERROR_LOCK_VIOLATION}, um::{ fileapi::LockFileEx, minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY}, }, }; let handle = file.as_raw_handle(); let (overlapped, ok) = unsafe { let mut overlapped = std::mem::zeroed(); let ok = LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, PREFIX_LOCKED_BYTES as u32, 0, &mut overlapped, ); (overlapped, ok) }; if ok != 0 { return Ok(Lock::Acquired(Self { file, overlapped })); } let err = io::Error::last_os_error(); let raw = err.raw_os_error(); // docs report it should return ERROR_IO_PENDING, but in my testing it actually // returns ERROR_LOCK_VIOLATION. Or maybe winapi is wrong? if raw == Some(ERROR_IO_PENDING as i32) || raw == Some(ERROR_LOCK_VIOLATION as i32) { return Ok(Lock::AlreadyLocked(file)); } Err(CodeError::SingletonLockfileOpenFailed(err)) } #[cfg(unix)] pub fn acquire(file: File) -> Result { use std::os::unix::io::AsRawFd; let fd = file.as_raw_fd(); let res = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) }; if res == 0 { return Ok(Lock::Acquired(Self { file })); } let err = io::Error::last_os_error(); if err.kind() == io::ErrorKind::WouldBlock { return Ok(Lock::AlreadyLocked(file)); } Err(CodeError::SingletonLockfileOpenFailed(err)) } pub fn file(&self) -> &File { &self.file } pub fn file_mut(&mut self) -> &mut File { &mut self.file } } impl Drop for FileLock { #[cfg(windows)] fn drop(&mut self) { use std::os::windows::prelude::AsRawHandle; use winapi::um::fileapi::UnlockFileEx; unsafe { UnlockFileEx( self.file.as_raw_handle(), 0, u32::MAX, u32::MAX, &mut self.overlapped, ) }; } #[cfg(unix)] fn drop(&mut self) { use std::os::unix::io::AsRawFd; unsafe { libc::flock(self.file.as_raw_fd(), libc::LOCK_UN) }; } } ================================================ FILE: cli/src/util/http.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::{ constants::get_default_user_agent, log, util::errors::{self, WrappedError}, }; use async_trait::async_trait; use core::panic; use futures::stream::TryStreamExt; use hyper::{ header::{HeaderName, CONTENT_LENGTH}, http::HeaderValue, HeaderMap, StatusCode, }; use serde::de::DeserializeOwned; use std::{io, pin::Pin, str::FromStr, sync::Arc, task::Poll}; use tokio::{ fs, io::{AsyncRead, AsyncReadExt}, sync::mpsc, }; use tokio_util::compat::FuturesAsyncReadCompatExt; use super::{ errors::{wrap, AnyError, StatusError}, io::{copy_async_progress, ReadBuffer, ReportCopyProgress}, }; pub async fn download_into_file( filename: &std::path::Path, progress: T, mut res: SimpleResponse, ) -> Result where T: ReportCopyProgress, { let mut file = fs::File::create(filename) .await .map_err(|e| errors::wrap(e, "failed to create file"))?; let content_length = res .headers .get(CONTENT_LENGTH) .and_then(|h| h.to_str().ok()) .and_then(|s| s.parse::().ok()) .unwrap_or(0); copy_async_progress(progress, &mut res.read, &mut file, content_length) .await .map_err(|e| errors::wrap(e, "failed to download file"))?; Ok(file) } pub struct SimpleResponse { pub status_code: StatusCode, pub headers: HeaderMap, pub read: Pin>, pub url: Option, } impl SimpleResponse { pub fn url_path_basename(&self) -> Option { self.url.as_ref().and_then(|u| { u.path_segments() .and_then(|s| s.last().map(|s| s.to_owned())) }) } } impl SimpleResponse { pub fn generic_error(url: &str) -> Self { let (_, rx) = mpsc::unbounded_channel(); SimpleResponse { url: url::Url::parse(url).ok(), status_code: StatusCode::INTERNAL_SERVER_ERROR, headers: HeaderMap::new(), read: Box::pin(DelegatedReader::new(rx)), } } /// Converts the response into a StatusError pub async fn into_err(mut self) -> StatusError { let mut body = String::new(); self.read.read_to_string(&mut body).await.ok(); StatusError { url: self .url .map(|u| u.to_string()) .unwrap_or_else(|| "".to_owned()), status_code: self.status_code.as_u16(), body, } } /// Deserializes the response body as JSON pub async fn json(&mut self) -> Result { let mut buf = vec![]; // ideally serde would deserialize a stream, but it does not appear that // is supported. reqwest itself reads and decodes separately like we do here: self.read .read_to_end(&mut buf) .await .map_err(|e| wrap(e, "error reading response"))?; let t = serde_json::from_slice(&buf) .map_err(|e| wrap(e, format!("error decoding json from {:?}", self.url)))?; Ok(t) } } /// *Very* simple HTTP implementation. In most cases, this will just delegate to /// the request library on the server (i.e. `reqwest`) but it can also be used /// to make update/download requests on the client rather than the server, /// similar to SSH's `remote.SSH.localServerDownload` setting. #[async_trait] pub trait SimpleHttp { async fn make_request( &self, method: &'static str, url: String, ) -> Result; } pub type BoxedHttp = Arc; // Implementation of SimpleHttp that uses a reqwest client. #[derive(Clone)] pub struct ReqwestSimpleHttp { client: reqwest::Client, } impl ReqwestSimpleHttp { pub fn new() -> Self { Self { client: reqwest::ClientBuilder::new() .user_agent(get_default_user_agent()) .build() .unwrap(), } } pub fn with_client(client: reqwest::Client) -> Self { Self { client } } } impl Default for ReqwestSimpleHttp { fn default() -> Self { Self::new() } } #[async_trait] impl SimpleHttp for ReqwestSimpleHttp { async fn make_request( &self, method: &'static str, url: String, ) -> Result { let res = self .client .request(reqwest::Method::try_from(method).unwrap(), &url) .send() .await?; Ok(SimpleResponse { status_code: res.status(), headers: res.headers().clone(), url: Some(res.url().clone()), read: Box::pin( res.bytes_stream() .map_err(|e| futures::io::Error::new(futures::io::ErrorKind::Other, e)) .into_async_read() .compat(), ), }) } } enum DelegatedHttpEvent { InitResponse { status_code: u16, headers: Vec<(String, String)>, }, Body(Vec), End, } // Handle for a delegated request that allows manually issuing and response. pub struct DelegatedHttpRequest { pub method: &'static str, pub url: String, ch: mpsc::UnboundedSender, } impl DelegatedHttpRequest { pub fn initial_response(&self, status_code: u16, headers: Vec<(String, String)>) { self.ch .send(DelegatedHttpEvent::InitResponse { status_code, headers, }) .ok(); } pub fn body(&self, chunk: Vec) { self.ch.send(DelegatedHttpEvent::Body(chunk)).ok(); } pub fn end(self) {} } impl Drop for DelegatedHttpRequest { fn drop(&mut self) { self.ch.send(DelegatedHttpEvent::End).ok(); } } /// Implementation of SimpleHttp that allows manually controlling responses. #[derive(Clone)] pub struct DelegatedSimpleHttp { start_request: mpsc::Sender, log: log::Logger, } impl DelegatedSimpleHttp { pub fn new(log: log::Logger) -> (Self, mpsc::Receiver) { let (tx, rx) = mpsc::channel(4); ( DelegatedSimpleHttp { log, start_request: tx, }, rx, ) } } #[async_trait] impl SimpleHttp for DelegatedSimpleHttp { async fn make_request( &self, method: &'static str, url: String, ) -> Result { trace!(self.log, "making delegated request to {}", url); let (tx, mut rx) = mpsc::unbounded_channel(); let sent = self .start_request .send(DelegatedHttpRequest { method, url: url.clone(), ch: tx, }) .await; if sent.is_err() { return Ok(SimpleResponse::generic_error(&url)); // sender shut down } match rx.recv().await { Some(DelegatedHttpEvent::InitResponse { status_code, headers, }) => { trace!( self.log, "delegated request to {} resulted in status = {}", url, status_code ); let mut headers_map = HeaderMap::with_capacity(headers.len()); for (k, v) in &headers { if let (Ok(key), Ok(value)) = ( HeaderName::from_str(&k.to_lowercase()), HeaderValue::from_str(v), ) { headers_map.insert(key, value); } } Ok(SimpleResponse { url: url::Url::parse(&url).ok(), status_code: StatusCode::from_u16(status_code) .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), headers: headers_map, read: Box::pin(DelegatedReader::new(rx)), }) } Some(DelegatedHttpEvent::End) => Ok(SimpleResponse::generic_error(&url)), Some(_) => panic!("expected initresponse as first message from delegated http"), None => Ok(SimpleResponse::generic_error(&url)), // sender shut down } } } struct DelegatedReader { receiver: mpsc::UnboundedReceiver, readbuf: ReadBuffer, } impl DelegatedReader { pub fn new(rx: mpsc::UnboundedReceiver) -> Self { DelegatedReader { readbuf: ReadBuffer::default(), receiver: rx, } } } impl AsyncRead for DelegatedReader { fn poll_read( mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, buf: &mut tokio::io::ReadBuf<'_>, ) -> std::task::Poll> { if let Some((v, s)) = self.readbuf.take_data() { return self.readbuf.put_data(buf, v, s); } match self.receiver.poll_recv(cx) { Poll::Ready(Some(DelegatedHttpEvent::Body(msg))) => self.readbuf.put_data(buf, msg, 0), Poll::Ready(Some(_)) => Poll::Ready(Ok(())), // EOF Poll::Ready(None) => { Poll::Ready(Err(io::Error::new(io::ErrorKind::UnexpectedEof, "EOF"))) } Poll::Pending => Poll::Pending, } } } /// Simple http implementation that falls back to delegated http if /// making a direct reqwest fails. pub struct FallbackSimpleHttp { native: ReqwestSimpleHttp, delegated: DelegatedSimpleHttp, } impl FallbackSimpleHttp { pub fn new(native: ReqwestSimpleHttp, delegated: DelegatedSimpleHttp) -> Self { FallbackSimpleHttp { native, delegated } } pub fn native(&self) -> ReqwestSimpleHttp { self.native.clone() } pub fn delegated(&self) -> DelegatedSimpleHttp { self.delegated.clone() } } #[async_trait] impl SimpleHttp for FallbackSimpleHttp { async fn make_request( &self, method: &'static str, url: String, ) -> Result { let r1 = self.native.make_request(method, url.clone()).await; if let Ok(res) = r1 { if !res.status_code.is_server_error() { return Ok(res); } } self.delegated.make_request(method, url).await } } ================================================ FILE: cli/src/util/input.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::util::errors::wrap; use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select}; use indicatif::ProgressBar; use std::fmt::Display; use super::{errors::WrappedError, io::ReportCopyProgress}; /// Wrapper around indicatif::ProgressBar that implements ReportCopyProgress. pub struct ProgressBarReporter { bar: ProgressBar, has_set_total: bool, } impl From for ProgressBarReporter { fn from(bar: ProgressBar) -> Self { ProgressBarReporter { bar, has_set_total: false, } } } impl ReportCopyProgress for ProgressBarReporter { fn report_progress(&mut self, bytes_so_far: u64, total_bytes: u64) { if !self.has_set_total { self.bar.set_length(total_bytes); } if bytes_so_far == total_bytes { self.bar.finish_and_clear(); } else { self.bar.set_position(bytes_so_far); } } } pub fn prompt_yn(text: &str) -> Result { Confirm::with_theme(&ColorfulTheme::default()) .with_prompt(text) .default(true) .interact() .map_err(|e| wrap(e, "Failed to read confirm input")) } pub fn prompt_options(text: impl Into, options: &[T]) -> Result where T: Display + Copy, { let chosen = Select::with_theme(&ColorfulTheme::default()) .with_prompt(text) .items(options) .default(0) .interact() .map_err(|e| wrap(e, "Failed to read select input"))?; Ok(options[chosen]) } pub fn prompt_placeholder(question: &str, placeholder: &str) -> Result { Input::with_theme(&ColorfulTheme::default()) .with_prompt(question) .default(placeholder.to_string()) .interact_text() .map_err(|e| wrap(e, "Failed to read confirm input")) } ================================================ FILE: cli/src/util/io.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ fs::File, io::{self, BufRead, Seek}, task::Poll, time::Duration, }; use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, sync::mpsc, time::sleep, }; use super::ring_buffer::RingBuffer; pub trait ReportCopyProgress { fn report_progress(&mut self, bytes_so_far: u64, total_bytes: u64); } /// Type that doesn't emit anything for download progress. pub struct SilentCopyProgress(); impl ReportCopyProgress for SilentCopyProgress { fn report_progress(&mut self, _bytes_so_far: u64, _total_bytes: u64) {} } /// Copies from the reader to the writer, reporting progress to the provided /// reporter every so often. pub async fn copy_async_progress( mut reporter: T, reader: &mut R, writer: &mut W, total_bytes: u64, ) -> io::Result where R: AsyncRead + Unpin, W: AsyncWrite + Unpin, T: ReportCopyProgress, { let mut buf = vec![0; 8 * 1024]; let mut bytes_so_far = 0; let mut bytes_last_reported = 0; let report_granularity = std::cmp::min(total_bytes / 10, 2 * 1024 * 1024); reporter.report_progress(0, total_bytes); loop { let read_buf = match reader.read(&mut buf).await { Ok(0) => break, Ok(n) => &buf[..n], Err(e) => return Err(e), }; writer.write_all(read_buf).await?; bytes_so_far += read_buf.len() as u64; if bytes_so_far - bytes_last_reported > report_granularity { bytes_last_reported = bytes_so_far; reporter.report_progress(bytes_so_far, total_bytes); } } reporter.report_progress(bytes_so_far, total_bytes); Ok(bytes_so_far) } /// Helper used when converting Future interfaces to poll-based interfaces. /// Stores excess data that can be reused on future polls. #[derive(Default)] pub(crate) struct ReadBuffer(Option<(Vec, usize)>); impl ReadBuffer { /// Removes any data stored in the read buffer pub fn take_data(&mut self) -> Option<(Vec, usize)> { self.0.take() } /// Writes as many bytes as possible to the readbuf, stashing any extra. pub fn put_data( &mut self, target: &mut tokio::io::ReadBuf<'_>, bytes: Vec, start: usize, ) -> Poll> { if bytes.is_empty() { self.0 = None; // should not return Ok(), since if nothing is written to the target // it signals EOF. Instead wait for more data from the source. return Poll::Pending; } if target.remaining() >= bytes.len() - start { target.put_slice(&bytes[start..]); self.0 = None; } else { let end = start + target.remaining(); target.put_slice(&bytes[start..end]); self.0 = Some((bytes, end)); } Poll::Ready(Ok(())) } } #[derive(Debug)] pub enum TailEvent { /// A new line was read from the file. The line includes its trailing newline character. Line(String), /// The file appears to have been rewritten (size shrunk) Reset, /// An error was encountered with the file. Err(io::Error), } /// Simple, naive implementation of `tail -f -n `. Uses polling, so /// it's not the fastest, but simple and working for easy cases. pub fn tailf(file: File, n: usize) -> mpsc::UnboundedReceiver { let (tx, rx) = mpsc::unbounded_channel(); let mut last_len = match file.metadata() { Ok(m) => m.len(), Err(e) => { tx.send(TailEvent::Err(e)).ok(); return rx; } }; let mut reader = io::BufReader::new(file); let mut pos = 0; // Read the initial "n" lines back from the request. initial_lines // is a small ring buffer. let mut initial_lines = RingBuffer::new(n); loop { let mut line = String::new(); let bytes_read = match reader.read_line(&mut line) { Ok(0) => break, Ok(n) => n, Err(e) => { tx.send(TailEvent::Err(e)).ok(); return rx; } }; if !line.ends_with('\n') { // EOF break; } pos += bytes_read as u64; initial_lines.push(line); } for line in initial_lines.into_iter() { tx.send(TailEvent::Line(line)).ok(); } // now spawn the poll process to keep reading new lines tokio::spawn(async move { let poll_interval = Duration::from_millis(500); loop { tokio::select! { _ = sleep(poll_interval) => {}, _ = tx.closed() => return } match reader.get_ref().metadata() { Err(e) => { tx.send(TailEvent::Err(e)).ok(); return; } Ok(m) => { if m.len() == last_len { continue; } if m.len() < last_len { tx.send(TailEvent::Reset).ok(); pos = 0; } last_len = m.len(); } } if let Err(e) = reader.seek(io::SeekFrom::Start(pos)) { tx.send(TailEvent::Err(e)).ok(); return; } loop { let mut line = String::new(); let n = match reader.read_line(&mut line) { Ok(0) => break, Ok(n) => n, Err(e) => { tx.send(TailEvent::Err(e)).ok(); return; } }; if n == 0 || !line.ends_with('\n') { break; } pos += n as u64; if tx.send(TailEvent::Line(line)).is_err() { return; } } } }); rx } #[cfg(test)] mod tests { use rand::Rng; use std::{fs::OpenOptions, io::Write}; use super::*; #[tokio::test] async fn test_tailf_empty() { let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("tmp"); let read_file = OpenOptions::new() .write(true) .read(true) .create(true) .truncate(true) .open(&file_path) .unwrap(); let mut rx = tailf(read_file, 32); assert!(rx.try_recv().is_err()); let mut append_file = OpenOptions::new().append(true).open(&file_path).unwrap(); writeln!(&mut append_file, "some line").unwrap(); let recv = rx.recv().await; if let Some(TailEvent::Line(l)) = recv { assert_eq!("some line\n".to_string(), l); } else { unreachable!("expect a line event, got {:?}", recv) } write!(&mut append_file, "partial ").unwrap(); writeln!(&mut append_file, "line").unwrap(); let recv = rx.recv().await; if let Some(TailEvent::Line(l)) = recv { assert_eq!("partial line\n".to_string(), l); } else { unreachable!("expect a line event, got {:?}", recv) } } #[tokio::test] async fn test_tailf_resets() { let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("tmp"); let mut read_file = OpenOptions::new() .write(true) .read(true) .create(true) .truncate(true) .open(&file_path) .unwrap(); writeln!(&mut read_file, "some existing content").unwrap(); let mut rx = tailf(read_file, 0); assert!(rx.try_recv().is_err()); let mut append_file = File::create(&file_path).unwrap(); // truncates writeln!(&mut append_file, "some line").unwrap(); let recv = rx.recv().await; if let Some(TailEvent::Reset) = recv { // ok } else { unreachable!("expect a reset event, got {:?}", recv) } let recv = rx.recv().await; if let Some(TailEvent::Line(l)) = recv { assert_eq!("some line\n".to_string(), l); } else { unreachable!("expect a line event, got {:?}", recv) } } #[tokio::test] async fn test_tailf_with_data() { let dir = tempfile::tempdir().unwrap(); let file_path = dir.path().join("tmp"); let mut read_file = OpenOptions::new() .write(true) .read(true) .create(true) .truncate(true) .open(&file_path) .unwrap(); let mut rng = rand::thread_rng(); let mut written = vec![]; let base_line = "Elit ipsum cillum ex cillum. Adipisicing consequat cupidatat do proident ut in sunt Lorem ipsum tempor. Eiusmod ipsum Lorem labore exercitation sunt pariatur excepteur fugiat cillum velit cillum enim. Nisi Lorem cupidatat ad enim velit officia eiusmod esse tempor aliquip. Deserunt pariatur tempor in duis culpa esse sit nulla irure ullamco ipsum voluptate non laboris. Occaecat officia nulla officia mollit do aliquip reprehenderit ad incididunt."; for i in 0..100 { let line = format!("{}: {}", i, &base_line[..rng.gen_range(0..base_line.len())]); writeln!(&mut read_file, "{line}").unwrap(); written.push(line); } write!(&mut read_file, "partial line").unwrap(); read_file.seek(io::SeekFrom::Start(0)).unwrap(); let last_n = 32; let mut rx = tailf(read_file, last_n); for i in 0..last_n { let recv = rx.try_recv().unwrap(); if let TailEvent::Line(l) = recv { let mut expected = written[written.len() - last_n + i].to_string(); expected.push('\n'); assert_eq!(expected, l); } else { unreachable!("expect a line event, got {:?}", recv) } } assert!(rx.try_recv().is_err()); let mut append_file = OpenOptions::new().append(true).open(&file_path).unwrap(); writeln!(append_file, " is now complete").unwrap(); let recv = rx.recv().await; if let Some(TailEvent::Line(l)) = recv { assert_eq!("partial line is now complete\n".to_string(), l); } else { unreachable!("expect a line event, got {:?}", recv) } } } ================================================ FILE: cli/src/util/is_integrated.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{env, io}; /// Gets whether the current CLI seems like it's running in integrated mode, /// by looking at the location of the exe and known VS Code files. pub fn is_integrated_cli() -> io::Result { let exe = env::current_exe()?; let parent = match exe.parent() { Some(parent) if parent.file_name().and_then(|n| n.to_str()) == Some("bin") => parent, _ => return Ok(false), }; let parent = match parent.parent() { Some(p) => p, None => return Ok(false), }; let expected_file = if cfg!(target_os = "macos") { "node_modules.asar" } else { "resources.pak" }; Ok(parent.join(expected_file).exists()) } ================================================ FILE: cli/src/util/machine.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::{ ffi::OsString, path::{Path, PathBuf}, time::Duration, }; use sysinfo::{Pid, PidExt, ProcessExt, System, SystemExt}; pub fn process_at_path_exists(pid: u32, name: &Path) -> bool { let mut sys = System::new(); let pid = Pid::from_u32(pid); if !sys.refresh_process(pid) { return false; } let name_str = format!("{}", name.display()); if let Some(process) = sys.process(pid) { for cmd in process.cmd() { if cmd.contains(&name_str) { return true; } } } false } pub fn process_exists(pid: u32) -> bool { let mut sys = System::new(); sys.refresh_process(Pid::from_u32(pid)) } pub fn kill_pid(pid: u32) -> bool { let mut sys = System::new(); let pid = Pid::from_u32(pid); sys.refresh_process(pid); if let Some(p) = sys.process(pid) { p.kill() } else { false } } pub async fn wait_until_process_exits(pid: Pid, poll_ms: u64) { let mut s = System::new(); let duration = Duration::from_millis(poll_ms); while s.refresh_process(pid) { tokio::time::sleep(duration).await; } } pub fn find_running_process(name: &Path) -> Option { let mut sys = System::new(); sys.refresh_processes(); let name_str = format!("{}", name.display()); for (pid, process) in sys.processes() { for cmd in process.cmd() { if cmd.contains(&name_str) { return Some(pid.as_u32()); } } } None } pub async fn wait_until_exe_deleted(current_exe: &Path, poll_ms: u64) { let duration = Duration::from_millis(poll_ms); while current_exe.exists() { tokio::time::sleep(duration).await; } } /// Gets the canonical current exe location, referring to the "current" symlink /// if running inside snap. pub fn canonical_exe() -> std::io::Result { canonical_exe_inner( std::env::current_exe(), std::env::var_os("SNAP"), std::env::var_os("SNAP_REVISION"), ) } #[inline(always)] #[allow(unused_variables)] fn canonical_exe_inner( exe: std::io::Result, snap: Option, rev: Option, ) -> std::io::Result { let exe = exe?; #[cfg(target_os = "linux")] if let (Some(snap), Some(rev)) = (snap, rev) { if !exe.starts_with(snap) { return Ok(exe); } let mut out = PathBuf::new(); for part in exe.iter() { if part == rev { out.push("current") } else { out.push(part) } } return Ok(out); } Ok(exe) } #[cfg(test)] mod tests { use super::*; use std::path::PathBuf; #[test] #[cfg(target_os = "linux")] fn test_canonical_exe_in_snap() { let exe = canonical_exe_inner( Ok(PathBuf::from("/snap/my-snap/1234/some/exe")), Some("/snap/my-snap/1234".into()), Some("1234".into()), ) .unwrap(); assert_eq!(exe, PathBuf::from("/snap/my-snap/current/some/exe")); } #[test] fn test_canonical_exe_not_in_snap() { let exe = canonical_exe_inner( Ok(PathBuf::from("/not-in-snap")), Some("/snap/my-snap/1234".into()), Some("1234".into()), ) .unwrap(); assert_eq!(exe, PathBuf::from("/not-in-snap")); } #[test] fn test_canonical_exe_not_in_snap2() { let exe = canonical_exe_inner(Ok(PathBuf::from("/not-in-snap")), None, None).unwrap(); assert_eq!(exe, PathBuf::from("/not-in-snap")); } } ================================================ FILE: cli/src/util/os.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ #[cfg(windows)] pub fn os_release() -> Result { // The windows API *had* nice GetVersionEx/A APIs, but these were deprecated // in Winodws 8 and there's no newer win API to get version numbers. So // instead read the registry. use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey}; let key = RegKey::predef(HKEY_LOCAL_MACHINE) .open_subkey(r"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?; let major: u32 = key.get_value("CurrentMajorVersionNumber")?; let minor: u32 = key.get_value("CurrentMinorVersionNumber")?; let build: String = key.get_value("CurrentBuild")?; Ok(format!("{}.{}.{}", major, minor, build)) } #[cfg(unix)] pub fn os_release() -> Result { use std::{ffi::CStr, mem}; unsafe { let mut ret = mem::MaybeUninit::zeroed(); if libc::uname(ret.as_mut_ptr()) != 0 { return Err(std::io::Error::last_os_error()); } let ret = ret.assume_init(); let c_str: &CStr = CStr::from_ptr(ret.release.as_ptr()); Ok(c_str.to_string_lossy().into_owned()) } } ================================================ FILE: cli/src/util/prereqs.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use std::cmp::Ordering; use crate::constants::QUALITYLESS_SERVER_NAME; use crate::update_service::Platform; use lazy_static::lazy_static; use regex::bytes::Regex as BinRegex; use regex::Regex; use tokio::fs; use super::errors::CodeError; lazy_static! { static ref LDCONFIG_STDC_RE: Regex = Regex::new(r"libstdc\+\+.* => (.+)").unwrap(); static ref LDD_VERSION_RE: BinRegex = BinRegex::new(r"^ldd.*\s(\d+)\.(\d+)(?:\.(\d+))?\s").unwrap(); static ref GENERIC_VERSION_RE: Regex = Regex::new(r"^([0-9]+)\.([0-9]+)$").unwrap(); static ref LIBSTD_CXX_VERSION_RE: BinRegex = BinRegex::new(r"GLIBCXX_([0-9]+)\.([0-9]+)(?:\.([0-9]+))?").unwrap(); static ref MIN_LDD_VERSION: SimpleSemver = SimpleSemver::new(2, 28, 0); } #[cfg(target_arch = "arm")] lazy_static! { static ref MIN_CXX_VERSION: SimpleSemver = SimpleSemver::new(3, 4, 26); } #[cfg(not(target_arch = "arm"))] lazy_static! { static ref MIN_CXX_VERSION: SimpleSemver = SimpleSemver::new(3, 4, 25); } const NIXOS_TEST_PATH: &str = "/etc/NIXOS"; pub struct PreReqChecker {} impl Default for PreReqChecker { fn default() -> Self { Self::new() } } impl PreReqChecker { pub fn new() -> PreReqChecker { PreReqChecker {} } #[cfg(not(target_os = "linux"))] pub async fn verify(&self) -> Result { Platform::env_default().ok_or_else(|| { CodeError::UnsupportedPlatform(format!( "{} {}", std::env::consts::OS, std::env::consts::ARCH )) }) } #[cfg(target_os = "linux")] pub async fn verify(&self) -> Result { let (is_nixos, skip_glibc_checks, or_musl) = tokio::join!( check_is_nixos(), skip_requirements_check(), check_musl_interpreter() ); let (gnu_a, gnu_b) = if !skip_glibc_checks { tokio::join!(check_glibc_version(), check_glibcxx_version()) } else { println!("!!! WARNING: Skipping server pre-requisite check !!!"); println!("!!! Server stability is not guaranteed. Proceed at your own risk. !!!"); (Ok(true), Ok(true)) }; match (&gnu_a, &gnu_b, is_nixos) { (Ok(true), Ok(true), _) | (_, _, true) => { return Ok(if cfg!(target_arch = "x86_64") { Platform::LinuxX64 } else if cfg!(target_arch = "arm") { Platform::LinuxARM32 } else { Platform::LinuxARM64 }); } _ => {} }; if or_musl.is_ok() { return Ok(if cfg!(target_arch = "x86_64") { Platform::LinuxAlpineX64 } else { Platform::LinuxAlpineARM64 }); } let mut errors: Vec = vec![]; if let Err(e) = gnu_a { errors.push(e); } else if let Err(e) = gnu_b { errors.push(e); } if let Err(e) = or_musl { errors.push(e); } let bullets = errors .iter() .map(|e| format!(" - {e}")) .collect::>() .join("\n"); Err(CodeError::PrerequisitesFailed { bullets, name: QUALITYLESS_SERVER_NAME, }) } } #[allow(dead_code)] async fn check_musl_interpreter() -> Result<(), String> { const MUSL_PATH: &str = if cfg!(target_arch = "aarch64") { "/lib/ld-musl-aarch64.so.1" } else { "/lib/ld-musl-x86_64.so.1" }; if fs::metadata(MUSL_PATH).await.is_err() { return Err(format!( "find {MUSL_PATH}, which is required to run the {QUALITYLESS_SERVER_NAME} in musl environments" )); } Ok(()) } /// Checks the glibc version, returns "true" if the default server is required. #[cfg(target_os = "linux")] async fn check_glibc_version() -> Result { #[cfg(target_env = "gnu")] let version = { let v = unsafe { libc::gnu_get_libc_version() }; let v = unsafe { std::ffi::CStr::from_ptr(v) }; let v = v.to_str().unwrap(); extract_generic_version(v) }; #[cfg(not(target_env = "gnu"))] let version = { super::command::capture_command("ldd", ["--version"]) .await .ok() .and_then(|o| extract_ldd_version(&o.stdout)) }; if let Some(v) = version { return if v >= *MIN_LDD_VERSION { Ok(true) } else { Err(format!( "find GLIBC >= {} (but found {} instead) for GNU environments", *MIN_LDD_VERSION, v )) }; } Ok(false) } /// Check for nixos to avoid mandating glibc versions. See: /// https://github.com/microsoft/vscode-remote-release/issues/7129 #[allow(dead_code)] async fn check_is_nixos() -> bool { fs::metadata(NIXOS_TEST_PATH).await.is_ok() } /// Do not remove this check. /// Provides a way to skip the server glibc requirements check from /// outside the install flow. /// /// 1) A system process can create this /// file before the server is downloaded and installed. /// /// 2) An environment variable declared in host /// that contains path to a glibc sysroot satisfying the /// minimum requirements. #[cfg(not(windows))] pub async fn skip_requirements_check() -> bool { std::env::var("VSCODE_SERVER_CUSTOM_GLIBC_LINKER").is_ok() || fs::metadata("/tmp/vscode-skip-server-requirements-check") .await .is_ok() } #[cfg(windows)] pub async fn skip_requirements_check() -> bool { false } /// Checks the glibc++ version, returns "true" if the default server is required. #[cfg(target_os = "linux")] async fn check_glibcxx_version() -> Result { let mut libstdc_path: Option = None; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] const DEFAULT_LIB_PATH: &str = "/usr/lib64/libstdc++.so.6"; #[cfg(any(target_arch = "x86", target_arch = "arm"))] const DEFAULT_LIB_PATH: &str = "/usr/lib/libstdc++.so.6"; const LDCONFIG_PATH: &str = "/sbin/ldconfig"; if fs::metadata(DEFAULT_LIB_PATH).await.is_ok() { libstdc_path = Some(DEFAULT_LIB_PATH.to_owned()); } else if fs::metadata(LDCONFIG_PATH).await.is_ok() { libstdc_path = super::command::capture_command(LDCONFIG_PATH, ["-p"]) .await .ok() .and_then(|o| extract_libstd_from_ldconfig(&o.stdout)); } match libstdc_path { Some(path) => match fs::read(&path).await { Ok(contents) => check_for_sufficient_glibcxx_versions(contents), Err(e) => Err(format!( "validate GLIBCXX version for GNU environments, but could not: {e}" )), }, None => Err("find libstdc++.so or ldconfig for GNU environments".to_owned()), } } #[cfg(target_os = "linux")] fn check_for_sufficient_glibcxx_versions(contents: Vec) -> Result { let max_version = LIBSTD_CXX_VERSION_RE .captures_iter(&contents) .map(|m| SimpleSemver { major: m.get(1).map_or(0, |s| u32_from_bytes(s.as_bytes())), minor: m.get(2).map_or(0, |s| u32_from_bytes(s.as_bytes())), patch: m.get(3).map_or(0, |s| u32_from_bytes(s.as_bytes())), }) .max(); if let Some(max_version) = &max_version { if max_version >= &*MIN_CXX_VERSION { return Ok(true); } } Err(format!( "find GLIBCXX >= {} (but found {} instead) for GNU environments", *MIN_CXX_VERSION, max_version .as_ref() .map(String::from) .unwrap_or("none".to_string()) )) } #[allow(dead_code)] fn extract_ldd_version(output: &[u8]) -> Option { LDD_VERSION_RE.captures(output).map(|m| SimpleSemver { major: m.get(1).map_or(0, |s| u32_from_bytes(s.as_bytes())), minor: m.get(2).map_or(0, |s| u32_from_bytes(s.as_bytes())), patch: 0, }) } #[allow(dead_code)] fn extract_generic_version(output: &str) -> Option { GENERIC_VERSION_RE.captures(output).map(|m| SimpleSemver { major: m.get(1).map_or(0, |s| s.as_str().parse().unwrap()), minor: m.get(2).map_or(0, |s| s.as_str().parse().unwrap()), patch: 0, }) } #[allow(dead_code)] fn extract_libstd_from_ldconfig(output: &[u8]) -> Option { String::from_utf8_lossy(output) .lines() .find_map(|l| LDCONFIG_STDC_RE.captures(l)) .and_then(|cap| cap.get(1)) .map(|cap| cap.as_str().to_owned()) } fn u32_from_bytes(b: &[u8]) -> u32 { String::from_utf8_lossy(b).parse::().unwrap_or(0) } #[derive(Debug, Default, PartialEq, Eq)] struct SimpleSemver { major: u32, minor: u32, patch: u32, } impl PartialOrd for SimpleSemver { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for SimpleSemver { fn cmp(&self, other: &Self) -> Ordering { let major = self.major.cmp(&other.major); if major != Ordering::Equal { return major; } let minor = self.minor.cmp(&other.minor); if minor != Ordering::Equal { return minor; } self.patch.cmp(&other.patch) } } impl From<&SimpleSemver> for String { fn from(s: &SimpleSemver) -> Self { format!("v{}.{}.{}", s.major, s.minor, s.patch) } } impl std::fmt::Display for SimpleSemver { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", String::from(self)) } } #[allow(dead_code)] impl SimpleSemver { fn new(major: u32, minor: u32, patch: u32) -> SimpleSemver { SimpleSemver { major, minor, patch, } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_extract_libstd_from_ldconfig() { let actual = " libstoken.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libstoken.so.1 libstemmer.so.0d (libc6,x86-64) => /lib/x86_64-linux-gnu/libstemmer.so.0d libstdc++.so.6 (libc6,x86-64) => /lib/x86_64-linux-gnu/libstdc++.so.6 libstartup-notification-1.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libstartup-notification-1.so.0 libssl3.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libssl3.so ".to_owned().into_bytes(); assert_eq!( extract_libstd_from_ldconfig(&actual), Some("/lib/x86_64-linux-gnu/libstdc++.so.6".to_owned()), ); assert_eq!( extract_libstd_from_ldconfig(&"nothing here!".to_owned().into_bytes()), None, ); } #[test] fn test_gte() { assert!(SimpleSemver::new(1, 2, 3) >= SimpleSemver::new(1, 2, 3)); assert!(SimpleSemver::new(1, 2, 3) >= SimpleSemver::new(0, 10, 10)); assert!(SimpleSemver::new(1, 2, 3) >= SimpleSemver::new(1, 1, 10)); assert!(SimpleSemver::new(1, 2, 3) < SimpleSemver::new(1, 2, 10)); assert!(SimpleSemver::new(1, 2, 3) < SimpleSemver::new(1, 3, 1)); assert!(SimpleSemver::new(1, 2, 3) < SimpleSemver::new(2, 2, 1)); } #[test] fn check_for_sufficient_glibcxx_versions() { let actual = "ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Roland McGrath and Ulrich Drepper." .to_owned() .into_bytes(); assert_eq!( extract_ldd_version(&actual), Some(SimpleSemver::new(2, 31, 0)), ); let actual2 = "ldd (GNU libc) 2.40.9000 Copyright (C) 2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Roland McGrath and Ulrich Drepper." .to_owned() .into_bytes(); assert_eq!( extract_ldd_version(&actual2), Some(SimpleSemver::new(2, 40, 0)), ); } } ================================================ FILE: cli/src/util/ring_buffer.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ pub struct RingBuffer { data: Vec, i: usize, } impl RingBuffer { pub fn new(capacity: usize) -> Self { Self { data: Vec::with_capacity(capacity), i: 0, } } pub fn capacity(&self) -> usize { self.data.capacity() } pub fn len(&self) -> usize { self.data.len() } pub fn is_full(&self) -> bool { self.data.len() == self.data.capacity() } pub fn is_empty(&self) -> bool { self.data.len() == 0 } pub fn push(&mut self, value: T) { if self.data.len() == self.data.capacity() { self.data[self.i] = value; } else { self.data.push(value); } self.i = (self.i + 1) % self.data.capacity(); } pub fn iter(&self) -> RingBufferIter<'_, T> { RingBufferIter { index: 0, buffer: self, } } } impl IntoIterator for RingBuffer { type Item = T; type IntoIter = OwnedRingBufferIter; fn into_iter(self) -> OwnedRingBufferIter where T: Default, { OwnedRingBufferIter { index: 0, buffer: self, } } } pub struct OwnedRingBufferIter { buffer: RingBuffer, index: usize, } impl Iterator for OwnedRingBufferIter { type Item = T; fn next(&mut self) -> Option { if self.index == self.buffer.len() { return None; } let ii = (self.index + self.buffer.i) % self.buffer.len(); let item = std::mem::take(&mut self.buffer.data[ii]); self.index += 1; Some(item) } } pub struct RingBufferIter<'a, T> { buffer: &'a RingBuffer, index: usize, } impl<'a, T> Iterator for RingBufferIter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { if self.index == self.buffer.len() { return None; } let ii = (self.index + self.buffer.i) % self.buffer.len(); let item = &self.buffer.data[ii]; self.index += 1; Some(item) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_inserts() { let mut rb = RingBuffer::new(3); assert_eq!(rb.capacity(), 3); assert!(!rb.is_full()); assert_eq!(rb.len(), 0); assert_eq!(rb.iter().copied().count(), 0); rb.push(1); assert!(!rb.is_full()); assert_eq!(rb.len(), 1); assert_eq!(rb.iter().copied().collect::>(), vec![1]); rb.push(2); assert!(!rb.is_full()); assert_eq!(rb.len(), 2); assert_eq!(rb.iter().copied().collect::>(), vec![1, 2]); rb.push(3); assert!(rb.is_full()); assert_eq!(rb.len(), 3); assert_eq!(rb.iter().copied().collect::>(), vec![1, 2, 3]); rb.push(4); assert!(rb.is_full()); assert_eq!(rb.len(), 3); assert_eq!(rb.iter().copied().collect::>(), vec![2, 3, 4]); assert_eq!(rb.into_iter().collect::>(), vec![2, 3, 4]); } } ================================================ FILE: cli/src/util/sync.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use async_trait::async_trait; use std::{marker::PhantomData, sync::Arc}; use tokio::sync::{ broadcast, mpsc, watch::{self, error::RecvError}, }; #[derive(Clone)] pub struct Barrier(watch::Receiver>) where T: Clone; impl Barrier where T: Clone, { /// Waits for the barrier to be closed, returning a value if one was sent. pub async fn wait(&mut self) -> Result { loop { self.0.changed().await?; if let Some(v) = self.0.borrow().clone() { return Ok(v); } } } /// Gets whether the barrier is currently open pub fn is_open(&self) -> bool { self.0.borrow().is_some() } } #[async_trait] impl Receivable for Barrier { async fn recv_msg(&mut self) -> Option { self.wait().await.ok() } } #[derive(Clone)] pub struct BarrierOpener(Arc>>); impl BarrierOpener { /// Opens the barrier. pub fn open(&self, value: T) { self.0.send_if_modified(|v| { if v.is_none() { *v = Some(value); true } else { false } }); } } /// The Barrier is something that can be opened once from one side, /// and is thereafter permanently closed. It can contain a value. pub fn new_barrier() -> (Barrier, BarrierOpener) where T: Clone, { let (closed_tx, closed_rx) = watch::channel(None); (Barrier(closed_rx), BarrierOpener(Arc::new(closed_tx))) } /// Type that can receive messages in an async way. #[async_trait] pub trait Receivable { async fn recv_msg(&mut self) -> Option; } // todo: ideally we would use an Arc in the broadcast::Receiver to avoid having // to clone bytes everywhere, requires updating rpc consumers as well. #[async_trait] impl Receivable for broadcast::Receiver { async fn recv_msg(&mut self) -> Option { loop { match self.recv().await { Ok(v) => return Some(v), Err(broadcast::error::RecvError::Lagged(_)) => continue, Err(broadcast::error::RecvError::Closed) => return None, } } } } #[async_trait] impl Receivable for mpsc::UnboundedReceiver { async fn recv_msg(&mut self) -> Option { self.recv().await } } #[async_trait] impl Receivable for () { async fn recv_msg(&mut self) -> Option { futures::future::pending().await } } pub struct ConcatReceivable, B: Receivable> { left: Option, right: B, _marker: PhantomData, } impl, B: Receivable> ConcatReceivable { pub fn new(left: A, right: B) -> Self { Self { left: Some(left), right, _marker: PhantomData, } } } #[async_trait] impl, B: Send + Receivable> Receivable for ConcatReceivable { async fn recv_msg(&mut self) -> Option { if let Some(left) = &mut self.left { match left.recv_msg().await { Some(v) => return Some(v), None => { self.left = None; } } } return self.right.recv_msg().await; } } pub struct MergedReceivable, B: Receivable> { left: Option, right: Option, _marker: PhantomData, } impl, B: Receivable> MergedReceivable { pub fn new(left: A, right: B) -> Self { Self { left: Some(left), right: Some(right), _marker: PhantomData, } } } #[async_trait] impl, B: Send + Receivable> Receivable for MergedReceivable { async fn recv_msg(&mut self) -> Option { loop { match (&mut self.left, &mut self.right) { (Some(left), Some(right)) => { tokio::select! { left = left.recv_msg() => match left { Some(v) => return Some(v), None => { self.left = None; continue; }, }, right = right.recv_msg() => match right { Some(v) => return Some(v), None => { self.right = None; continue; }, }, } } (Some(a), None) => break a.recv_msg().await, (None, Some(b)) => break b.recv_msg().await, (None, None) => break None, } } } } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_barrier_close_after_spawn() { let (mut barrier, opener) = new_barrier::(); let (tx, rx) = tokio::sync::oneshot::channel::(); tokio::spawn(async move { tx.send(barrier.wait().await.unwrap()).unwrap(); }); opener.open(42); assert!(rx.await.unwrap() == 42); } #[tokio::test] async fn test_barrier_close_before_spawn() { let (barrier, opener) = new_barrier::(); let (tx1, rx1) = tokio::sync::oneshot::channel::(); let (tx2, rx2) = tokio::sync::oneshot::channel::(); opener.open(42); let mut b1 = barrier.clone(); tokio::spawn(async move { tx1.send(b1.wait().await.unwrap()).unwrap(); }); let mut b2 = barrier.clone(); tokio::spawn(async move { tx2.send(b2.wait().await.unwrap()).unwrap(); }); assert!(rx1.await.unwrap() == 42); assert!(rx2.await.unwrap() == 42); } } ================================================ FILE: cli/src/util/tar.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use crate::util::errors::{wrap, WrappedError}; use flate2::read::GzDecoder; use std::fs::{self, File}; use std::io::{Read, Seek}; use std::path::{Path, PathBuf}; use tar::Archive; use super::errors::wrapdbg; use super::io::ReportCopyProgress; fn should_skip_first_segment(file: &fs::File) -> Result<(bool, u64), WrappedError> { // unfortunately, we need to re-read the archive here since you cannot reuse // `.entries()`. But this will generally only look at one or two files, so this // should be acceptably speedy... If not, we could hardcode behavior for // different types of archives. let tar = GzDecoder::new(file); let mut archive = Archive::new(tar); let mut entries = archive .entries() .map_err(|e| wrap(e, "error opening archive"))?; let first_name = { let file = entries .next() .expect("expected not to have an empty archive") .map_err(|e| wrap(e, "error reading entry file"))?; let path = file.path().expect("expected to have path"); path.iter() .next() .expect("expected to have non-empty name") .to_owned() }; let mut num_entries = 1; let mut had_different_prefixes = false; for file in entries.flatten() { if !had_different_prefixes { if let Ok(name) = file.path() { if name.iter().next() != Some(&first_name) { had_different_prefixes = true; } } } num_entries += 1; } Ok((!had_different_prefixes && num_entries > 1, num_entries)) // prefix removal is invalid if there's only a single file } pub fn decompress_tarball( mut tar_gz: File, parent_path: &Path, mut reporter: T, ) -> Result<(), WrappedError> where T: ReportCopyProgress, { let (skip_first, num_entries) = should_skip_first_segment(&tar_gz)?; let report_progress_every = num_entries / 20; let mut entries_so_far = 0; let mut last_reported_at = 0; // reset since skip logic read the tar already: tar_gz .rewind() .map_err(|e| wrap(e, "error resetting seek position"))?; let tar = GzDecoder::new(tar_gz); let mut archive = Archive::new(tar); archive .entries() .map_err(|e| wrap(e, "error opening archive"))? .filter_map(|e| e.ok()) .try_for_each::<_, Result<_, WrappedError>>(|mut entry| { // approximate progress based on where we are in the archive: entries_so_far += 1; if entries_so_far - last_reported_at > report_progress_every { reporter.report_progress(entries_so_far, num_entries); entries_so_far += 1; last_reported_at = entries_so_far; } let entry_path = entry .path() .map_err(|e| wrap(e, "error reading entry path"))?; let path = parent_path.join(if skip_first { entry_path.iter().skip(1).collect::() } else { entry_path.into_owned() }); if let Some(p) = path.parent() { fs::create_dir_all(p) .map_err(|e| wrap(e, format!("could not create dir for {}", p.display())))?; } entry .unpack(&path) .map_err(|e| wrapdbg(e, format!("error unpacking {}", path.display())))?; Ok(()) })?; reporter.report_progress(num_entries, num_entries); Ok(()) } pub fn has_gzip_header(path: &Path) -> std::io::Result<(File, bool)> { let mut file = fs::File::open(path)?; let mut header = [0; 2]; let _ = file.read_exact(&mut header); file.rewind()?; Ok((file, header[0] == 0x1f && header[1] == 0x8b)) } ================================================ FILE: cli/src/util/zipper.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::errors::{wrap, WrappedError}; use super::io::ReportCopyProgress; use std::fs::{self, File}; use std::io; use std::path::Path; use std::path::PathBuf; use zip::read::ZipFile; use zip::{self, ZipArchive}; // Borrowed and modified from https://github.com/zip-rs/zip/blob/master/examples/extract.rs /// Returns whether all files in the archive start with the same path segment. /// If so, it's an indication we should skip that segment when extracting. fn should_skip_first_segment(archive: &mut ZipArchive) -> bool { let first_name = { let file = archive .by_index_raw(0) .expect("expected not to have an empty archive"); let path = file .enclosed_name() .expect("expected to have path") .iter() .next() .expect("expected to have non-empty name"); path.to_owned() }; for i in 1..archive.len() { if let Ok(file) = archive.by_index_raw(i) { if let Some(name) = file.enclosed_name() { if name.iter().next() != Some(&first_name) { return false; } } } } archive.len() > 1 // prefix removal is invalid if there's only a single file } pub fn unzip_file(file: File, parent_path: &Path, mut reporter: T) -> Result<(), WrappedError> where T: ReportCopyProgress, { let mut archive = zip::ZipArchive::new(file).map_err(|e| wrap(e, "failed to open zip archive"))?; let skip_segments_no = usize::from(should_skip_first_segment(&mut archive)); let report_progress_every = archive.len() / 20; for i in 0..archive.len() { if i % report_progress_every == 0 { reporter.report_progress(i as u64, archive.len() as u64); } let mut file = archive .by_index(i) .map_err(|e| wrap(e, format!("could not open zip entry {i}")))?; let outpath: PathBuf = match file.enclosed_name() { Some(path) => { let mut full_path = PathBuf::from(parent_path); full_path.push(PathBuf::from_iter(path.iter().skip(skip_segments_no))); full_path } None => continue, }; if file.is_dir() || file.name().ends_with('/') { fs::create_dir_all(&outpath) .map_err(|e| wrap(e, format!("could not create dir for {}", outpath.display())))?; apply_permissions(&file, &outpath)?; continue; } if let Some(p) = outpath.parent() { fs::create_dir_all(p) .map_err(|e| wrap(e, format!("could not create dir for {}", outpath.display())))?; } #[cfg(unix)] { use libc::S_IFLNK; use std::io::Read; use std::os::unix::ffi::OsStringExt; #[cfg(target_os = "macos")] const S_IFLINK_32: u32 = S_IFLNK as u32; #[cfg(target_os = "linux")] const S_IFLINK_32: u32 = S_IFLNK; if matches!(file.unix_mode(), Some(mode) if mode & S_IFLINK_32 == S_IFLINK_32) { let mut link_to = Vec::new(); file.read_to_end(&mut link_to).map_err(|e| { wrap( e, format!("could not read symlink linkpath {}", outpath.display()), ) })?; let link_path = PathBuf::from(std::ffi::OsString::from_vec(link_to)); std::os::unix::fs::symlink(link_path, &outpath).map_err(|e| { wrap(e, format!("could not create symlink {}", outpath.display())) })?; continue; } } let mut outfile = fs::File::create(&outpath).map_err(|e| { wrap( e, format!( "unable to open file to write {} (from {:?})", outpath.display(), file.enclosed_name().map(|p| p.to_string_lossy()), ), ) })?; io::copy(&mut file, &mut outfile) .map_err(|e| wrap(e, format!("error copying file {}", outpath.display())))?; apply_permissions(&file, &outpath)?; } reporter.report_progress(archive.len() as u64, archive.len() as u64); Ok(()) } #[cfg(unix)] fn apply_permissions(file: &ZipFile, outpath: &Path) -> Result<(), WrappedError> { use std::os::unix::fs::PermissionsExt; if let Some(mode) = file.unix_mode() { fs::set_permissions(outpath, fs::Permissions::from_mode(mode)).map_err(|e| { wrap( e, format!("error setting permissions on {}", outpath.display()), ) })?; } Ok(()) } #[cfg(windows)] fn apply_permissions(_file: &ZipFile, _outpath: &Path) -> Result<(), WrappedError> { Ok(()) } ================================================ FILE: cli/src/util.rs ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ mod is_integrated; pub mod command; pub mod errors; pub mod http; pub mod input; pub mod io; pub mod machine; pub mod prereqs; pub mod ring_buffer; pub mod sync; pub use is_integrated::*; pub mod app_lock; pub mod file_lock; pub mod os; pub mod tar; pub mod zipper; ================================================ FILE: eslint.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // @ts-check import fs from 'fs'; import path from 'path'; import tseslint from 'typescript-eslint'; import { fileURLToPath } from 'url'; import stylisticTs from '@stylistic/eslint-plugin-ts'; import pluginLocal from 'eslint-plugin-local'; import pluginJsdoc from 'eslint-plugin-jsdoc'; import pluginHeader from 'eslint-plugin-header'; pluginHeader.rules.header.meta.schema = false; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ignores = fs.readFileSync(path.join(__dirname, '.eslint-ignore'), 'utf8') .toString() .split(/\r\n|\n/) .filter(line => line && !line.startsWith('#')); export default tseslint.config( // Global ignores { ignores: [ ...ignores, '!**/.eslint-plugin-local/**/*' ], }, // All files (JS and TS) { languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, 'header': pluginHeader, }, rules: { 'constructor-super': 'warn', 'curly': 'off', // <-- Void 'eqeqeq': 'warn', 'prefer-const': [ 'off', // <-- Void { 'destructuring': 'all' } ], 'no-buffer-constructor': 'warn', 'no-caller': 'warn', 'no-case-declarations': 'warn', 'no-debugger': 'warn', 'no-duplicate-case': 'warn', 'no-duplicate-imports': 'warn', 'no-eval': 'warn', 'no-async-promise-executor': 'warn', 'no-extra-semi': 'warn', 'no-new-wrappers': 'warn', 'no-redeclare': 'off', 'no-sparse-arrays': 'warn', 'no-throw-literal': 'warn', 'no-unsafe-finally': 'warn', 'no-unused-labels': 'warn', 'no-misleading-character-class': 'warn', 'no-restricted-globals': [ 'warn', 'name', 'length', 'event', 'closed', 'external', 'status', 'origin', 'orientation', 'context' ], // non-complete list of globals that are easy to access unintentionally 'no-var': 'warn', 'semi': 'off', 'local/code-translation-remind': 'warn', 'local/code-no-native-private': 'warn', 'local/code-parameter-properties-must-have-explicit-accessibility': 'warn', 'local/code-no-nls-in-standalone-editor': 'warn', 'local/code-no-potentially-unsafe-disposables': 'warn', 'local/code-no-dangerous-type-assertions': 'off', // Void warn -> off 'local/code-no-standalone-editor': 'warn', 'local/code-no-unexternalized-strings': 'warn', 'local/code-must-use-super-dispose': 'warn', 'local/code-declare-service-brand': 'warn', 'local/code-layering': [ 'warn', { 'common': [], 'node': [ 'common' ], 'browser': [ 'common' ], 'electron-sandbox': [ 'common', 'browser' ], 'electron-utility': [ 'common', 'node' ], 'electron-main': [ 'common', 'node', 'electron-utility' ] } ], // Void - this should only apply to workbench/void/ // 'header/header': [ // 2, // 'block', // [ // '/*--------------------------------------------------------------------------------------', // '* Copyright 2025 Glass Devtools, Inc. All rights reserved.', // '* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.', // '*--------------------------------------------------------------------------------------*/', // ] // ] }, }, // TS { files: [ '**/*.ts', ], languageOptions: { parser: tseslint.parser, }, plugins: { '@stylistic/ts': stylisticTs, '@typescript-eslint': tseslint.plugin, 'local': pluginLocal, 'jsdoc': pluginJsdoc, }, rules: { '@stylistic/ts/semi': 'off', // <-- Void '@stylistic/ts/member-delimiter-style': 'off', // <-- Void 'local/code-no-unused-expressions': [ 'warn', { 'allowTernary': true } ], 'jsdoc/no-types': 'warn', 'local/code-no-static-self-ref': 'off' // <-- Void } }, // vscode TS { files: [ 'src/**/*.ts', ], languageOptions: { parser: tseslint.parser, }, plugins: { '@typescript-eslint': tseslint.plugin, }, rules: { '@typescript-eslint/naming-convention': [ 'warn', { 'selector': 'class', 'format': [ 'PascalCase' ] } ] } }, // Tests { files: [ '**/*.test.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-must-use-super-dispose': 'off', 'local/code-no-test-only': 'error', 'local/code-no-test-async-suite': 'warn', 'local/code-no-unexternalized-strings': 'off', 'local/code-must-use-result': [ 'warn', [ { 'message': 'Expression must be awaited', 'functions': [ 'assertSnapshot', 'assertHeap' ] } ] ] } }, // vscode tests specific rules { files: [ 'src/vs/**/*.test.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-ensure-no-disposables-leak-in-test': [ 'warn', { // Files should (only) be removed from the list they adopt the leak detector 'exclude': [ 'src/vs/platform/configuration/test/common/configuration.test.ts', 'src/vs/platform/opener/test/common/opener.test.ts', 'src/vs/platform/registry/test/common/platform.test.ts', 'src/vs/platform/workspace/test/common/workspace.test.ts', 'src/vs/platform/workspaces/test/electron-main/workspaces.test.ts', 'src/vs/workbench/contrib/bulkEdit/test/browser/bulkCellEdits.test.ts', 'src/vs/workbench/contrib/chat/test/common/chatWordCounter.test.ts', 'src/vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts', 'src/vs/workbench/contrib/notebook/test/browser/notebookExecutionService.test.ts', 'src/vs/workbench/contrib/notebook/test/browser/notebookExecutionStateService.test.ts', 'src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts', 'src/vs/workbench/services/commands/test/common/commandService.test.ts', 'src/vs/workbench/services/userActivity/test/browser/domActivityTracker.test.ts', 'src/vs/workbench/test/browser/quickAccess.test.ts' ] } ] } }, // vscode API { files: [ '**/vscode.d.ts', '**/vscode.proposed.*.d.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'no-restricted-syntax': [ 'warn', { 'selector': `TSArrayType > TSUnionType`, 'message': 'Use Array<...> for arrays of union types.' }, ], 'local/vscode-dts-create-func': 'warn', 'local/vscode-dts-literal-or-types': 'warn', 'local/vscode-dts-string-type-literals': 'warn', 'local/vscode-dts-interface-naming': 'warn', 'local/vscode-dts-cancellation': 'warn', 'local/vscode-dts-use-export': 'warn', 'local/vscode-dts-use-thenable': 'warn', 'local/vscode-dts-vscode-in-comments': 'warn', 'local/vscode-dts-provider-naming': [ 'warn', { 'allowed': [ 'FileSystemProvider', 'TreeDataProvider', 'TestProvider', 'CustomEditorProvider', 'CustomReadonlyEditorProvider', 'TerminalLinkProvider', 'AuthenticationProvider', 'NotebookContentProvider' ] } ], 'local/vscode-dts-event-naming': [ 'warn', { 'allowed': [ 'onCancellationRequested', 'event' ], 'verbs': [ 'accept', 'change', 'close', 'collapse', 'create', 'delete', 'discover', 'dispose', 'drop', 'edit', 'end', 'execute', 'expand', 'grant', 'hide', 'invalidate', 'open', 'override', 'perform', 'receive', 'register', 'remove', 'rename', 'save', 'send', 'start', 'terminate', 'trigger', 'unregister', 'write' ] } ] } }, // vscode.d.ts { files: [ '**/vscode.d.ts' ], languageOptions: { parser: tseslint.parser, }, rules: { 'jsdoc/tag-lines': 'off', 'jsdoc/valid-types': 'off', 'jsdoc/no-multi-asterisks': [ 'warn', { 'allowWhitespace': true } ], 'jsdoc/require-jsdoc': [ 'warn', { 'enableFixer': false, 'contexts': [ 'TSInterfaceDeclaration', 'TSPropertySignature', 'TSMethodSignature', 'TSDeclareFunction', 'ClassDeclaration', 'MethodDefinition', 'PropertyDeclaration', 'TSEnumDeclaration', 'TSEnumMember', 'ExportNamedDeclaration' ] } ], 'jsdoc/check-param-names': [ 'warn', { 'enableFixer': false, 'checkDestructured': false } ], 'jsdoc/require-returns': 'warn' } }, // common/browser layer { files: [ 'src/**/{common,browser}/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-amd-node-module': 'warn' } }, // node/electron layer { files: [ 'src/*.ts', 'src/**/{node,electron-main,electron-utility}/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'no-restricted-globals': [ 'warn', 'name', 'length', 'event', 'closed', 'external', 'status', 'origin', 'orientation', 'context', // Below are globals that are unsupported in ESM '__dirname', '__filename', 'require' ] } }, // browser/electron-sandbox layer { files: [ 'src/**/{browser,electron-sandbox}/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-no-global-document-listener': 'warn', 'no-restricted-syntax': [ 'warn', { 'selector': `BinaryExpression[operator='instanceof'][right.name='MouseEvent']`, 'message': 'Use DOM.isMouseEvent() to support multi-window scenarios.' }, { 'selector': `BinaryExpression[operator='instanceof'][right.name=/^HTML\\w+/]`, 'message': 'Use DOM.isHTMLElement() and related methods to support multi-window scenarios.' }, { 'selector': `BinaryExpression[operator='instanceof'][right.name=/^SVG\\w+/]`, 'message': 'Use DOM.isSVGElement() and related methods to support multi-window scenarios.' }, { 'selector': `BinaryExpression[operator='instanceof'][right.name='KeyboardEvent']`, 'message': 'Use DOM.isKeyboardEvent() to support multi-window scenarios.' }, { 'selector': `BinaryExpression[operator='instanceof'][right.name='PointerEvent']`, 'message': 'Use DOM.isPointerEvent() to support multi-window scenarios.' }, { 'selector': `BinaryExpression[operator='instanceof'][right.name='DragEvent']`, 'message': 'Use DOM.isDragEvent() to support multi-window scenarios.' }, { 'selector': `MemberExpression[object.name='document'][property.name='activeElement']`, 'message': 'Use .document.activeElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='contains']`, 'message': 'Use .document.contains to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='styleSheets']`, 'message': 'Use .document.styleSheets to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='fullscreenElement']`, 'message': 'Use .document.fullscreenElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='body']`, 'message': 'Use .document.body to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='addEventListener']`, 'message': 'Use .document.addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='removeEventListener']`, 'message': 'Use .document.removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='hasFocus']`, 'message': 'Use .document.hasFocus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='head']`, 'message': 'Use .document.head to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='exitFullscreen']`, 'message': 'Use .document.exitFullscreen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getElementById']`, 'message': 'Use .document.getElementById to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getElementsByClassName']`, 'message': 'Use .document.getElementsByClassName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getElementsByName']`, 'message': 'Use .document.getElementsByName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getElementsByTagName']`, 'message': 'Use .document.getElementsByTagName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getElementsByTagNameNS']`, 'message': 'Use .document.getElementsByTagNameNS to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='getSelection']`, 'message': 'Use .document.getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='open']`, 'message': 'Use .document.open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='close']`, 'message': 'Use .document.close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='documentElement']`, 'message': 'Use .document.documentElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='visibilityState']`, 'message': 'Use .document.visibilityState to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='querySelector']`, 'message': 'Use .document.querySelector to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='querySelectorAll']`, 'message': 'Use .document.querySelectorAll to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='elementFromPoint']`, 'message': 'Use .document.elementFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='elementsFromPoint']`, 'message': 'Use .document.elementsFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='onkeydown']`, 'message': 'Use .document.onkeydown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='onkeyup']`, 'message': 'Use .document.onkeyup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='onmousedown']`, 'message': 'Use .document.onmousedown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='onmouseup']`, 'message': 'Use .document.onmouseup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'selector': `MemberExpression[object.name='document'][property.name='execCommand']`, 'message': 'Use .document.execCommand to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' } ], 'no-restricted-globals': [ 'warn', 'name', 'length', 'event', 'closed', 'external', 'status', 'origin', 'orientation', 'context', { 'name': 'setInterval', 'message': 'Use .setInterval to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'clearInterval', 'message': 'Use .clearInterval to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'requestAnimationFrame', 'message': 'Use .requestAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'cancelAnimationFrame', 'message': 'Use .cancelAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'requestIdleCallback', 'message': 'Use .requestIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'cancelIdleCallback', 'message': 'Use .cancelIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'window', 'message': 'Use to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'addEventListener', 'message': 'Use .addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'removeEventListener', 'message': 'Use .removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'getComputedStyle', 'message': 'Use .getComputedStyle to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'focus', 'message': 'Use .focus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'blur', 'message': 'Use .blur to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'close', 'message': 'Use .close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'dispatchEvent', 'message': 'Use .dispatchEvent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'getSelection', 'message': 'Use .getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'matchMedia', 'message': 'Use .matchMedia to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'open', 'message': 'Use .open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'parent', 'message': 'Use .parent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'postMessage', 'message': 'Use .postMessage to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'devicePixelRatio', 'message': 'Use .devicePixelRatio to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'frames', 'message': 'Use .frames to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'frameElement', 'message': 'Use .frameElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'innerHeight', 'message': 'Use .innerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'innerWidth', 'message': 'Use .innerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'outerHeight', 'message': 'Use .outerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'outerWidth', 'message': 'Use .outerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'opener', 'message': 'Use .opener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'origin', 'message': 'Use .origin to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'screen', 'message': 'Use .screen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'screenLeft', 'message': 'Use .screenLeft to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'screenTop', 'message': 'Use .screenTop to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'screenX', 'message': 'Use .screenX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'screenY', 'message': 'Use .screenY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'scrollX', 'message': 'Use .scrollX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'scrollY', 'message': 'Use .scrollY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'top', 'message': 'Use .top to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' }, { 'name': 'visualViewport', 'message': 'Use .visualViewport to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.' } ] } }, // electron-utility layer { files: [ 'src/**/electron-utility/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, rules: { 'no-restricted-imports': [ 'warn', { 'paths': [ { 'name': 'electron', 'allowImportNames': [ 'net', 'system-preferences', ], 'message': 'Only net and system-preferences are allowed to be imported from electron' } ] } ] } }, { files: [ 'src/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-import-patterns': [ 'warn', { // imports that are allowed in all files of layers: // - browser // - electron-sandbox 'when': 'hasBrowser', 'allow': [] }, { // imports that are allowed in all files of layers: // - node // - electron-utility // - electron-main 'when': 'hasNode', 'allow': [ '@parcel/watcher', '@vscode/sqlite3', '@vscode/vscode-languagedetection', '@vscode/ripgrep', '@vscode/iconv-lite-umd', '@vscode/policy-watcher', '@vscode/proxy-agent', '@vscode/spdlog', '@vscode/windows-process-tree', 'assert', 'child_process', 'console', 'cookie', 'crypto', 'dns', 'events', 'fs', 'fs/promises', 'http', 'https', 'minimist', 'node:module', 'native-keymap', 'native-watchdog', 'net', 'node-pty', 'os', 'path', 'perf_hooks', 'readline', 'stream', 'string_decoder', 'tas-client-umd', 'tls', 'undici-types', 'url', 'util', 'v8-inspect-profiler', 'vscode-regexpp', 'vscode-textmate', 'worker_threads', '@xterm/addon-clipboard', '@xterm/addon-image', '@xterm/addon-ligatures', '@xterm/addon-search', '@xterm/addon-serialize', '@xterm/addon-unicode11', '@xterm/addon-webgl', '@xterm/headless', '@xterm/xterm', 'yauzl', 'yazl', 'zlib', // Void added this '@modelcontextprotocol/sdk/**' ] }, { // imports that are allowed in all files of layers: // - electron-utility // - electron-main 'when': 'hasElectron', 'allow': [ 'electron' ] }, { // imports that are allowed in all /test/ files 'when': 'test', 'allow': [ 'assert', 'sinon', 'sinon-test' ] }, // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!! Do not relax these rules !!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // A path ending in /~ has a special meaning. It indicates a template position // which will be substituted with one or more layers. // // When /~ is used in the target, the rule will be expanded to 14 distinct rules. // e.g. 'src/vs/base/~' will be expanded to: // - src/vs/base/common // - src/vs/base/worker // - src/vs/base/browser // - src/vs/base/electron-sandbox // - src/vs/base/node // - src/vs/base/electron-main // - src/vs/base/test/common // - src/vs/base/test/worker // - src/vs/base/test/browser // - src/vs/base/test/electron-sandbox // - src/vs/base/test/node // - src/vs/base/test/electron-main // // When /~ is used in the restrictions, it will be replaced with the correct // layers that can be used e.g. 'src/vs/base/electron-sandbox' will be able // to import '{common,browser,electron-sanbox}', etc. // // It is possible to use /~ in the restrictions property even without using it in // the target property by adding a layer property. { 'target': 'src/vs/base/~', 'restrictions': [ 'vs/base/~' ] }, { 'target': 'src/vs/base/parts/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~' ] }, { 'target': 'src/vs/platform/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'tas-client-umd', // node module allowed even in /common/ '@microsoft/1ds-core-js', // node module allowed even in /common/ '@microsoft/1ds-post-js', // node module allowed even in /common/ '@xterm/headless' // node module allowed even in /common/ ] }, { 'target': 'src/vs/editor/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', '@vscode/tree-sitter-wasm' // node module allowed even in /common/ ] }, { 'target': 'src/vs/editor/contrib/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~' ] }, { 'target': 'src/vs/editor/standalone/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/standalone/~', '@vscode/tree-sitter-wasm' // type import ] }, { 'target': 'src/vs/editor/editor.all.ts', 'layer': 'browser', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~' ] }, { 'target': 'src/vs/editor/editor.worker.start.ts', 'layer': 'worker', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~' ] }, { 'target': 'src/vs/editor/{editor.api.ts,editor.main.ts}', 'layer': 'browser', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/standalone/~', 'vs/editor/*' ] }, { 'target': 'src/vs/workbench/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/workbench/~', 'vs/workbench/services/*/~', 'assert', { 'when': 'test', 'pattern': 'vs/workbench/contrib/*/~' } // TODO@layers ] }, { 'target': 'src/vs/workbench/api/~', 'restrictions': [ '@c4312/eventsource-umd', 'vscode', 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/workbench/api/~', 'vs/workbench/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/contrib/terminalContrib/*/~' ] }, { 'target': 'src/vs/workbench/services/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/workbench/~', 'vs/workbench/services/*/~', { 'when': 'test', 'pattern': 'vs/workbench/contrib/*/~' }, // TODO@layers 'tas-client-umd', // node module allowed even in /common/ 'vscode-textmate', // node module allowed even in /common/ '@vscode/vscode-languagedetection', // node module allowed even in /common/ '@vscode/tree-sitter-wasm', // type import { 'when': 'hasBrowser', 'pattern': '@xterm/xterm' } // node module allowed even in /browser/ ] }, { 'target': 'src/vs/workbench/contrib/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/workbench/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/contrib/terminal/terminalContribChatExports*', 'vs/workbench/contrib/terminal/terminalContribExports*', 'vscode-notebook-renderer', // Type only import '@vscode/tree-sitter-wasm', // type import { 'when': 'hasBrowser', 'pattern': '@xterm/xterm' }, // node module allowed even in /browser/ { 'when': 'hasBrowser', 'pattern': '@xterm/addon-*' }, // node module allowed even in /browser/ { 'when': 'hasBrowser', 'pattern': 'vscode-textmate' } // node module allowed even in /browser/ ] }, { 'target': 'src/vs/workbench/contrib/terminalContrib/*/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/workbench/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', // Only allow terminalContrib to import from itself, this works because // terminalContrib is one extra folder deep 'vs/workbench/contrib/terminalContrib/*/~', 'vscode-notebook-renderer', // Type only import { 'when': 'hasBrowser', 'pattern': '@xterm/xterm' }, // node module allowed even in /browser/ { 'when': 'hasBrowser', 'pattern': '@xterm/addon-*' }, // node module allowed even in /browser/ { 'when': 'hasBrowser', 'pattern': 'vscode-textmate' }, // node module allowed even in /browser/ '@xterm/headless' // node module allowed even in /common/ and /browser/ ] }, { 'target': 'src/vs/code/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/code/~', { 'when': 'hasBrowser', 'pattern': 'vs/workbench/workbench.web.main.js' }, { 'when': 'hasBrowser', 'pattern': 'vs/workbench/workbench.web.main.internal.js' }, { 'when': 'hasBrowser', 'pattern': 'vs/workbench/~' }, { 'when': 'hasBrowser', 'pattern': 'vs/workbench/services/*/~' } ] }, { 'target': 'src/vs/server/~', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/workbench/~', 'vs/workbench/api/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/server/~' ] }, { 'target': 'src/vs/workbench/contrib/terminal/terminal.all.ts', 'layer': 'browser', 'restrictions': [ 'vs/workbench/contrib/**' ] }, { 'target': 'src/vs/workbench/contrib/terminal/terminalContribChatExports.ts', 'layer': 'browser', 'restrictions': [ 'vs/workbench/contrib/terminalContrib/*/~' ] }, { 'target': 'src/vs/workbench/contrib/terminal/terminalContribExports.ts', 'layer': 'browser', 'restrictions': [ 'vs/platform/*/~', 'vs/workbench/contrib/terminalContrib/*/~' ] }, { 'target': 'src/vs/workbench/workbench.common.main.ts', 'layer': 'browser', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/editor.all.js', 'vs/workbench/~', 'vs/workbench/api/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/contrib/terminal/terminal.all.js' ] }, { 'target': 'src/vs/workbench/workbench.web.main.ts', 'layer': 'browser', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/editor.all.js', 'vs/workbench/~', 'vs/workbench/api/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/workbench.common.main.js' ] }, { 'target': 'src/vs/workbench/workbench.web.main.internal.ts', 'layer': 'browser', 'restrictions': [ 'vs/base/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/editor.all.js', 'vs/workbench/~', 'vs/workbench/api/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/workbench.common.main.js' ] }, { 'target': 'src/vs/workbench/workbench.desktop.main.ts', 'layer': 'electron-sandbox', 'restrictions': [ 'vs/base/*/~', 'vs/base/parts/*/~', 'vs/platform/*/~', 'vs/editor/~', 'vs/editor/contrib/*/~', 'vs/editor/editor.all.js', 'vs/workbench/~', 'vs/workbench/api/~', 'vs/workbench/services/*/~', 'vs/workbench/contrib/*/~', 'vs/workbench/workbench.common.main.js' ] }, { 'target': 'src/vs/amdX.ts', 'restrictions': [ 'vs/base/common/*' ] }, { 'target': 'src/vs/{loader.d.ts,monaco.d.ts,nls.ts,nls.messages.ts}', 'restrictions': [] }, { 'target': 'src/vscode-dts/**', 'restrictions': [] }, { 'target': 'src/bootstrap-window.ts', 'restrictions': [] }, { 'target': 'src/vs/nls.ts', 'restrictions': [ 'vs/*' ] }, { 'target': 'src/{bootstrap-cli.ts,bootstrap-esm.ts,bootstrap-fork.ts,bootstrap-import.ts,bootstrap-meta.ts,bootstrap-node.ts,bootstrap-server.ts,cli.ts,main.ts,server-cli.ts,server-main.ts}', 'restrictions': [ 'vs/**/common/*', 'vs/**/node/*', 'vs/nls.js', 'src/*.js', '*' // node.js ] } ] } }, { files: [ 'test/**/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-import-patterns': [ 'warn', { 'target': 'test/smoke/**', 'restrictions': [ 'test/automation', 'test/smoke/**', '@vscode/*', '@parcel/*', '@playwright/*', '*' // node modules ] }, { 'target': 'test/automation/**', 'restrictions': [ 'test/automation/**', '@vscode/*', '@parcel/*', 'playwright-core/**', '@playwright/*', '*' // node modules ] }, { 'target': 'test/integration/**', 'restrictions': [ 'test/integration/**', '@vscode/*', '@parcel/*', '@playwright/*', '*' // node modules ] }, { 'target': 'test/monaco/**', 'restrictions': [ 'test/monaco/**', '@vscode/*', '@parcel/*', '@playwright/*', '*' // node modules ] } ] } }, { files: [ 'src/vs/workbench/contrib/notebook/browser/view/renderers/*.ts' ], languageOptions: { parser: tseslint.parser, }, plugins: { 'local': pluginLocal, }, rules: { 'local/code-no-runtime-import': [ 'error', { 'src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts': [ '**/*' ] } ], 'local/code-limited-top-functions': [ 'error', { 'src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts': [ 'webviewPreloads', 'preloadsScriptStr' ] } ] } }, // Terminal { files: [ 'src/vs/workbench/contrib/terminal/**/*.ts', 'src/vs/workbench/contrib/terminalContrib/**/*.ts', ], languageOptions: { parser: tseslint.parser, }, rules: { '@typescript-eslint/naming-convention': [ 'warn', // variableLike { 'selector': 'variable', 'format': ['camelCase', 'UPPER_CASE', 'PascalCase'] }, { 'selector': 'variable', 'filter': '^I.+Service$', 'format': ['PascalCase'], 'prefix': ['I'] }, // memberLike { 'selector': 'memberLike', 'modifiers': ['private'], 'format': ['camelCase'], 'leadingUnderscore': 'require' }, { 'selector': 'memberLike', 'modifiers': ['protected'], 'format': ['camelCase'], 'leadingUnderscore': 'require' }, { 'selector': 'enumMember', 'format': ['PascalCase'] }, // memberLike - Allow enum-like objects to use UPPER_CASE { 'selector': 'method', 'modifiers': ['public'], 'format': ['camelCase', 'UPPER_CASE'] }, // typeLike { 'selector': 'typeLike', 'format': ['PascalCase'] }, { 'selector': 'interface', 'format': ['PascalCase'] } ], 'comma-dangle': ['warn', 'only-multiline'] } }, // markdown-language-features { files: [ 'extensions/markdown-language-features/**/*.ts', ], languageOptions: { parser: tseslint.parser, }, plugins: { '@typescript-eslint': tseslint.plugin, }, rules: { '@typescript-eslint/naming-convention': [ 'warn', { 'selector': 'default', 'modifiers': ['private'], 'format': null, 'leadingUnderscore': 'require' }, { 'selector': 'default', 'modifiers': ['public'], 'format': null, 'leadingUnderscore': 'forbid' } ] } }, // typescript-language-features { files: [ 'extensions/typescript-language-features/**/*.ts', ], languageOptions: { parser: tseslint.parser, parserOptions: { project: [ 'extensions/typescript-language-features/tsconfig.json', 'extensions/typescript-language-features/web/tsconfig.json' ], } }, plugins: { '@typescript-eslint': tseslint.plugin, }, rules: { '@typescript-eslint/prefer-optional-chain': 'warn', '@typescript-eslint/prefer-readonly': 'warn', } } ); ================================================ FILE: extensions/.npmrc ================================================ legacy-peer-deps="true" timeout=180000 ================================================ FILE: extensions/bat/.vscodeignore ================================================ test/** cgmanifest.json ================================================ FILE: extensions/bat/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "mmims/language-batchfile", "repositoryUrl": "https://github.com/mmims/language-batchfile", "commitHash": "6154ae25a24e01ac9329e7bcf958e093cd8733a9" } }, "license": "MIT", "version": "0.7.6" } ], "version": 1 } ================================================ FILE: extensions/bat/language-configuration.json ================================================ { "comments": { "lineComment": "@REM" }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], { "open": "\"", "close": "\"", "notIn": ["string"] } ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["%", "%"], ["\"", "\""] ], "folding": { "markers": { "start": "^\\s*(::|REM|@REM)\\s*#region", "end": "^\\s*(::|REM|@REM)\\s*#endregion" } } } ================================================ FILE: extensions/bat/package.json ================================================ { "name": "bat", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.52.0" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "bat", "extensions": [ ".bat", ".cmd" ], "aliases": [ "Batch", "bat" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "bat", "scopeName": "source.batchfile", "path": "./syntaxes/batchfile.tmLanguage.json" } ], "snippets": [ { "language": "bat", "path": "./snippets/batchfile.code-snippets" } ] }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/bat/package.nls.json ================================================ { "displayName": "Windows Bat Language Basics", "description": "Provides snippets, syntax highlighting, bracket matching and folding in Windows batch files." } ================================================ FILE: extensions/bat/snippets/batchfile.code-snippets ================================================ { "Region Start": { "prefix": "#region", "body": [ "::#region" ], "description": "Folding Region Start" }, "Region End": { "prefix": "#endregion", "body": [ "::#endregion" ], "description": "Folding Region End" } } ================================================ FILE: extensions/bat/syntaxes/batchfile.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/mmims/language-batchfile/blob/master/grammars/batchfile.cson", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/mmims/language-batchfile/commit/6154ae25a24e01ac9329e7bcf958e093cd8733a9", "name": "Batch File", "scopeName": "source.batchfile", "injections": { "L:meta.block.repeat.batchfile": { "patterns": [ { "include": "#repeatParameter" } ] } }, "patterns": [ { "include": "#commands" }, { "include": "#comments" }, { "include": "#constants" }, { "include": "#controls" }, { "include": "#escaped_characters" }, { "include": "#labels" }, { "include": "#numbers" }, { "include": "#operators" }, { "include": "#parens" }, { "include": "#strings" }, { "include": "#variables" } ], "repository": { "commands": { "patterns": [ { "match": "(?<=^|[\\s@])(?i:adprep|append|arp|assoc|at|atmadm|attrib|auditpol|autochk|autoconv|autofmt|bcdboot|bcdedit|bdehdcfg|bitsadmin|bootcfg|brea|cacls|cd|certreq|certutil|change|chcp|chdir|chglogon|chgport|chgusr|chkdsk|chkntfs|choice|cipher|clip|cls|clscluadmin|cluster|cmd|cmdkey|cmstp|color|comp|compact|convert|copy|cprofile|cscript|csvde|date|dcdiag|dcgpofix|dcpromo|defra|del|dfscmd|dfsdiag|dfsrmig|diantz|dir|dirquota|diskcomp|diskcopy|diskpart|diskperf|diskraid|diskshadow|dispdiag|doin|dnscmd|doskey|driverquery|dsacls|dsadd|dsamain|dsdbutil|dsget|dsmgmt|dsmod|dsmove|dsquery|dsrm|edit|endlocal|eraseesentutl|eventcreate|eventquery|eventtriggers|evntcmd|expand|extract|fc|filescrn|find|findstr|finger|flattemp|fonde|forfiles|format|freedisk|fsutil|ftp|ftype|fveupdate|getmac|gettype|gpfixup|gpresult|gpupdate|graftabl|hashgen|hep|helpctr|hostname|icacls|iisreset|inuse|ipconfig|ipxroute|irftp|ismserv|jetpack|klist|ksetup|ktmutil|ktpass|label|ldifd|ldp|lodctr|logman|logoff|lpq|lpr|macfile|makecab|manage-bde|mapadmin|md|mkdir|mklink|mmc|mode|more|mount|mountvol|move|mqbup|mqsvc|mqtgsvc|msdt|msg|msiexec|msinfo32|mstsc|nbtstat|net computer|net group|net localgroup|net print|net session|net share|net start|net stop|net use|net user|net view|net|netcfg|netdiag|netdom|netsh|netstat|nfsadmin|nfsshare|nfsstat|nlb|nlbmgr|nltest|nslookup|ntackup|ntcmdprompt|ntdsutil|ntfrsutl|openfiles|pagefileconfig|path|pathping|pause|pbadmin|pentnt|perfmon|ping|pnpunatten|pnputil|popd|powercfg|powershell|powershell_ise|print|prncnfg|prndrvr|prnjobs|prnmngr|prnport|prnqctl|prompt|pubprn|pushd|pushprinterconnections|pwlauncher|qappsrv|qprocess|query|quser|qwinsta|rasdial|rcp|rd|rdpsign|regentc|recover|redircmp|redirusr|reg|regini|regsvr32|relog|ren|rename|rendom|repadmin|repair-bde|replace|reset session|rxec|risetup|rmdir|robocopy|route|rpcinfo|rpcping|rsh|runas|rundll32|rwinsta|sc|schtasks|scp|scwcmd|secedit|serverceipoptin|servrmanagercmd|serverweroptin|setspn|setx|sfc|sftp|shadow|shift|showmount|shutdown|sort|ssh|ssh-add|ssh-agent|ssh-keygen|ssh-keyscan|start|storrept|subst|sxstrace|ysocmgr|systeminfo|takeown|tapicfg|taskkill|tasklist|tcmsetup|telnet|tftp|time|timeout|title|tlntadmn|tpmvscmgr|tpmvscmgr|tacerpt|tracert|tree|tscon|tsdiscon|tsecimp|tskill|tsprof|type|typeperf|tzutil|uddiconfig|umount|unlodctr|ver|verifier|verif|vol|vssadmin|w32tm|waitfor|wbadmin|wdsutil|wecutil|wevtutil|where|whoami|winnt|winnt32|winpop|winrm|winrs|winsat|wlbs|wmic|wscript|wsl|xcopy)(?=$|\\s)", "name": "keyword.command.batchfile" }, { "begin": "(?i)(?<=^|[\\s@])(echo)(?:(?=$|\\.|:)|\\s+(?:(on|off)(?=\\s*$))?)", "beginCaptures": { "1": { "name": "keyword.command.batchfile" }, "2": { "name": "keyword.other.special-method.batchfile" } }, "end": "(?=$\\n|[&|><)])", "patterns": [ { "include": "#escaped_characters" }, { "include": "#variables" }, { "include": "#numbers" }, { "include": "#strings" } ] }, { "match": "(?i)(?<=^|[\\s@])(setlocal)(?:\\s*$|\\s+(EnableExtensions|DisableExtensions|EnableDelayedExpansion|DisableDelayedExpansion)(?=\\s*$))", "captures": { "1": { "name": "keyword.command.batchfile" }, "2": { "name": "keyword.other.special-method.batchfile" } } }, { "include": "#command_set" } ] }, "command_set": { "patterns": [ { "begin": "(?<=^|[\\s@])(?i:SET)(?=$|\\s)", "beginCaptures": { "0": { "name": "keyword.command.batchfile" } }, "end": "(?=$\\n|[&|><)])", "patterns": [ { "include": "#command_set_inside" } ] } ] }, "command_set_inside": { "patterns": [ { "include": "#escaped_characters" }, { "include": "#variables" }, { "include": "#numbers" }, { "include": "#parens" }, { "include": "#command_set_strings" }, { "include": "#strings" }, { "begin": "([^ ][^=]*)(=)", "beginCaptures": { "1": { "name": "variable.other.readwrite.batchfile" }, "2": { "name": "keyword.operator.assignment.batchfile" } }, "end": "(?=$\\n|[&|><)])", "patterns": [ { "include": "#escaped_characters" }, { "include": "#variables" }, { "include": "#numbers" }, { "include": "#parens" }, { "include": "#strings" } ] }, { "begin": "\\s+/[aA]\\s+", "end": "(?=$\\n|[&|><)])", "name": "meta.expression.set.batchfile", "patterns": [ { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.batchfile" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.batchfile" } }, "name": "string.quoted.double.batchfile", "patterns": [ { "include": "#command_set_inside_arithmetic" }, { "include": "#command_set_group" }, { "include": "#variables" } ] }, { "include": "#command_set_inside_arithmetic" }, { "include": "#command_set_group" } ] }, { "begin": "\\s+/[pP]\\s+", "end": "(?=$\\n|[&|><)])", "patterns": [ { "include": "#command_set_strings" }, { "begin": "([^ ][^=]*)(=)", "beginCaptures": { "1": { "name": "variable.other.readwrite.batchfile" }, "2": { "name": "keyword.operator.assignment.batchfile" } }, "end": "(?=$\\n|[&|><)])", "name": "meta.prompt.set.batchfile", "patterns": [ { "include": "#strings" } ] } ] } ] }, "command_set_group": { "patterns": [ { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.group.begin.batchfile" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.group.end.batchfile" } }, "patterns": [ { "include": "#command_set_inside_arithmetic" } ] } ] }, "command_set_inside_arithmetic": { "patterns": [ { "include": "#command_set_operators" }, { "include": "#numbers" }, { "match": ",", "name": "punctuation.separator.batchfile" } ] }, "command_set_operators": { "patterns": [ { "match": "([^ ]*)(\\+\\=|\\-\\=|\\*\\=|\\/\\=|%%\\=|&\\=|\\|\\=|\\^\\=|<<\\=|>>\\=)", "captures": { "1": { "name": "variable.other.readwrite.batchfile" }, "2": { "name": "keyword.operator.assignment.augmented.batchfile" } } }, { "match": "\\+|\\-|/|\\*|%%|\\||&|\\^|<<|>>|~", "name": "keyword.operator.arithmetic.batchfile" }, { "match": "!", "name": "keyword.operator.logical.batchfile" }, { "match": "([^ =]*)(=)", "captures": { "1": { "name": "variable.other.readwrite.batchfile" }, "2": { "name": "keyword.operator.assignment.batchfile" } } } ] }, "command_set_strings": { "patterns": [ { "begin": "(\")\\s*([^ ][^=]*)(=)", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.batchfile" }, "2": { "name": "variable.other.readwrite.batchfile" }, "3": { "name": "keyword.operator.assignment.batchfile" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.batchfile" } }, "name": "string.quoted.double.batchfile", "patterns": [ { "include": "#variables" }, { "include": "#numbers" }, { "include": "#escaped_characters" } ] } ] }, "comments": { "patterns": [ { "begin": "(?:^|(&))\\s*(?=((?::[+=,;: ])))", "beginCaptures": { "1": { "name": "keyword.operator.conditional.batchfile" } }, "end": "\\n", "patterns": [ { "begin": "((?::[+=,;: ]))", "beginCaptures": { "1": { "name": "punctuation.definition.comment.batchfile" } }, "end": "(?=\\n)", "name": "comment.line.colon.batchfile" } ] }, { "begin": "(?<=^|[\\s@])(?i)(REM)(\\.)", "beginCaptures": { "1": { "name": "keyword.command.rem.batchfile" }, "2": { "name": "punctuation.separator.batchfile" } }, "end": "(?=$\\n|[&|><)])", "name": "comment.line.rem.batchfile" }, { "begin": "(?<=^|[\\s@])(?i:rem)\\b", "beginCaptures": { "0": { "name": "keyword.command.rem.batchfile" } }, "end": "\\n", "name": "comment.line.rem.batchfile", "patterns": [ { "match": "[><|]", "name": "invalid.illegal.unexpected-character.batchfile" } ] } ] }, "constants": { "patterns": [ { "match": "\\b(?i:NUL)\\b", "name": "constant.language.batchfile" } ] }, "controls": { "patterns": [ { "match": "(?i)(?<=^|\\s)(?:call|exit(?=$|\\s)|goto(?=$|\\s|:))", "name": "keyword.control.statement.batchfile" }, { "match": "(?<=^|\\s)(?i)(if)\\s+(?:(not)\\s+)?(exist|defined|errorlevel|cmdextversion)(?=\\s)", "captures": { "1": { "name": "keyword.control.conditional.batchfile" }, "2": { "name": "keyword.operator.logical.batchfile" }, "3": { "name": "keyword.other.special-method.batchfile" } } }, { "match": "(?<=^|\\s)(?i)(?:if|else)(?=$|\\s)", "name": "keyword.control.conditional.batchfile" }, { "begin": "(?<=^|[\\s(&^])(?i)for(?=\\s)", "beginCaptures": { "0": { "name": "keyword.control.repeat.batchfile" } }, "name": "meta.block.repeat.batchfile", "end": "\\n", "patterns": [ { "begin": "(?<=[\\s^])(?i)in(?=\\s)", "beginCaptures": { "0": { "name": "keyword.control.repeat.in.batchfile" } }, "end": "(?<=[\\s)^])(?i)do(?=\\s)|\\n", "endCaptures": { "0": { "name": "keyword.control.repeat.do.batchfile" } }, "patterns": [ { "include": "$self" } ] }, { "include": "$self" } ] } ] }, "escaped_characters": { "patterns": [ { "match": "%%|\\^\\^!|\\^(?=.)|\\^\\n", "name": "constant.character.escape.batchfile" } ] }, "labels": { "patterns": [ { "match": "(?i)(?:^\\s*|(?<=call|goto)\\s*)(:)([^+=,;:\\s]\\S*)", "captures": { "1": { "name": "punctuation.separator.batchfile" }, "2": { "name": "keyword.other.special-method.batchfile" } } } ] }, "numbers": { "patterns": [ { "match": "(?<=^|\\s|=)(0[xX][0-9A-Fa-f]*|[+-]?\\d+)(?=$|\\s|<|>)", "name": "constant.numeric.batchfile" } ] }, "operators": { "patterns": [ { "match": "@(?=\\S)", "name": "keyword.operator.at.batchfile" }, { "match": "(?<=\\s)(?i:EQU|NEQ|LSS|LEQ|GTR|GEQ)(?=\\s)|==", "name": "keyword.operator.comparison.batchfile" }, { "match": "(?<=\\s)(?i)(NOT)(?=\\s)", "name": "keyword.operator.logical.batchfile" }, { "match": "(?[&>]?", "name": "keyword.operator.redirection.batchfile" } ] }, "parens": { "patterns": [ { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.group.begin.batchfile" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.group.end.batchfile" } }, "name": "meta.group.batchfile", "patterns": [ { "match": ",|;", "name": "punctuation.separator.batchfile" }, { "include": "$self" } ] } ] }, "repeatParameter": { "patterns": [ { "match": "(%%)(?:(?i:~[fdpnxsatz]*(?:\\$PATH:)?)?[a-zA-Z])", "captures": { "1": { "name": "punctuation.definition.variable.batchfile" } }, "name": "variable.parameter.repeat.batchfile" } ] }, "strings": { "patterns": [ { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.batchfile" } }, "end": "(\")|(\\n)", "endCaptures": { "1": { "name": "punctuation.definition.string.end.batchfile" }, "2": { "name": "invalid.illegal.newline.batchfile" } }, "name": "string.quoted.double.batchfile", "patterns": [ { "match": "%%", "name": "constant.character.escape.batchfile" }, { "include": "#variables" } ] } ] }, "variables": { "patterns": [ { "match": "(%)(?:(?i:~[fdpnxsatz]*(?:\\$PATH:)?)?\\d|\\*)", "captures": { "1": { "name": "punctuation.definition.variable.batchfile" } }, "name": "variable.parameter.batchfile" }, { "include": "#variable" }, { "include": "#variable_delayed_expansion" } ] }, "variable": { "patterns": [ { "begin": "%(?=[^%]+%)", "beginCaptures": { "0": { "name": "punctuation.definition.variable.begin.batchfile" } }, "end": "(%)|\\n", "endCaptures": { "1": { "name": "punctuation.definition.variable.end.batchfile" } }, "name": "variable.other.readwrite.batchfile", "patterns": [ { "begin": ":~", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=%|\\n)", "name": "meta.variable.substring.batchfile", "patterns": [ { "include": "#variable_substring" } ] }, { "begin": ":", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=%|\\n)", "name": "meta.variable.substitution.batchfile", "patterns": [ { "include": "#variable_replace" }, { "begin": "=", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=%|\\n)", "patterns": [ { "include": "#variable_delayed_expansion" }, { "match": "[^%]+", "name": "string.unquoted.batchfile" } ] } ] } ] } ] }, "variable_delayed_expansion": { "patterns": [ { "begin": "!(?=[^!]+!)", "beginCaptures": { "0": { "name": "punctuation.definition.variable.begin.batchfile" } }, "end": "(!)|\\n", "endCaptures": { "1": { "name": "punctuation.definition.variable.end.batchfile" } }, "name": "variable.other.readwrite.batchfile", "patterns": [ { "begin": ":~", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=!|\\n)", "name": "meta.variable.substring.batchfile", "patterns": [ { "include": "#variable_substring" } ] }, { "begin": ":", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=!|\\n)", "name": "meta.variable.substitution.batchfile", "patterns": [ { "include": "#escaped_characters" }, { "include": "#variable_replace" }, { "include": "#variable" }, { "begin": "=", "beginCaptures": { "0": { "name": "punctuation.separator.batchfile" } }, "end": "(?=!|\\n)", "patterns": [ { "include": "#variable" }, { "match": "[^!]+", "name": "string.unquoted.batchfile" } ] } ] } ] } ] }, "variable_replace": { "patterns": [ { "match": "[^=%!\\n]+", "name": "string.unquoted.batchfile" } ] }, "variable_substring": { "patterns": [ { "match": "([+-]?\\d+)(?:(,)([+-]?\\d+))?", "captures": { "1": { "name": "constant.numeric.batchfile" }, "2": { "name": "punctuation.separator.batchfile" }, "3": { "name": "constant.numeric.batchfile" } } } ] } } } ================================================ FILE: extensions/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "typescript", "repositoryUrl": "https://github.com/microsoft/TypeScript", "commitHash": "54426a14f4c232da8e563d20ca8e71263e1c96b5" } }, "isOnlyProductionDependency": true, "license": "Apache-2.0", "version": "2.6.2" } ], "version": 1 } ================================================ FILE: extensions/clojure/.vscodeignore ================================================ test/** cgmanifest.json ================================================ FILE: extensions/clojure/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "atom/language-clojure", "repositoryUrl": "https://github.com/atom/language-clojure", "commitHash": "45bdb881501d0b8f8b707ca1d3fcc8b4b99fca03" } }, "license": "MIT", "version": "0.22.8", "description": "The file syntaxes/clojure.tmLanguage.json was derived from the Atom package https://github.com/atom/language-clojure which was originally converted from the TextMate bundle https://github.com/mmcgrana/textmate-clojure." } ], "version": 1 } ================================================ FILE: extensions/clojure/language-configuration.json ================================================ { "comments": { "lineComment": ";;" }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], { "open": "\"", "close": "\"", "notIn": ["string"] } ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["\"", "\""] ], "folding": { "offSide": true } } ================================================ FILE: extensions/clojure/package.json ================================================ { "name": "clojure", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "*" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-clojure grammars/clojure.cson ./syntaxes/clojure.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "clojure", "aliases": [ "Clojure", "clojure" ], "extensions": [ ".clj", ".cljs", ".cljc", ".cljx", ".clojure", ".edn" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "clojure", "scopeName": "source.clojure", "path": "./syntaxes/clojure.tmLanguage.json" } ], "configurationDefaults": { "[clojure]": { "diffEditor.ignoreTrimWhitespace": false } } }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/clojure/package.nls.json ================================================ { "displayName": "Clojure Language Basics", "description": "Provides syntax highlighting and bracket matching in Clojure files." } ================================================ FILE: extensions/clojure/syntaxes/clojure.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/atom/language-clojure/blob/master/grammars/clojure.cson", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/atom/language-clojure/commit/45bdb881501d0b8f8b707ca1d3fcc8b4b99fca03", "name": "Clojure", "scopeName": "source.clojure", "patterns": [ { "include": "#comment" }, { "include": "#shebang-comment" }, { "include": "#quoted-sexp" }, { "include": "#sexp" }, { "include": "#keyfn" }, { "include": "#string" }, { "include": "#vector" }, { "include": "#set" }, { "include": "#map" }, { "include": "#regexp" }, { "include": "#var" }, { "include": "#constants" }, { "include": "#dynamic-variables" }, { "include": "#metadata" }, { "include": "#namespace-symbol" }, { "include": "#symbol" } ], "repository": { "comment": { "begin": "(?\\<\\/\\!\\?\\*]+(?=(\\s|\\)|\\]|\\}|\\,))", "name": "constant.keyword.clojure" }, "keyfn": { "patterns": [ { "match": "(?<=(\\s|\\(|\\[|\\{))(if(-[-\\p{Ll}\\?]*)?|when(-[-\\p{Ll}]*)?|for(-[-\\p{Ll}]*)?|cond|do|let(-[-\\p{Ll}\\?]*)?|binding|loop|recur|fn|throw[\\p{Ll}\\-]*|try|catch|finally|([\\p{Ll}]*case))(?=(\\s|\\)|\\]|\\}))", "name": "storage.control.clojure" }, { "match": "(?<=(\\s|\\(|\\[|\\{))(declare-?|(in-)?ns|import|use|require|load|compile|(def[\\p{Ll}\\-]*))(?=(\\s|\\)|\\]|\\}))", "name": "keyword.control.clojure" } ] }, "dynamic-variables": { "match": "\\*[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\d]+\\*", "name": "meta.symbol.dynamic.clojure" }, "map": { "begin": "(\\{)", "beginCaptures": { "1": { "name": "punctuation.section.map.begin.clojure" } }, "end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})", "endCaptures": { "1": { "name": "punctuation.section.map.end.trailing.clojure" }, "2": { "name": "punctuation.section.map.end.clojure" } }, "name": "meta.map.clojure", "patterns": [ { "include": "$self" } ] }, "metadata": { "patterns": [ { "begin": "(\\^\\{)", "beginCaptures": { "1": { "name": "punctuation.section.metadata.map.begin.clojure" } }, "end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})", "endCaptures": { "1": { "name": "punctuation.section.metadata.map.end.trailing.clojure" }, "2": { "name": "punctuation.section.metadata.map.end.clojure" } }, "name": "meta.metadata.map.clojure", "patterns": [ { "include": "$self" } ] }, { "begin": "(\\^)", "end": "(\\s)", "name": "meta.metadata.simple.clojure", "patterns": [ { "include": "#keyword" }, { "include": "$self" } ] } ] }, "quoted-sexp": { "begin": "(['``]\\()", "beginCaptures": { "1": { "name": "punctuation.section.expression.begin.clojure" } }, "end": "(\\))$|(\\)(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\))", "endCaptures": { "1": { "name": "punctuation.section.expression.end.trailing.clojure" }, "2": { "name": "punctuation.section.expression.end.trailing.clojure" }, "3": { "name": "punctuation.section.expression.end.clojure" } }, "name": "meta.quoted-expression.clojure", "patterns": [ { "include": "$self" } ] }, "regexp": { "begin": "#\"", "beginCaptures": { "0": { "name": "punctuation.definition.regexp.begin.clojure" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.definition.regexp.end.clojure" } }, "name": "string.regexp.clojure", "patterns": [ { "include": "#regexp_escaped_char" } ] }, "regexp_escaped_char": { "match": "\\\\.", "name": "constant.character.escape.clojure" }, "set": { "begin": "(\\#\\{)", "beginCaptures": { "1": { "name": "punctuation.section.set.begin.clojure" } }, "end": "(\\}(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\})", "endCaptures": { "1": { "name": "punctuation.section.set.end.trailing.clojure" }, "2": { "name": "punctuation.section.set.end.clojure" } }, "name": "meta.set.clojure", "patterns": [ { "include": "$self" } ] }, "sexp": { "begin": "(\\()", "beginCaptures": { "1": { "name": "punctuation.section.expression.begin.clojure" } }, "end": "(\\))$|(\\)(?=[\\}\\]\\)\\s]*(?:;|$)))|(\\))", "endCaptures": { "1": { "name": "punctuation.section.expression.end.trailing.clojure" }, "2": { "name": "punctuation.section.expression.end.trailing.clojure" }, "3": { "name": "punctuation.section.expression.end.clojure" } }, "name": "meta.expression.clojure", "patterns": [ { "begin": "(?<=\\()(ns|declare|def[\\w\\d._:+=>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)", "name": "entity.global.clojure" }, { "include": "$self" } ] }, { "include": "#keyfn" }, { "include": "#constants" }, { "include": "#vector" }, { "include": "#map" }, { "include": "#set" }, { "include": "#sexp" }, { "match": "(?<=\\()(.+?)(?=\\s|\\))", "captures": { "1": { "name": "entity.name.function.clojure" } }, "patterns": [ { "include": "$self" } ] }, { "include": "$self" } ] }, "shebang-comment": { "begin": "^(#!)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.shebang.clojure" } }, "end": "$", "name": "comment.line.shebang.clojure" }, "string": { "begin": "(?\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)/", "captures": { "1": { "name": "meta.symbol.namespace.clojure" } } } ] }, "symbol": { "patterns": [ { "match": "([\\p{L}\\.\\-\\_\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)", "name": "meta.symbol.clojure" } ] }, "var": { "match": "(?<=(\\s|\\(|\\[|\\{)\\#)'[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\/\\!\\?\\*]+(?=(\\s|\\)|\\]|\\}))", "name": "meta.var.clojure" }, "vector": { "begin": "(\\[)", "beginCaptures": { "1": { "name": "punctuation.section.vector.begin.clojure" } }, "end": "(\\](?=[\\}\\]\\)\\s]*(?:;|$)))|(\\])", "endCaptures": { "1": { "name": "punctuation.section.vector.end.trailing.clojure" }, "2": { "name": "punctuation.section.vector.end.clojure" } }, "name": "meta.vector.clojure", "patterns": [ { "include": "$self" } ] } } } ================================================ FILE: extensions/coffeescript/.vscodeignore ================================================ test/** cgmanifest.json ================================================ FILE: extensions/coffeescript/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "atom/language-coffee-script", "repositoryUrl": "https://github.com/atom/language-coffee-script", "commitHash": "0f6db9143663e18b1ad00667820f46747dba495e" } }, "license": "MIT", "description": "The file syntaxes/coffeescript.tmLanguage.json was derived from the Atom package https://github.com/atom/language-coffee-script which was originally converted from the TextMate bundle https://github.com/jashkenas/coffee-script-tmbundle.", "version": "0.49.3" } ], "version": 1 } ================================================ FILE: extensions/coffeescript/language-configuration.json ================================================ { "comments": { "lineComment": "#", "blockComment": [ "###", "###" ] }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], { "open": "\"", "close": "\"", "notIn": ["string"] }, { "open": "'", "close": "'", "notIn": ["string"] } ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["\"", "\""], ["'", "'"], [" ", " "] ], "folding": { "offSide": true, "markers": { "start": "^\\s*#region\\b", "end": "^\\s*#endregion\\b" } } } ================================================ FILE: extensions/coffeescript/package.json ================================================ { "name": "coffeescript", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "*" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-coffee-script grammars/coffeescript.cson ./syntaxes/coffeescript.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "coffeescript", "extensions": [ ".coffee", ".cson", ".iced" ], "aliases": [ "CoffeeScript", "coffeescript", "coffee" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "coffeescript", "scopeName": "source.coffee", "path": "./syntaxes/coffeescript.tmLanguage.json" } ], "breakpoints": [ { "language": "coffeescript" } ], "snippets": [ { "language": "coffeescript", "path": "./snippets/coffeescript.code-snippets" } ], "configurationDefaults": { "[coffeescript]": { "diffEditor.ignoreTrimWhitespace": false, "editor.defaultColorDecorators": "never" } } }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/coffeescript/package.nls.json ================================================ { "displayName": "CoffeeScript Language Basics", "description": "Provides snippets, syntax highlighting, bracket matching and folding in CoffeeScript files." } ================================================ FILE: extensions/coffeescript/snippets/coffeescript.code-snippets ================================================ { "Region Start": { "prefix": "#region", "body": [ "#region" ], "description": "Folding Region Start" }, "Region End": { "prefix": "#endregion", "body": [ "#endregion" ], "description": "Folding Region End" } } ================================================ FILE: extensions/coffeescript/syntaxes/coffeescript.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/atom/language-coffee-script/blob/master/grammars/coffeescript.cson", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/atom/language-coffee-script/commit/0f6db9143663e18b1ad00667820f46747dba495e", "name": "CoffeeScript", "scopeName": "source.coffee", "patterns": [ { "include": "#jsx" }, { "match": "(new)\\s+(?:(?:(class)\\s+(\\w+(?:\\.\\w*)*)?)|(\\w+(?:\\.\\w*)*))", "name": "meta.class.instance.constructor.coffee", "captures": { "1": { "name": "keyword.operator.new.coffee" }, "2": { "name": "storage.type.class.coffee" }, "3": { "name": "entity.name.type.instance.coffee" }, "4": { "name": "entity.name.type.instance.coffee" } } }, { "begin": "'''", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.coffee" } }, "end": "'''", "endCaptures": { "0": { "name": "punctuation.definition.string.end.coffee" } }, "name": "string.quoted.single.heredoc.coffee", "patterns": [ { "captures": { "1": { "name": "punctuation.definition.escape.backslash.coffee" } }, "match": "(\\\\).", "name": "constant.character.escape.backslash.coffee" } ] }, { "begin": "\"\"\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.coffee" } }, "end": "\"\"\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.coffee" } }, "name": "string.quoted.double.heredoc.coffee", "patterns": [ { "captures": { "1": { "name": "punctuation.definition.escape.backslash.coffee" } }, "match": "(\\\\).", "name": "constant.character.escape.backslash.coffee" }, { "include": "#interpolated_coffee" } ] }, { "match": "(`)(.*)(`)", "name": "string.quoted.script.coffee", "captures": { "1": { "name": "punctuation.definition.string.begin.coffee" }, "2": { "name": "source.js.embedded.coffee", "patterns": [ { "include": "source.js" } ] }, "3": { "name": "punctuation.definition.string.end.coffee" } } }, { "begin": "(?)", "beginCaptures": { "1": { "name": "entity.name.function.coffee" }, "2": { "name": "variable.other.readwrite.instance.coffee" }, "3": { "name": "keyword.operator.assignment.coffee" } }, "end": "[=-]>", "endCaptures": { "0": { "name": "storage.type.function.coffee" } }, "name": "meta.function.coffee", "patterns": [ { "include": "#function_params" } ] }, { "begin": "(?x)\n(?<=\\s|^)(?:((')([^']*?)('))|((\")([^\"]*?)(\")))\n\\s*([:=])\\s*\n(?=(\\([^\\(\\)]*\\)\\s*)?[=-]>)", "beginCaptures": { "1": { "name": "string.quoted.single.coffee" }, "2": { "name": "punctuation.definition.string.begin.coffee" }, "3": { "name": "entity.name.function.coffee" }, "4": { "name": "punctuation.definition.string.end.coffee" }, "5": { "name": "string.quoted.double.coffee" }, "6": { "name": "punctuation.definition.string.begin.coffee" }, "7": { "name": "entity.name.function.coffee" }, "8": { "name": "punctuation.definition.string.end.coffee" }, "9": { "name": "keyword.operator.assignment.coffee" } }, "end": "[=-]>", "endCaptures": { "0": { "name": "storage.type.function.coffee" } }, "name": "meta.function.coffee", "patterns": [ { "include": "#function_params" } ] }, { "begin": "(?=(\\([^\\(\\)]*\\)\\s*)?[=-]>)", "end": "[=-]>", "endCaptures": { "0": { "name": "storage.type.function.coffee" } }, "name": "meta.function.inline.coffee", "patterns": [ { "include": "#function_params" } ] }, { "begin": "(?<=\\s|^)({)(?=[^'\"#]+?}[\\s\\]}]*=)", "beginCaptures": { "1": { "name": "punctuation.definition.destructuring.begin.bracket.curly.coffee" } }, "end": "}", "endCaptures": { "0": { "name": "punctuation.definition.destructuring.end.bracket.curly.coffee" } }, "name": "meta.variable.assignment.destructured.object.coffee", "patterns": [ { "include": "$self" }, { "match": "[a-zA-Z$_]\\w*", "name": "variable.assignment.coffee" } ] }, { "begin": "(?<=\\s|^)(\\[)(?=[^'\"#]+?\\][\\s\\]}]*=)", "beginCaptures": { "1": { "name": "punctuation.definition.destructuring.begin.bracket.square.coffee" } }, "end": "\\]", "endCaptures": { "0": { "name": "punctuation.definition.destructuring.end.bracket.square.coffee" } }, "name": "meta.variable.assignment.destructured.array.coffee", "patterns": [ { "include": "$self" }, { "match": "[a-zA-Z$_]\\w*", "name": "variable.assignment.coffee" } ] }, { "match": "\\b(?|\\-\\d|\\[|{|\"|'))", "end": "(?=\\s*(?|\\-\\d|\\[|{|\"|')))", "beginCaptures": { "1": { "name": "variable.other.readwrite.instance.coffee" }, "2": { "patterns": [ { "include": "#function_names" } ] } }, "end": "(?=\\s*(?|\\-\\d|\\[|{|\"|')))", "beginCaptures": { "1": { "name": "punctuation.separator.method.period.coffee" }, "2": { "name": "keyword.operator.prototype.coffee" }, "3": { "patterns": [ { "include": "#method_names" } ] } }, "end": "(?=\\s*(?>=|>>>=|\\|=)", "captures": { "1": { "name": "variable.assignment.coffee" }, "2": { "name": "keyword.operator.assignment.compound.bitwise.coffee" } } }, { "match": "<<|>>>|>>", "name": "keyword.operator.bitwise.shift.coffee" }, { "match": "!=|<=|>=|==|<|>", "name": "keyword.operator.comparison.coffee" }, { "match": "&&|!|\\|\\|", "name": "keyword.operator.logical.coffee" }, { "match": "&|\\||\\^|~", "name": "keyword.operator.bitwise.coffee" }, { "match": "([a-zA-Z$_][\\w$]*)?\\s*(=|:(?!:))(?![>=])", "captures": { "1": { "name": "variable.assignment.coffee" }, "2": { "name": "keyword.operator.assignment.coffee" } } }, { "match": "--", "name": "keyword.operator.decrement.coffee" }, { "match": "\\+\\+", "name": "keyword.operator.increment.coffee" }, { "match": "\\.\\.\\.", "name": "keyword.operator.splat.coffee" }, { "match": "\\?", "name": "keyword.operator.existential.coffee" }, { "match": "%|\\*|/|-|\\+", "name": "keyword.operator.coffee" }, { "match": "(?x)\n\\b(?)", "name": "meta.tag.coffee", "patterns": [ { "include": "#jsx-attribute" } ] } ] }, "jsx-end-tag": { "patterns": [ { "begin": "()", "name": "meta.tag.coffee" } ] } } } ================================================ FILE: extensions/configuration-editing/.npmrc ================================================ legacy-peer-deps="true" timeout=180000 ================================================ FILE: extensions/configuration-editing/.vscodeignore ================================================ test/** src/** tsconfig.json out/** extension.webpack.config.js extension-browser.webpack.config.js package-lock.json build/** schemas/devContainer.codespaces.schema.json schemas/devContainer.vscode.schema.json ================================================ FILE: extensions/configuration-editing/extension-browser.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const path = require('path'); const withBrowserDefaults = require('../shared.webpack.config').browser; module.exports = withBrowserDefaults({ context: __dirname, entry: { extension: './src/configurationEditingMain.ts' }, output: { filename: 'configurationEditingMain.js' }, resolve: { alias: { './node/net': path.resolve(__dirname, 'src', 'browser', 'net'), } } }); ================================================ FILE: extensions/configuration-editing/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withDefaults = require('../shared.webpack.config'); module.exports = withDefaults({ context: __dirname, entry: { extension: './src/configurationEditingMain.ts', }, output: { filename: 'configurationEditingMain.js' }, resolve: { mainFields: ['module', 'main'] } }); ================================================ FILE: extensions/configuration-editing/package.json ================================================ { "name": "configuration-editing", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.0.0" }, "icon": "images/icon.png", "activationEvents": [ "onProfile", "onProfile:github", "onLanguage:json", "onLanguage:jsonc" ], "enabledApiProposals": [ "profileContentHandlers" ], "main": "./out/configurationEditingMain", "browser": "./dist/browser/configurationEditingMain", "scripts": { "compile": "gulp compile-extension:configuration-editing", "watch": "gulp watch-extension:configuration-editing" }, "dependencies": { "@octokit/rest": "^21.1.1", "jsonc-parser": "^3.2.0", "tunnel": "^0.0.6" }, "capabilities": { "virtualWorkspaces": true, "untrustedWorkspaces": { "supported": true } }, "contributes": { "languages": [ { "id": "jsonc", "extensions": [ ".code-workspace", "language-configuration.json", "icon-theme.json", "color-theme.json" ], "filenames": [ "settings.json", "launch.json", "tasks.json", "mcp.json", "keybindings.json", "extensions.json", "argv.json", "profiles.json", "devcontainer.json", ".devcontainer.json" ] }, { "id": "json", "extensions": [ ".code-profile" ] } ], "jsonValidation": [ { "fileMatch": "vscode://defaultsettings/keybindings.json", "url": "vscode://schemas/keybindings" }, { "fileMatch": "%APP_SETTINGS_HOME%/keybindings.json", "url": "vscode://schemas/keybindings" }, { "fileMatch": "%APP_SETTINGS_HOME%/profiles/*/keybindings.json", "url": "vscode://schemas/keybindings" }, { "fileMatch": "vscode://defaultsettings/*.json", "url": "vscode://schemas/settings/default" }, { "fileMatch": "%APP_SETTINGS_HOME%/settings.json", "url": "vscode://schemas/settings/user" }, { "fileMatch": "%APP_SETTINGS_HOME%/profiles/*/settings.json", "url": "vscode://schemas/settings/profile" }, { "fileMatch": "%MACHINE_SETTINGS_HOME%/settings.json", "url": "vscode://schemas/settings/machine" }, { "fileMatch": "%APP_WORKSPACES_HOME%/*/workspace.json", "url": "vscode://schemas/workspaceConfig" }, { "fileMatch": "**/*.code-workspace", "url": "vscode://schemas/workspaceConfig" }, { "fileMatch": "**/argv.json", "url": "vscode://schemas/argv" }, { "fileMatch": "/.vscode/settings.json", "url": "vscode://schemas/settings/folder" }, { "fileMatch": "/.vscode/launch.json", "url": "vscode://schemas/launch" }, { "fileMatch": "/.vscode/tasks.json", "url": "vscode://schemas/tasks" }, { "fileMatch": "/.vscode/mcp.json", "url": "vscode://schemas/mcp" }, { "fileMatch": "%APP_SETTINGS_HOME%/tasks.json", "url": "vscode://schemas/tasks" }, { "fileMatch": "%APP_SETTINGS_HOME%/snippets/*.json", "url": "vscode://schemas/snippets" }, { "fileMatch": "%APP_SETTINGS_HOME%/profiles/*/snippets/.json", "url": "vscode://schemas/snippets" }, { "fileMatch": "%APP_SETTINGS_HOME%/sync/snippets/preview/*.json", "url": "vscode://schemas/snippets" }, { "fileMatch": "**/*.code-snippets", "url": "vscode://schemas/global-snippets" }, { "fileMatch": "/.vscode/extensions.json", "url": "vscode://schemas/extensions" }, { "fileMatch": "devcontainer.json", "url": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json" }, { "fileMatch": ".devcontainer.json", "url": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json" }, { "fileMatch": "%APP_SETTINGS_HOME%/globalStorage/ms-vscode-remote.remote-containers/nameConfigs/*.json", "url": "./schemas/attachContainer.schema.json" }, { "fileMatch": "%APP_SETTINGS_HOME%/globalStorage/ms-vscode-remote.remote-containers/imageConfigs/*.json", "url": "./schemas/attachContainer.schema.json" }, { "fileMatch": "**/quality/*/product.json", "url": "vscode://schemas/vscode-product" } ] }, "devDependencies": { "@types/node": "20.x" }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/configuration-editing/package.nls.json ================================================ { "displayName": "Configuration Editing", "description": "Provides capabilities (advanced IntelliSense, auto-fixing) in configuration files like settings, launch, and extension recommendation files." } ================================================ FILE: extensions/configuration-editing/schemas/attachContainer.schema.json ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "description": "Configures an attached to container", "allowComments": true, "allowTrailingCommas": true, "type": "object", "definitions": { "attachContainer": { "type": "object", "properties": { "workspaceFolder": { "type": "string", "description": "The path of the workspace folder inside the container." }, "forwardPorts": { "type": "array", "description": "Ports that are forwarded from the container to the local machine. Can be an integer port number, or a string of the format \"host:port_number\".", "items": { "oneOf": [ { "type": "integer", "maximum": 65535, "minimum": 0 }, { "type": "string", "pattern": "^([a-z0-9_-]+):(\\d{1,5})$" } ] } }, "portsAttributes": { "type": "object", "patternProperties": { "(^\\d+(-\\d+)?$)|(.+)": { "type": "object", "description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.", "properties": { "onAutoForward": { "type": "string", "enum": [ "notify", "openBrowser", "openBrowserOnce", "openPreview", "silent", "ignore" ], "enumDescriptions": [ "Shows a notification when a port is automatically forwarded.", "Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.", "Opens the browser when the port is automatically forwarded, but only the first time the port is forward during a session. Depending on your settings, this could open an embedded browser.", "Opens a preview in the same window when the port is automatically forwarded.", "Shows no notification and takes no action when this port is automatically forwarded.", "This port will not be automatically forwarded." ], "description": "Defines the action that occurs when the port is discovered for automatic forwarding", "default": "notify" }, "elevateIfNeeded": { "type": "boolean", "description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.", "default": false }, "label": { "type": "string", "description": "Label that will be shown in the UI for this port.", "default": "Application" }, "requireLocalPort": { "type": "boolean", "markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.", "default": false }, "protocol": { "type": "string", "enum": [ "http", "https" ], "description": "The protocol to use when forwarding this port." } }, "default": { "label": "Application", "onAutoForward": "notify" } } }, "markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Application\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n},\n\".+\\\\/server.js\": {\n \"onAutoForward\": \"openPreview\"\n}\n```", "defaultSnippets": [ { "body": { "${1:3000}": { "label": "${2:Application}", "onAutoForward": "notify" } } } ], "additionalProperties": false }, "otherPortsAttributes": { "type": "object", "properties": { "onAutoForward": { "type": "string", "enum": [ "notify", "openBrowser", "openPreview", "silent", "ignore" ], "enumDescriptions": [ "Shows a notification when a port is automatically forwarded.", "Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.", "Opens a preview in the same window when the port is automatically forwarded.", "Shows no notification and takes no action when this port is automatically forwarded.", "This port will not be automatically forwarded." ], "description": "Defines the action that occurs when the port is discovered for automatic forwarding", "default": "notify" }, "elevateIfNeeded": { "type": "boolean", "description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.", "default": false }, "label": { "type": "string", "description": "Label that will be shown in the UI for this port.", "default": "Application" }, "requireLocalPort": { "type": "boolean", "markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.", "default": false }, "protocol": { "type": "string", "enum": [ "http", "https" ], "description": "The protocol to use when forwarding this port." } }, "defaultSnippets": [ { "body": { "onAutoForward": "ignore" } } ], "markdownDescription": "Set default properties that are applied to all ports that don't get properties from the setting `remote.portsAttributes`. For example:\n\n```\n{\n \"onAutoForward\": \"ignore\"\n}\n```", "additionalProperties": false }, "settings": { "$ref": "vscode://schemas/settings/machine", "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time." }, "remoteEnv": { "type": "object", "additionalProperties": { "type": [ "string", "null" ] }, "description": "Remote environment variables. If these are used in the Integrated Terminal, make sure the 'Terminal > Integrated: Inherit Env' setting is enabled." }, "remoteUser": { "type": "string", "description": "The user VS Code Server will be started with. The default is the same user as the container." }, "extensions": { "type": "array", "description": "An array of extensions that should be installed into the container.", "items": { "type": "string", "pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." } }, "userEnvProbe": { "type": "string", "enum": [ "none", "loginShell", "loginInteractiveShell", "interactiveShell" ], "description": "User environment probe to run. The default is none." }, "postAttachCommand": { "type": [ "string", "array" ], "description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.", "items": { "type": "string" } } } } }, "allOf": [ { "$ref": "#/definitions/attachContainer" } ] } ================================================ FILE: extensions/configuration-editing/schemas/devContainer.codespaces.schema.json ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "customizations": { "type": "object", "properties": { "codespaces": { "type": "object", "description": "Customizations specific to GitHub Codespaces", "properties": { "repositories": { "type": "object", "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", "patternProperties": { "^[a-zA-Z0-9-_.]+[.]*\/[a-zA-Z0-9-_*]+[.]*$": { "type": "object", "additionalProperties": true, "oneOf": [ { "properties": { "permissions": { "type": "object", "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", "additionalProperties": true, "anyOf": [ { "properties": { "actions": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "checks": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "contents": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "deployments": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "discussions": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "issues": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "packages": { "type": "string", "enum": [ "read" ] } } }, { "properties": { "pages": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "pull_requests": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "repository_projects": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "statuses": { "type": "string", "enum": [ "read", "write" ] } } }, { "properties": { "workflows": { "type": "string", "enum": [ "write" ] } } } ] } } }, { "properties": { "permissions": { "type": "string", "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", "enum": [ "read-all", "write-all" ] } } } ] } } }, "openFiles": { "type": "array", "description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.", "items": { "type": "string" } }, "disableAutomaticConfiguration": { "type": "boolean", "description": "Disables the setup that is automatically run in a codespace if no `postCreateCommand` is specified.", "default": false } } } } }, "codespaces": { "type": "object", "additionalProperties": true, "description": "Codespaces-specific configuration.", "deprecated": true, "deprecationMessage": "Use 'customizations/codespaces' instead" } } } ================================================ FILE: extensions/configuration-editing/schemas/devContainer.vscode.schema.json ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "customizations": { "type": "object", "properties": { "vscode": { "type": "object", "properties": { "extensions": { "type": "array", "description": "An array of extensions that should be installed into the container. A minus '-' in front of the extension id removes it from the list of extensions to be installed.", "items": { "type": "string", "pattern": "^-?([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)((@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)|@prerelease)?$", "errorMessage": "Expected format: '${publisher}.${name}', '-${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." } }, "settings": { "$ref": "vscode://schemas/settings/machine", "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." }, "devPort": { "type": "integer", "description": "The port VS Code can use to connect to its backend." } } } } }, "extensions": { "type": "array", "description": "An array of extensions that should be installed into the container. A minus '-' in front of the extension id removes it from the list of extensions to be installed.", "items": { "type": "string", "pattern": "^-?([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)((@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)|@prerelease)?$", "errorMessage": "Expected format: '${publisher}.${name}', '-${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." }, "deprecated": true, "deprecationMessage": "Use 'customizations/vscode/extensions' instead" }, "settings": { "$ref": "vscode://schemas/settings/machine", "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again.", "deprecated": true, "deprecationMessage": "Use 'customizations/vscode/settings' instead" }, "devPort": { "type": "integer", "description": "The port VS Code can use to connect to its backend.", "deprecated": true, "deprecationMessage": "Use 'customizations/vscode/devPort' instead" } } } ================================================ FILE: extensions/configuration-editing/src/browser/net.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export const agent = undefined; ================================================ FILE: extensions/configuration-editing/src/configurationEditingMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { getLocation, JSONPath, parse, visit, Location } from 'jsonc-parser'; import * as vscode from 'vscode'; import { SettingsDocument } from './settingsDocumentHelper'; import { provideInstalledExtensionProposals } from './extensionsProposals'; import './importExportProfiles'; export function activate(context: vscode.ExtensionContext): void { //settings.json suggestions context.subscriptions.push(registerSettingsCompletions()); //extensions suggestions context.subscriptions.push(...registerExtensionsCompletions()); // launch.json variable suggestions context.subscriptions.push(registerVariableCompletions('**/launch.json')); // task.json variable suggestions context.subscriptions.push(registerVariableCompletions('**/tasks.json')); // Workspace file launch/tasks variable completions context.subscriptions.push(registerVariableCompletions('**/*.code-workspace')); // keybindings.json/package.json context key suggestions context.subscriptions.push(registerContextKeyCompletions()); } function registerSettingsCompletions(): vscode.Disposable { return vscode.languages.registerCompletionItemProvider({ language: 'jsonc', pattern: '**/settings.json' }, { provideCompletionItems(document, position, token) { return new SettingsDocument(document).provideCompletionItems(position, token); } }); } function registerVariableCompletions(pattern: string): vscode.Disposable { return vscode.languages.registerCompletionItemProvider({ language: 'jsonc', pattern }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); if (isCompletingInsidePropertyStringValue(document, location, position)) { if (document.fileName.endsWith('.code-workspace') && !isLocationInsideTopLevelProperty(location, ['launch', 'tasks'])) { return []; } let range = document.getWordRangeAtPosition(position, /\$\{[^"\}]*\}?/); if (!range || range.start.isEqual(position) || range.end.isEqual(position) && document.getText(range).endsWith('}')) { range = new vscode.Range(position, position); } return [ { label: 'workspaceFolder', detail: vscode.l10n.t("The path of the folder opened in VS Code") }, { label: 'workspaceFolderBasename', detail: vscode.l10n.t("The name of the folder opened in VS Code without any slashes (/)") }, { label: 'fileWorkspaceFolderBasename', detail: vscode.l10n.t("The current opened file workspace folder name without any slashes (/)") }, { label: 'relativeFile', detail: vscode.l10n.t("The current opened file relative to ${workspaceFolder}") }, { label: 'relativeFileDirname', detail: vscode.l10n.t("The current opened file's dirname relative to ${workspaceFolder}") }, { label: 'file', detail: vscode.l10n.t("The current opened file") }, { label: 'cwd', detail: vscode.l10n.t("The task runner's current working directory on startup") }, { label: 'lineNumber', detail: vscode.l10n.t("The current selected line number in the active file") }, { label: 'selectedText', detail: vscode.l10n.t("The current selected text in the active file") }, { label: 'fileDirname', detail: vscode.l10n.t("The current opened file's dirname") }, { label: 'fileExtname', detail: vscode.l10n.t("The current opened file's extension") }, { label: 'fileBasename', detail: vscode.l10n.t("The current opened file's basename") }, { label: 'fileBasenameNoExtension', detail: vscode.l10n.t("The current opened file's basename with no file extension") }, { label: 'defaultBuildTask', detail: vscode.l10n.t("The name of the default build task. If there is not a single default build task then a quick pick is shown to choose the build task.") }, { label: 'pathSeparator', detail: vscode.l10n.t("The character used by the operating system to separate components in file paths. Is also aliased to '/'.") }, { label: 'extensionInstallFolder', detail: vscode.l10n.t("The path where an extension is installed."), param: 'publisher.extension' }, ].map(variable => ({ label: `\${${variable.label}}`, range, insertText: variable.param ? new vscode.SnippetString(`\${${variable.label}:`).appendPlaceholder(variable.param).appendText('}') : (`\${${variable.label}}`), detail: variable.detail })); } return []; } }); } function isCompletingInsidePropertyStringValue(document: vscode.TextDocument, location: Location, pos: vscode.Position) { if (location.isAtPropertyKey) { return false; } const previousNode = location.previousNode; if (previousNode && previousNode.type === 'string') { const offset = document.offsetAt(pos); return offset > previousNode.offset && offset < previousNode.offset + previousNode.length; } return false; } function isLocationInsideTopLevelProperty(location: Location, values: string[]) { return values.includes(location.path[0] as string); } interface IExtensionsContent { recommendations: string[]; } function registerExtensionsCompletions(): vscode.Disposable[] { return [registerExtensionsCompletionsInExtensionsDocument(), registerExtensionsCompletionsInWorkspaceConfigurationDocument()]; } function registerExtensionsCompletionsInExtensionsDocument(): vscode.Disposable { return vscode.languages.registerCompletionItemProvider({ pattern: '**/extensions.json' }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); if (location.path[0] === 'recommendations') { const range = getReplaceRange(document, location, position); const extensionsContent = parse(document.getText()); return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } return []; } }); } function registerExtensionsCompletionsInWorkspaceConfigurationDocument(): vscode.Disposable { return vscode.languages.registerCompletionItemProvider({ pattern: '**/*.code-workspace' }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); if (location.path[0] === 'extensions' && location.path[1] === 'recommendations') { const range = getReplaceRange(document, location, position); const extensionsContent = parse(document.getText())['extensions']; return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } return []; } }); } function getReplaceRange(document: vscode.TextDocument, location: Location, position: vscode.Position) { const node = location.previousNode; if (node) { const nodeStart = document.positionAt(node.offset), nodeEnd = document.positionAt(node.offset + node.length); if (nodeStart.isBeforeOrEqual(position) && nodeEnd.isAfterOrEqual(position)) { return new vscode.Range(nodeStart, nodeEnd); } } return new vscode.Range(position, position); } vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'jsonc' }, { provideDocumentSymbols(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.ProviderResult { const result: vscode.SymbolInformation[] = []; let name: string = ''; let lastProperty = ''; let startOffset = 0; let depthInObjects = 0; visit(document.getText(), { onObjectProperty: (property, _offset, _length) => { lastProperty = property; }, onLiteralValue: (value: any, _offset: number, _length: number) => { if (lastProperty === 'name') { name = value; } }, onObjectBegin: (offset: number, _length: number) => { depthInObjects++; if (depthInObjects === 2) { startOffset = offset; } }, onObjectEnd: (offset: number, _length: number) => { if (name && depthInObjects === 2) { result.push(new vscode.SymbolInformation(name, vscode.SymbolKind.Object, new vscode.Range(document.positionAt(startOffset), document.positionAt(offset)))); } depthInObjects--; }, }); return result; } }, { label: 'Launch Targets' }); function registerContextKeyCompletions(): vscode.Disposable { type ContextKeyInfo = { key: string; type?: string; description?: string }; const paths = new Map([ [{ language: 'jsonc', pattern: '**/keybindings.json' }, [ ['*', 'when'] ]], [{ language: 'json', pattern: '**/package.json' }, [ ['contributes', 'menus', '*', '*', 'when'], ['contributes', 'views', '*', '*', 'when'], ['contributes', 'viewsWelcome', '*', 'when'], ['contributes', 'keybindings', '*', 'when'], ['contributes', 'keybindings', 'when'], ]] ]); return vscode.languages.registerCompletionItemProvider( [...paths.keys()], { async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) { const location = getLocation(document.getText(), document.offsetAt(position)); if (location.isAtPropertyKey) { return; } let isValidLocation = false; for (const [key, value] of paths) { if (vscode.languages.match(key, document)) { if (value.some(location.matches.bind(location))) { isValidLocation = true; break; } } } if (!isValidLocation || !isCompletingInsidePropertyStringValue(document, location, position)) { return; } const replacing = document.getWordRangeAtPosition(position, /[a-zA-Z.]+/) || new vscode.Range(position, position); const inserting = replacing.with(undefined, position); const data = await vscode.commands.executeCommand('getContextKeyInfo'); if (token.isCancellationRequested || !data) { return; } const result = new vscode.CompletionList(); for (const item of data) { const completion = new vscode.CompletionItem(item.key, vscode.CompletionItemKind.Constant); completion.detail = item.type; completion.range = { replacing, inserting }; completion.documentation = item.description; result.items.push(completion); } return result; } } ); } ================================================ FILE: extensions/configuration-editing/src/extensionsProposals.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; export async function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): Promise { if (Array.isArray(existing)) { const extensions = includeBuiltinExtensions ? vscode.extensions.all : vscode.extensions.all.filter(e => !(e.id.startsWith('vscode.') || e.id === 'Microsoft.vscode-markdown')); const knownExtensionProposals = extensions.filter(e => existing.indexOf(e.id) === -1); if (knownExtensionProposals.length) { return knownExtensionProposals.map(e => { const item = new vscode.CompletionItem(e.id); const insertText = `"${e.id}"${additionalText}`; item.kind = vscode.CompletionItemKind.Value; item.insertText = insertText; item.range = range; item.filterText = insertText; return item; }); } else { const example = new vscode.CompletionItem(vscode.l10n.t("Example")); example.insertText = '"vscode.csharp"'; example.kind = vscode.CompletionItemKind.Value; example.range = range; return [example]; } } return []; } ================================================ FILE: extensions/configuration-editing/src/importExportProfiles.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Octokit } from '@octokit/rest'; import * as vscode from 'vscode'; import { basename } from 'path'; import { agent } from './node/net'; class GitHubGistProfileContentHandler implements vscode.ProfileContentHandler { readonly name = vscode.l10n.t('GitHub'); readonly description = vscode.l10n.t('gist'); private _octokit: Promise | undefined; private getOctokit(): Promise { if (!this._octokit) { this._octokit = (async () => { const session = await vscode.authentication.getSession('github', ['gist', 'user:email'], { createIfNone: true }); const token = session.accessToken; const { Octokit } = await import('@octokit/rest'); return new Octokit({ request: { agent }, userAgent: 'GitHub VSCode', auth: `token ${token}` }); })(); } return this._octokit; } async saveProfile(name: string, content: string): Promise<{ readonly id: string; readonly link: vscode.Uri } | null> { const octokit = await this.getOctokit(); const result = await octokit.gists.create({ public: false, files: { [name]: { content } } }); if (result.data.id && result.data.html_url) { const link = vscode.Uri.parse(result.data.html_url); return { id: result.data.id, link }; } return null; } private _public_octokit: Promise | undefined; private getPublicOctokit(): Promise { if (!this._public_octokit) { this._public_octokit = (async () => { const { Octokit } = await import('@octokit/rest'); return new Octokit({ request: { agent }, userAgent: 'GitHub VSCode' }); })(); } return this._public_octokit; } async readProfile(id: string): Promise; async readProfile(uri: vscode.Uri): Promise; async readProfile(arg: string | vscode.Uri): Promise { const gist_id = typeof arg === 'string' ? arg : basename(arg.path); const octokit = await this.getPublicOctokit(); try { const gist = await octokit.gists.get({ gist_id }); if (gist.data.files) { return gist.data.files[Object.keys(gist.data.files)[0]]?.content ?? null; } } catch (error) { // ignore } return null; } } vscode.window.registerProfileContentHandler('github', new GitHubGistProfileContentHandler()); ================================================ FILE: extensions/configuration-editing/src/node/net.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Agent, globalAgent } from 'https'; import { URL } from 'url'; import { httpsOverHttp } from 'tunnel'; import { window } from 'vscode'; export const agent = getAgent(); /** * Return an https agent for the given proxy URL, or return the * global https agent if the URL was empty or invalid. */ function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent { if (!url) { return globalAgent; } try { const { hostname, port, username, password } = new URL(url); const auth = username && password && `${username}:${password}`; return httpsOverHttp({ proxy: { host: hostname, port, proxyAuth: auth } }); } catch (e) { window.showErrorMessage(`HTTPS_PROXY environment variable ignored: ${e.message}`); return globalAgent; } } ================================================ FILE: extensions/configuration-editing/src/settingsDocumentHelper.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { getLocation, Location, parse } from 'jsonc-parser'; import { provideInstalledExtensionProposals } from './extensionsProposals'; const OVERRIDE_IDENTIFIER_REGEX = /\[([^\[\]]*)\]/g; export class SettingsDocument { constructor(private document: vscode.TextDocument) { } public async provideCompletionItems(position: vscode.Position, _token: vscode.CancellationToken): Promise { const location = getLocation(this.document.getText(), this.document.offsetAt(position)); // window.title if (location.path[0] === 'window.title') { return this.provideWindowTitleCompletionItems(location, position); } // files.association if (location.path[0] === 'files.associations') { return this.provideFilesAssociationsCompletionItems(location, position); } // files.exclude, search.exclude, explorer.autoRevealExclude if (location.path[0] === 'files.exclude' || location.path[0] === 'search.exclude' || location.path[0] === 'explorer.autoRevealExclude') { return this.provideExcludeCompletionItems(location, position); } // files.defaultLanguage if (location.path[0] === 'files.defaultLanguage') { return this.provideLanguageCompletionItems(location, position); } // workbench.editor.label if (location.path[0] === 'workbench.editor.label.patterns') { return this.provideEditorLabelCompletionItems(location, position); } // settingsSync.ignoredExtensions if (location.path[0] === 'settingsSync.ignoredExtensions') { let ignoredExtensions = []; try { ignoredExtensions = parse(this.document.getText())['settingsSync.ignoredExtensions']; } catch (e) {/* ignore error */ } const range = this.getReplaceRange(location, position); return provideInstalledExtensionProposals(ignoredExtensions, '', range, true); } // remote.extensionKind if (location.path[0] === 'remote.extensionKind' && location.path.length === 2 && location.isAtPropertyKey) { let alreadyConfigured: string[] = []; try { alreadyConfigured = Object.keys(parse(this.document.getText())['remote.extensionKind']); } catch (e) {/* ignore error */ } const range = this.getReplaceRange(location, position); return provideInstalledExtensionProposals(alreadyConfigured, location.previousNode ? '' : `: [\n\t"ui"\n]`, range, true); } // remote.portsAttributes if (location.path[0] === 'remote.portsAttributes' && location.path.length === 2 && location.isAtPropertyKey) { return this.providePortsAttributesCompletionItem(this.getReplaceRange(location, position)); } return this.provideLanguageOverridesCompletionItems(location, position); } private getReplaceRange(location: Location, position: vscode.Position) { const node = location.previousNode; if (node) { const nodeStart = this.document.positionAt(node.offset), nodeEnd = this.document.positionAt(node.offset + node.length); if (nodeStart.isBeforeOrEqual(position) && nodeEnd.isAfterOrEqual(position)) { return new vscode.Range(nodeStart, nodeEnd); } } return new vscode.Range(position, position); } private isCompletingPropertyValue(location: Location, pos: vscode.Position) { if (location.isAtPropertyKey) { return false; } const previousNode = location.previousNode; if (previousNode) { const offset = this.document.offsetAt(pos); return offset >= previousNode.offset && offset <= previousNode.offset + previousNode.length; } return true; } private async provideWindowTitleCompletionItems(location: Location, pos: vscode.Position): Promise { const completions: vscode.CompletionItem[] = []; if (!this.isCompletingPropertyValue(location, pos)) { return completions; } let range = this.document.getWordRangeAtPosition(pos, /\$\{[^"\}]*\}?/); if (!range || range.start.isEqual(pos) || range.end.isEqual(pos) && this.document.getText(range).endsWith('}')) { range = new vscode.Range(pos, pos); } const getText = (variable: string) => { const text = '${' + variable + '}'; return location.previousNode ? text : JSON.stringify(text); }; completions.push(this.newSimpleCompletionItem(getText('activeEditorShort'), range, vscode.l10n.t("the file name (e.g. myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorMedium'), range, vscode.l10n.t("the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorLong'), range, vscode.l10n.t("the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderShort'), range, vscode.l10n.t("the name of the folder the file is contained in (e.g. myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderMedium'), range, vscode.l10n.t("the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderLong'), range, vscode.l10n.t("the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('rootName'), range, vscode.l10n.t("name of the workspace with optional remote name and workspace indicator if applicable (e.g. myFolder, myRemoteFolder [SSH] or myWorkspace (Workspace))"))); completions.push(this.newSimpleCompletionItem(getText('rootNameShort'), range, vscode.l10n.t("shortened name of the workspace without suffixes (e.g. myFolder or myWorkspace)"))); completions.push(this.newSimpleCompletionItem(getText('rootPath'), range, vscode.l10n.t("file path of the workspace (e.g. /Users/Development/myWorkspace)"))); completions.push(this.newSimpleCompletionItem(getText('folderName'), range, vscode.l10n.t("name of the workspace folder the file is contained in (e.g. myFolder)"))); completions.push(this.newSimpleCompletionItem(getText('folderPath'), range, vscode.l10n.t("file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)"))); completions.push(this.newSimpleCompletionItem(getText('appName'), range, vscode.l10n.t("e.g. VS Code"))); completions.push(this.newSimpleCompletionItem(getText('remoteName'), range, vscode.l10n.t("e.g. SSH"))); completions.push(this.newSimpleCompletionItem(getText('dirty'), range, vscode.l10n.t("an indicator for when the active editor has unsaved changes"))); completions.push(this.newSimpleCompletionItem(getText('separator'), range, vscode.l10n.t("a conditional separator (' - ') that only shows when surrounded by variables with values"))); completions.push(this.newSimpleCompletionItem(getText('activeRepositoryName'), range, vscode.l10n.t("the name of the active repository (e.g. vscode)"))); completions.push(this.newSimpleCompletionItem(getText('activeRepositoryBranchName'), range, vscode.l10n.t("the name of the active branch in the active repository (e.g. main)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorState'), range, vscode.l10n.t("the state of the active editor (e.g. modified)."))); return completions; } private async provideEditorLabelCompletionItems(location: Location, pos: vscode.Position): Promise { const completions: vscode.CompletionItem[] = []; if (!this.isCompletingPropertyValue(location, pos)) { return completions; } let range = this.document.getWordRangeAtPosition(pos, /\$\{[^"\}]*\}?/); if (!range || range.start.isEqual(pos) || range.end.isEqual(pos) && this.document.getText(range).endsWith('}')) { range = new vscode.Range(pos, pos); } const getText = (variable: string) => { const text = '${' + variable + '}'; return location.previousNode ? text : JSON.stringify(text); }; completions.push(this.newSimpleCompletionItem(getText('dirname'), range, vscode.l10n.t("The parent folder name of the editor (e.g. myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('dirname(1)'), range, vscode.l10n.t("The nth parent folder name of the editor"))); completions.push(this.newSimpleCompletionItem(getText('filename'), range, vscode.l10n.t("The file name of the editor without its directory or extension (e.g. myFile)"))); completions.push(this.newSimpleCompletionItem(getText('extname'), range, vscode.l10n.t("The file extension of the editor (e.g. txt)"))); return completions; } private async provideFilesAssociationsCompletionItems(location: Location, position: vscode.Position): Promise { const completions: vscode.CompletionItem[] = []; if (location.path.length === 2) { // Key if (location.path[1] === '') { const range = this.getReplaceRange(location, position); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files with Extension"), documentation: vscode.l10n.t("Map all files matching the glob pattern in their filename to the language with the given identifier."), snippet: location.isAtPropertyKey ? '"*.${1:extension}": "${2:language}"' : '{ "*.${1:extension}": "${2:language}" }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files with Path"), documentation: vscode.l10n.t("Map all files matching the absolute path glob pattern in their path to the language with the given identifier."), snippet: location.isAtPropertyKey ? '"/${1:path to file}/*.${2:extension}": "${3:language}"' : '{ "/${1:path to file}/*.${2:extension}": "${3:language}" }', range })); } else if (this.isCompletingPropertyValue(location, position)) { // Value return this.provideLanguageCompletionItemsForLanguageOverrides(this.getReplaceRange(location, position)); } } return completions; } private async provideExcludeCompletionItems(location: Location, position: vscode.Position): Promise { const completions: vscode.CompletionItem[] = []; // Key if (location.path.length === 1 || (location.path.length === 2 && location.path[1] === '')) { const range = this.getReplaceRange(location, position); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files by Extension"), documentation: vscode.l10n.t("Match all files of a specific file extension."), snippet: location.path.length === 2 ? '"**/*.${1:extension}": true' : '{ "**/*.${1:extension}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files with Multiple Extensions"), documentation: vscode.l10n.t("Match all files with any of the file extensions."), snippet: location.path.length === 2 ? '"**/*.{ext1,ext2,ext3}": true' : '{ "**/*.{ext1,ext2,ext3}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files with Siblings by Name"), documentation: vscode.l10n.t("Match files that have siblings with the same name but a different extension."), snippet: location.path.length === 2 ? '"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }' : '{ "**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" } }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Folder by Name (Top Level)"), documentation: vscode.l10n.t("Match a top level folder with a specific name."), snippet: location.path.length === 2 ? '"${1:name}": true' : '{ "${1:name}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Folders with Multiple Names (Top Level)"), documentation: vscode.l10n.t("Match multiple top level folders."), snippet: location.path.length === 2 ? '"{folder1,folder2,folder3}": true' : '{ "{folder1,folder2,folder3}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Folder by Name (Any Location)"), documentation: vscode.l10n.t("Match a folder with a specific name in any location."), snippet: location.path.length === 2 ? '"**/${1:name}": true' : '{ "**/${1:name}": true }', range })); } // Value else if (location.path.length === 2 && this.isCompletingPropertyValue(location, position)) { const range = this.getReplaceRange(location, position); completions.push(this.newSnippetCompletionItem({ label: vscode.l10n.t("Files with Siblings by Name"), documentation: vscode.l10n.t("Match files that have siblings with the same name but a different extension."), snippet: '{ "when": "$(basename).${1:extension}" }', range })); } return completions; } private async provideLanguageCompletionItems(location: Location, position: vscode.Position): Promise { if (location.path.length === 1 && this.isCompletingPropertyValue(location, position)) { const range = this.getReplaceRange(location, position); const languages = await vscode.languages.getLanguages(); return [ this.newSimpleCompletionItem(JSON.stringify('${activeEditorLanguage}'), range, vscode.l10n.t("Use the language of the currently active text editor if any")), ...languages.map(l => this.newSimpleCompletionItem(JSON.stringify(l), range)) ]; } return []; } private async provideLanguageCompletionItemsForLanguageOverrides(range: vscode.Range): Promise { const languages = await vscode.languages.getLanguages(); const completionItems = []; for (const language of languages) { const item = new vscode.CompletionItem(JSON.stringify(language)); item.kind = vscode.CompletionItemKind.Property; item.range = range; completionItems.push(item); } return completionItems; } private async provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): Promise { if (location.path.length === 1 && location.isAtPropertyKey && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) { const startPosition = this.document.positionAt(location.previousNode.offset + 1); const endPosition = startPosition.translate(undefined, location.previousNode.value.length); const donotSuggestLanguages: string[] = []; const languageOverridesRanges: vscode.Range[] = []; let matches = OVERRIDE_IDENTIFIER_REGEX.exec(location.previousNode.value); let lastLanguageOverrideRange: vscode.Range | undefined; while (matches?.length) { lastLanguageOverrideRange = new vscode.Range(this.document.positionAt(location.previousNode.offset + 1 + matches.index), this.document.positionAt(location.previousNode.offset + 1 + matches.index + matches[0].length)); languageOverridesRanges.push(lastLanguageOverrideRange); /* Suggest the configured language if the position is in the match range */ if (!lastLanguageOverrideRange.contains(position)) { donotSuggestLanguages.push(matches[1].trim()); } matches = OVERRIDE_IDENTIFIER_REGEX.exec(location.previousNode.value); } const lastLanguageOverrideEndPosition = lastLanguageOverrideRange ? lastLanguageOverrideRange.end : startPosition; if (lastLanguageOverrideEndPosition.isBefore(endPosition)) { languageOverridesRanges.push(new vscode.Range(lastLanguageOverrideEndPosition, endPosition)); } const languageOverrideRange = languageOverridesRanges.find(range => range.contains(position)); /** * Skip if suggestions are for first language override range * Since VSCode registers language overrides to the schema, JSON language server does suggestions for first language override. */ if (languageOverrideRange && !languageOverrideRange.isEqual(languageOverridesRanges[0])) { const languages = await vscode.languages.getLanguages(); const completionItems = []; for (const language of languages) { if (!donotSuggestLanguages.includes(language)) { const item = new vscode.CompletionItem(`[${language}]`); item.kind = vscode.CompletionItemKind.Property; item.range = languageOverrideRange; completionItems.push(item); } } return completionItems; } } return []; } private providePortsAttributesCompletionItem(range: vscode.Range): vscode.CompletionItem[] { return [this.newSnippetCompletionItem( { label: '\"3000\"', documentation: 'Single Port Attribute', range, snippet: '\n \"${1:3000}\": {\n \"label\": \"${2:Application}\",\n \"onAutoForward\": \"${3:openPreview}\"\n }\n' }), this.newSnippetCompletionItem( { label: '\"5000-6000\"', documentation: 'Ranged Port Attribute', range, snippet: '\n \"${1:40000-55000}\": {\n \"onAutoForward\": \"${2:ignore}\"\n }\n' }), this.newSnippetCompletionItem( { label: '\".+\\\\/server.js\"', documentation: 'Command Match Port Attribute', range, snippet: '\n \"${1:.+\\\\/server.js\}\": {\n \"label\": \"${2:Application}\",\n \"onAutoForward\": \"${3:openPreview}\"\n }\n' }) ]; } private newSimpleCompletionItem(text: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem { const item = new vscode.CompletionItem(text); item.kind = vscode.CompletionItemKind.Value; item.detail = description; item.insertText = insertText ? insertText : text; item.range = range; return item; } private newSnippetCompletionItem(o: { label: string; documentation?: string; snippet: string; range: vscode.Range }): vscode.CompletionItem { const item = new vscode.CompletionItem(o.label); item.kind = vscode.CompletionItemKind.Value; item.documentation = o.documentation; item.insertText = new vscode.SnippetString(o.snippet); item.range = o.range; return item; } } ================================================ FILE: extensions/configuration-editing/src/test/completion.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import * as assert from 'assert'; import { promises as fs } from 'fs'; import * as path from 'path'; import * as os from 'os'; import 'mocha'; const testFolder = fs.mkdtemp(path.join(os.tmpdir(), 'conf-editing-')); suite('Completions in settings.json', () => { const testFile = 'settings.json'; test('window.title', async () => { { // inserting after text const content = [ '{', ' "window.title": "custom|"', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "custom${activeEditorShort}"', '}', ].join('\n'); const expected = { label: '${activeEditorShort}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // inserting before a variable const content = [ '{', ' "window.title": "|${activeEditorShort}"', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "${folderPath}${activeEditorShort}"', '}', ].join('\n'); const expected = { label: '${folderPath}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // inserting after a variable const content = [ '{', ' "window.title": "${activeEditorShort}|"', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "${activeEditorShort}${folderPath}"', '}', ].join('\n'); const expected = { label: '${folderPath}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // replacing an variable const content = [ '{', ' "window.title": "${a|ctiveEditorShort}"', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "${activeEditorMedium}"', '}', ].join('\n'); const expected = { label: '${activeEditorMedium}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // replacing a partial variable const content = [ '{', ' "window.title": "${a|"', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "${dirty}"', '}', ].join('\n'); const expected = { label: '${dirty}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // inserting a literal const content = [ '{', ' "window.title": |', '}', ].join('\n'); const resultText = [ '{', ' "window.title": "${activeEditorMedium}"', '}', ].join('\n'); const expected = { label: '"${activeEditorMedium}"', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { // no proposals after literal const content = [ '{', ' "window.title": "${activeEditorShort}" |', '}', ].join('\n'); const expected = { label: '${activeEditorMedium}', notAvailable: true }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('files.associations', async () => { { const content = [ '{', ' "files.associations": {', ' |', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.associations": {', ' "*.${1:extension}": "${2:language}"', ' }', '}', ].join('\n'); const expected = { label: 'Files with Extension', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.associations": {', ' |', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.associations": {', ' "/${1:path to file}/*.${2:extension}": "${3:language}"', ' }', '}', ].join('\n'); const expected = { label: 'Files with Path', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.associations": {', ' "*.extension": "|bat"', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.associations": {', ' "*.extension": "json"', ' }', '}', ].join('\n'); const expected = { label: '"json"', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.associations": {', ' "*.extension": "bat"|', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.associations": {', ' "*.extension": "json"', ' }', '}', ].join('\n'); const expected = { label: '"json"', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.associations": {', ' "*.extension": "bat" |', ' }', '}', ].join('\n'); const expected = { label: '"json"', notAvailable: true }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('files.exclude', async () => { { const content = [ '{', ' "files.exclude": {', ' |', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.exclude": {', ' "**/*.${1:extension}": true', ' }', '}', ].join('\n'); const expected = { label: 'Files by Extension', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.exclude": {', ' "**/*.extension": |true', ' }', '}', ].join('\n'); const resultText = [ '{', ' "files.exclude": {', ' "**/*.extension": { "when": "$(basename).${1:extension}" }', ' }', '}', ].join('\n'); const expected = { label: 'Files with Siblings by Name', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('files.defaultLanguage', async () => { { const content = [ '{', ' "files.defaultLanguage": "json|"', '}', ].join('\n'); const resultText = [ '{', ' "files.defaultLanguage": "jsonc"', '}', ].join('\n'); const expected = { label: '"jsonc"', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "files.defaultLanguage": |', '}', ].join('\n'); const resultText = [ '{', ' "files.defaultLanguage": "jsonc"', '}', ].join('\n'); const expected = { label: '"jsonc"', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('remote.extensionKind', async () => { { const content = [ '{', '\t"remote.extensionKind": {', '\t\t|', '\t}', '}', ].join('\n'); const expected = { label: 'vscode.npm' }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('remote.portsAttributes', async () => { { const content = [ '{', ' "remote.portsAttributes": {', ' |', ' }', '}', ].join('\n'); const expected = { label: '"3000"' }; await testCompletion(testFile, 'jsonc', content, expected); } }); }); suite('Completions in extensions.json', () => { const testFile = 'extensions.json'; test('change recommendation', async () => { { const content = [ '{', ' "recommendations": [', ' "|a.b"', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "recommendations": [', ' "ms-vscode.js-debug"', ' ]', '}', ].join('\n'); const expected = { label: 'ms-vscode.js-debug', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('add recommendation', async () => { { const content = [ '{', ' "recommendations": [', ' |', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "recommendations": [', ' "ms-vscode.js-debug"', ' ]', '}', ].join('\n'); const expected = { label: 'ms-vscode.js-debug', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); }); suite('Completions in launch.json', () => { const testFile = 'launch.json'; test('variable completions', async () => { { const content = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Run Extension",', ' "type": "extensionHost",', ' "preLaunchTask": "${|defaultBuildTask}"', ' }', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Run Extension",', ' "type": "extensionHost",', ' "preLaunchTask": "${cwd}"', ' }', ' ]', '}', ].join('\n'); const expected = { label: '${cwd}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Run Extension",', ' "type": "extensionHost",', ' "preLaunchTask": "|${defaultBuildTask}"', ' }', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Run Extension",', ' "type": "extensionHost",', ' "preLaunchTask": "${cwd}${defaultBuildTask}"', ' }', ' ]', '}', ].join('\n'); const expected = { label: '${cwd}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Do It",', ' "program": "${workspace|"', ' }', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "version": "0.2.0",', ' "configurations": [', ' {', ' "name": "Do It",', ' "program": "${cwd}"', ' }', ' ]', '}', ].join('\n'); const expected = { label: '${cwd}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); }); suite('Completions in tasks.json', () => { const testFile = 'tasks.json'; test('variable completions', async () => { { const content = [ '{', ' "version": "0.2.0",', ' "tasks": [', ' {', ' "type": "shell",', ' "command": "${|defaultBuildTask}"', ' }', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "version": "0.2.0",', ' "tasks": [', ' {', ' "type": "shell",', ' "command": "${cwd}"', ' }', ' ]', '}', ].join('\n'); const expected = { label: '${cwd}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } { const content = [ '{', ' "version": "0.2.0",', ' "tasks": [', ' {', ' "type": "shell",', ' "command": "${defaultBuildTask}|"', ' }', ' ]', '}', ].join('\n'); const resultText = [ '{', ' "version": "0.2.0",', ' "tasks": [', ' {', ' "type": "shell",', ' "command": "${defaultBuildTask}${cwd}"', ' }', ' ]', '}', ].join('\n'); const expected = { label: '${cwd}', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); }); suite('Completions in keybindings.json', () => { const testFile = 'keybindings.json'; test('context key insertion', async () => { { const content = [ '[', ' {', ' "key": "ctrl+k ctrl+,",', ' "command": "editor.jumpToNextFold",', ' "when": "|"', ' }', ']', ].join('\n'); const resultText = [ '[', ' {', ' "key": "ctrl+k ctrl+,",', ' "command": "editor.jumpToNextFold",', ' "when": "resourcePath"', ' }', ']', ].join('\n'); const expected = { label: 'resourcePath', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); test('context key replace', async () => { { const content = [ '[', ' {', ' "key": "ctrl+k ctrl+,",', ' "command": "editor.jumpToNextFold",', ' "when": "resou|rcePath"', ' }', ']', ].join('\n'); const resultText = [ '[', ' {', ' "key": "ctrl+k ctrl+,",', ' "command": "editor.jumpToNextFold",', ' "when": "resource"', ' }', ']', ].join('\n'); const expected = { label: 'resource', resultText }; await testCompletion(testFile, 'jsonc', content, expected); } }); }); interface ItemDescription { label: string; resultText?: string; notAvailable?: boolean; } async function testCompletion(testFileName: string, languageId: string, content: string, expected: ItemDescription) { const offset = content.indexOf('|'); content = content.substring(0, offset) + content.substring(offset + 1); const docUri = vscode.Uri.file(path.join(await testFolder, testFileName)); await fs.writeFile(docUri.fsPath, content); const editor = await setTestContent(docUri, languageId, content); const position = editor.document.positionAt(offset); // Executing the command `vscode.executeCompletionItemProvider` to simulate triggering completion const actualCompletions = (await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', docUri, position)) as vscode.CompletionList; const matches = actualCompletions.items.filter(completion => { return completion.label === expected.label; }); if (expected.notAvailable) { assert.strictEqual(matches.length, 0, `${expected.label} should not existing is results`); } else { assert.strictEqual(matches.length, 1, `${expected.label} should only existing once: Actual: ${actualCompletions.items.map(c => c.label).join(', ')}`); if (expected.resultText) { const match = matches[0]; if (match.range && match.insertText) { const range = match.range instanceof vscode.Range ? match.range : match.range.replacing; const text = typeof match.insertText === 'string' ? match.insertText : match.insertText.value; await editor.edit(eb => eb.replace(range, text)); assert.strictEqual(editor.document.getText(), expected.resultText); } else { assert.fail(`Range or insertText missing`); } } } } async function setTestContent(docUri: vscode.Uri, languageId: string, content: string): Promise { const ext = vscode.extensions.getExtension('vscode.configuration-editing')!; await ext.activate(); const doc = await vscode.workspace.openTextDocument(docUri); await vscode.languages.setTextDocumentLanguage(doc, languageId); const editor = await vscode.window.showTextDocument(doc); const fullRange = new vscode.Range(new vscode.Position(0, 0), doc.positionAt(doc.getText().length)); await editor.edit(eb => eb.replace(fullRange, content)); return editor; } ================================================ FILE: extensions/configuration-editing/src/test/index.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as testRunner from '../../../../test/integration/electron/testrunner'; const options: import('mocha').MochaOptions = { ui: 'tdd', color: true, timeout: 60000 }; // These integration tests is being run in multiple environments (electron, web, remote) // so we need to set the suite name based on the environment as the suite name is used // for the test results file name let suite = ''; if (process.env.VSCODE_BROWSER) { suite = `${process.env.VSCODE_BROWSER} Browser Integration Configuration-Editing Tests`; } else if (process.env.REMOTE_VSCODE) { suite = 'Remote Integration Configuration-Editing Tests'; } else { suite = 'Integration Configuration-Editing Tests'; } if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { options.reporter = 'mocha-multi-reporters'; options.reporterOptions = { reporterEnabled: 'spec, mocha-junit-reporter', mochaJunitReporterReporterOptions: { testsuitesTitle: `${suite} ${process.platform}`, mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) } }; } testRunner.configure(options); export = testRunner; ================================================ FILE: extensions/configuration-editing/src/typings/ref.d.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ declare module 'tunnel'; ================================================ FILE: extensions/configuration-editing/tsconfig.json ================================================ { "extends": "../tsconfig.base.json", "compilerOptions": { "outDir": "./out", "types": [ "node" ] }, "include": [ "src/**/*", "../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts", ] } ================================================ FILE: extensions/cpp/.vscodeignore ================================================ build/** test/** cgmanifest.json ================================================ FILE: extensions/cpp/build/update-grammars.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; var updateGrammar = require('vscode-grammar-updater'); async function updateGrammars() { await updateGrammar.update('jeff-hykin/better-c-syntax', 'autogenerated/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master'); // The license has changed for these two grammar. We have to freeze them as the new license is not compatible with our license. // await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master'); // await updateGrammar.update('jeff-hykin/better-cpp-syntax', 'autogenerated/cpp.embedded.macro.tmLanguage.json', './syntaxes/cpp.embedded.macro.tmLanguage.json', undefined, 'master'); await updateGrammar.update('NVIDIA/cuda-cpp-grammar', 'syntaxes/cuda-cpp.tmLanguage.json', './syntaxes/cuda-cpp.tmLanguage.json', undefined, 'master'); // `source.c.platform` which is still included by other grammars await updateGrammar.update('textmate/c.tmbundle', 'Syntaxes/Platform.tmLanguage', './syntaxes/platform.tmLanguage.json'); } updateGrammars(); ================================================ FILE: extensions/cpp/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "jeff-hykin/better-cpp-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-cpp-syntax", "commitHash": "f1d127a8af2b184db570345f0bb179503c47fdf6" } }, "license": "MIT", "licenseDetail": [ [ "MIT License", "", "Copyright (c) 2019 Jeff Hykin", "", "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." ] ], "version": "1.17.4", "description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { "component": { "type": "git", "git": { "name": "jeff-hykin/better-c-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-c-syntax", "commitHash": "34712a6106a4ffb0a04d2fa836fd28ff6c5849a4" } }, "license": "MIT", "version": "1.13.2", "description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { "component": { "type": "git", "git": { "name": "textmate/c.tmbundle", "repositoryUrl": "https://github.com/textmate/c.tmbundle", "commitHash": "60daf83b9d45329524f7847a75e9298b3aae5805" } }, "licenseDetail": [ "Copyright (c) textmate-c.tmbundle authors", "", "If not otherwise specified (see below), files in this repository fall under the following license:", "", "Permission to copy, use, modify, sell and distribute this", "software is granted. This software is provided \"as is\" without", "express or implied warranty, and with no claim as to its", "suitability for any purpose.", "", "An exception is made for files in readable text which contain their own license information,", "or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added", "to the base-name name of the original file, and an extension of txt, html, or similar. For example", "\"tidy\" is accompanied by \"tidy-license.txt\"." ], "license": "TextMate Bundle License", "version": "0.0.0" }, { "component": { "type": "git", "git": { "name": "NVIDIA/cuda-cpp-grammar", "repositoryUrl": "https://github.com/NVIDIA/cuda-cpp-grammar", "commitHash": "81e88eaec5170aa8585736c63627c73e3589998c" } }, "license": "MIT", "version": "0.0.0", "description": "The file syntaxes/cuda-cpp.tmLanguage.json was derived from https://github.com/jeff-hykin/cpp-textmate-grammar, which was derived from https://github.com/atom/language-c, which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." } ], "version": 1 } ================================================ FILE: extensions/cpp/language-configuration.json ================================================ { "comments": { "lineComment": "//", "blockComment": [ "/*", "*/" ] }, "brackets": [ [ "{", "}" ], [ "[", "]" ], [ "(", ")" ] ], "autoClosingPairs": [ { "open": "[", "close": "]" }, { "open": "{", "close": "}" }, { "open": "(", "close": ")" }, { "open": "'", "close": "'", "notIn": [ "string", "comment" ] }, { "open": "\"", "close": "\"", "notIn": [ "string" ] }, { "open": "/*", "close": "*/", "notIn": [ "string", "comment" ] }, { "open": "/**", "close": " */", "notIn": [ "string" ] } ], "surroundingPairs": [ [ "{", "}" ], [ "[", "]" ], [ "(", ")" ], [ "\"", "\"" ], [ "'", "'" ], [ "<", ">" ] ], "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)", "folding": { "markers": { "start": "^\\s*#pragma\\s+region\\b", "end": "^\\s*#pragma\\s+endregion\\b" } }, "indentationRules": { "decreaseIndentPattern": { "pattern": "^\\s*[\\}\\]\\)].*$" }, "increaseIndentPattern": { "pattern": "^.*(\\{[^}]*|\\([^)]*|\\[[^\\]]*)$" }, }, "onEnterRules": [ { // Decrease indentation after single line if/else if/else, for, or while "previousLineText": "^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$", // But make sure line doesn't have braces or is not another if statement "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", "action": { "indent": "outdent" } }, // Add // when pressing enter from inside line comment { "beforeText": { "pattern": "\/\/.*" }, "afterText": { "pattern": "^(?!\\s*$).+" }, "action": { "indent": "none", "appendText": "// " } }, ] } ================================================ FILE: extensions/cpp/package.json ================================================ { "name": "cpp", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "*" }, "scripts": { "update-grammar": "node ./build/update-grammars.js" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "c", "extensions": [ ".c", ".i" ], "aliases": [ "C", "c" ], "configuration": "./language-configuration.json" }, { "id": "cpp", "extensions": [ ".cpp", ".cppm", ".cc", ".ccm", ".cxx", ".cxxm", ".c++", ".c++m", ".hpp", ".hh", ".hxx", ".h++", ".h", ".ii", ".ino", ".inl", ".ipp", ".ixx", ".tpp", ".txx", ".hpp.in", ".h.in" ], "aliases": [ "C++", "Cpp", "cpp" ], "configuration": "./language-configuration.json" }, { "id": "cuda-cpp", "extensions": [ ".cu", ".cuh" ], "aliases": [ "CUDA C++" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "c", "scopeName": "source.c", "path": "./syntaxes/c.tmLanguage.json" }, { "language": "cpp", "scopeName": "source.cpp.embedded.macro", "path": "./syntaxes/cpp.embedded.macro.tmLanguage.json" }, { "language": "cpp", "scopeName": "source.cpp", "path": "./syntaxes/cpp.tmLanguage.json" }, { "scopeName": "source.c.platform", "path": "./syntaxes/platform.tmLanguage.json" }, { "language": "cuda-cpp", "scopeName": "source.cuda-cpp", "path": "./syntaxes/cuda-cpp.tmLanguage.json" } ], "problemPatterns": [ { "name": "nvcc-location", "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)", "kind": "location", "file": 1, "location": 2, "severity": 3, "message": 4 } ], "problemMatchers": [ { "name": "nvcc", "owner": "cuda-cpp", "fileLocation": [ "relative", "${workspaceFolder}" ], "pattern": "$nvcc-location" } ], "snippets": [ { "language": "c", "path": "./snippets/c.code-snippets" }, { "language": "cpp", "path": "./snippets/cpp.code-snippets" } ] }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/cpp/package.nls.json ================================================ { "displayName": "C/C++ Language Basics", "description": "Provides snippets, syntax highlighting, bracket matching and folding in C/C++ files." } ================================================ FILE: extensions/cpp/snippets/c.code-snippets ================================================ { "Region Start": { "prefix": "#region", "body": [ "#pragma region $0" ], "description": "Folding Region Start" }, "Region End": { "prefix": "#endregion", "body": [ "#pragma endregion" ], "description": "Folding Region End" } } ================================================ FILE: extensions/cpp/snippets/cpp.code-snippets ================================================ { "Region Start": { "prefix": "#region", "body": [ "#pragma region $0" ], "description": "Folding Region Start" }, "Region End": { "prefix": "#endregion", "body": [ "#pragma endregion" ], "description": "Folding Region End" } } ================================================ FILE: extensions/cpp/syntaxes/c.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/jeff-hykin/better-c-syntax/blob/master/autogenerated/c.tmLanguage.json", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/jeff-hykin/better-c-syntax/commit/34712a6106a4ffb0a04d2fa836fd28ff6c5849a4", "name": "C", "scopeName": "source.c", "patterns": [ { "include": "#preprocessor-rule-enabled" }, { "include": "#preprocessor-rule-disabled" }, { "include": "#preprocessor-rule-conditional" }, { "include": "#predefined_macros" }, { "include": "#comments" }, { "include": "#switch_statement" }, { "include": "#anon_pattern_1" }, { "include": "#storage_types" }, { "include": "#anon_pattern_2" }, { "include": "#anon_pattern_3" }, { "include": "#anon_pattern_4" }, { "include": "#anon_pattern_5" }, { "include": "#anon_pattern_6" }, { "include": "#anon_pattern_7" }, { "include": "#operators" }, { "include": "#numbers" }, { "include": "#strings" }, { "include": "#anon_pattern_range_1" }, { "include": "#anon_pattern_range_2" }, { "include": "#anon_pattern_range_3" }, { "include": "#pragma-mark" }, { "include": "#anon_pattern_range_4" }, { "include": "#anon_pattern_range_5" }, { "include": "#anon_pattern_range_6" }, { "include": "#anon_pattern_8" }, { "include": "#anon_pattern_9" }, { "include": "#anon_pattern_10" }, { "include": "#anon_pattern_11" }, { "include": "#anon_pattern_12" }, { "include": "#anon_pattern_13" }, { "include": "#block" }, { "include": "#parens" }, { "include": "#anon_pattern_range_7" }, { "include": "#line_continuation_character" }, { "include": "#anon_pattern_range_8" }, { "include": "#anon_pattern_range_9" }, { "include": "#anon_pattern_14" }, { "include": "#anon_pattern_15" } ], "repository": { "access-method": { "name": "meta.function-call.member.c", "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))\\s*(?:(\\.)|(->))((?:(?:[a-zA-Z_][a-zA-Z_0-9]*)\\s*(?:(?:\\.)|(?:->)))*)\\s*([a-zA-Z_][a-zA-Z_0-9]*)(\\()", "beginCaptures": { "1": { "name": "variable.object.c" }, "2": { "name": "punctuation.separator.dot-access.c" }, "3": { "name": "punctuation.separator.pointer-access.c" }, "4": { "patterns": [ { "match": "\\.", "name": "punctuation.separator.dot-access.c" }, { "match": "->", "name": "punctuation.separator.pointer-access.c" }, { "match": "[a-zA-Z_][a-zA-Z_0-9]*", "name": "variable.object.c" }, { "name": "everything.else.c", "match": ".+" } ] }, "5": { "name": "entity.name.function.member.c" }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.function.member.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.member.c" } }, "patterns": [ { "include": "#function-call-innards" } ] }, "anon_pattern_1": { "match": "\\b(break|continue|do|else|for|goto|if|_Pragma|return|while)\\b", "name": "keyword.control.c" }, "anon_pattern_10": { "match": "(?x) \\b\n(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t\n|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t\n|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t\n|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t\n|uintmax_t|uintmax_t)\n\\b", "name": "support.type.stdint.c" }, "anon_pattern_11": { "match": "\\b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\\b", "name": "support.constant.mac-classic.c" }, "anon_pattern_12": { "match": "(?x) \\b\n(AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam\n|ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr\n|Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber\n|ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64\n|SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32\n|UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr\n|UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char)\n\\b", "name": "support.type.mac-classic.c" }, "anon_pattern_13": { "match": "\\b([A-Za-z0-9_]+_t)\\b", "name": "support.type.posix-reserved.c" }, "anon_pattern_14": { "match": ";", "name": "punctuation.terminator.statement.c" }, "anon_pattern_15": { "match": ",", "name": "punctuation.separator.delimiter.c" }, "anon_pattern_2": { "match": "typedef", "name": "keyword.other.typedef.c" }, "anon_pattern_3": { "match": "\\b(const|extern|register|restrict|static|volatile|inline)\\b", "name": "storage.modifier.c" }, "anon_pattern_4": { "match": "\\bk[A-Z]\\w*\\b", "name": "constant.other.variable.mac-classic.c" }, "anon_pattern_5": { "match": "\\bg[A-Z]\\w*\\b", "name": "variable.other.readwrite.global.mac-classic.c" }, "anon_pattern_6": { "match": "\\bs[A-Z]\\w*\\b", "name": "variable.other.readwrite.static.mac-classic.c" }, "anon_pattern_7": { "match": "\\b(NULL|true|false|TRUE|FALSE)\\b", "name": "constant.language.c" }, "anon_pattern_8": { "match": "\\b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t)\\b", "name": "support.type.sys-types.c" }, "anon_pattern_9": { "match": "\\b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\\b", "name": "support.type.pthread.c" }, "anon_pattern_range_1": { "name": "meta.preprocessor.macro.c", "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*define\\b)\\s+((?", "endCaptures": { "0": { "name": "punctuation.definition.string.end.c" } }, "name": "string.quoted.other.lt-gt.include.c" } ] }, "anon_pattern_range_4": { "begin": "^\\s*((#)\\s*line)\\b", "beginCaptures": { "1": { "name": "keyword.control.directive.line.c" }, "2": { "name": "punctuation.definition.directive.c" } }, "end": "(?=(?://|/\\*))|(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", "beginCaptures": { "1": { "name": "variable.other.c" }, "2": { "name": "punctuation.section.parens.begin.bracket.round.initialization.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.initialization.c" } }, "patterns": [ { "include": "#function-call-innards" } ] }, { "begin": "{", "beginCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.c" } }, "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.c" } }, "patterns": [ { "include": "#block_innards" } ] }, { "include": "#parens-block" }, { "include": "$self" } ] }, "c_conditional_context": { "patterns": [ { "include": "$self" }, { "include": "#block_innards" } ] }, "c_function_call": { "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", "end": "(?<=\\))(?!\\w)", "name": "meta.function-call.c", "patterns": [ { "include": "#function-call-innards" } ] }, "case_statement": { "name": "meta.conditional.case.c", "begin": "((?>(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))((?\\s*)(\\/\\/[!\\/]+)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.documentation.c" } }, "end": "(?<=\\n)(?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.italic.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.bold.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.inline.raw.string.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?\\s*(?:in|out)\\s*)+)\\])?\\s+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.c" } ] }, "3": { "name": "variable.parameter.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|uml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc" } ] }, { "match": "(\\/\\*[!*]+(?=\\s))(.+)([!*]*\\*\\/)", "captures": { "1": { "name": "punctuation.definition.comment.begin.documentation.c" }, "2": { "patterns": [ { "match": "(?<=[\\s*!\\/])[\\\\@](?:callergraph|callgraph|else|endif|f\\$|f\\[|f\\]|hidecallergraph|hidecallgraph|hiderefby|hiderefs|hideinitializer|htmlinclude|n|nosubgrouping|private|privatesection|protected|protectedsection|public|publicsection|pure|showinitializer|showrefby|showrefs|tableofcontents|\\$|\\#|<|>|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.italic.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.bold.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.inline.raw.string.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?\\s*(?:in|out)\\s*)+)\\])?\\s+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.c" } ] }, "3": { "name": "variable.parameter.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|uml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc" } ] }, "3": { "name": "punctuation.definition.comment.end.documentation.c" } }, "name": "comment.block.documentation.c" }, { "name": "comment.block.documentation.c", "begin": "((?>\\s*)\\/\\*[!*]+(?:(?:\\n|$)|(?=\\s)))", "beginCaptures": { "1": { "name": "punctuation.definition.comment.begin.documentation.c" } }, "end": "([!*]*\\*\\/)", "endCaptures": { "1": { "name": "punctuation.definition.comment.end.documentation.c" } }, "patterns": [ { "match": "(?<=[\\s*!\\/])[\\\\@](?:callergraph|callgraph|else|endif|f\\$|f\\[|f\\]|hidecallergraph|hidecallgraph|hiderefby|hiderefs|hideinitializer|htmlinclude|n|nosubgrouping|private|privatesection|protected|protectedsection|public|publicsection|pure|showinitializer|showrefby|showrefs|tableofcontents|\\$|\\#|<|>|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.italic.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.bold.doxygen.c" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "name": "markup.inline.raw.string.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?\\s*(?:in|out)\\s*)+)\\])?\\s+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.c" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.c" } ] }, "3": { "name": "variable.parameter.c" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|uml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.c" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc" } ] }, { "match": "^\\/\\* =(\\s*.*?)\\s*= \\*\\/$\\n?", "captures": { "1": { "name": "meta.toc-list.banner.block.c" } }, "name": "comment.block.banner.c" }, { "name": "comment.block.c", "begin": "(\\/\\*)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.begin.c" } }, "end": "(\\*\\/)", "endCaptures": { "1": { "name": "punctuation.definition.comment.end.c" } } }, { "match": "^\\/\\/ =(\\s*.*?)\\s*=$\\n?", "captures": { "1": { "name": "meta.toc-list.banner.line.c" } }, "name": "comment.line.banner.c" }, { "begin": "((?:^[ \\t]+)?)(?=\\/\\/)", "beginCaptures": { "1": { "name": "punctuation.whitespace.comment.leading.c" } }, "end": "(?!\\G)", "patterns": [ { "name": "comment.line.double-slash.c", "begin": "(\\/\\/)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.c" } }, "end": "(?=\\n)", "patterns": [ { "include": "#line_continuation_character" } ] } ] } ] }, { "include": "#block_comment" }, { "include": "#line_comment" } ] }, { "include": "#block_comment" }, { "include": "#line_comment" } ] }, "default_statement": { "name": "meta.conditional.case.c", "begin": "((?>(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))((?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" }, "2": { "name": "punctuation.section.arguments.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.c" } }, "patterns": [ { "include": "#function-call-innards" } ] }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.c" } }, "patterns": [ { "include": "#function-call-innards" } ] }, { "include": "#block_innards" } ] }, "function-innards": { "patterns": [ { "include": "#comments" }, { "include": "#storage_types" }, { "include": "#operators" }, { "include": "#vararg_ellipses" }, { "name": "meta.function.definition.parameters.c", "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" }, "2": { "name": "punctuation.section.parameters.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.c" } }, "patterns": [ { "include": "#probably_a_parameter" }, { "include": "#function-innards" } ] }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.c" } }, "patterns": [ { "include": "#function-innards" } ] }, { "include": "$self" } ] }, "inline_comment": { "patterns": [ { "patterns": [ { "match": "(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/))", "captures": { "1": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "2": { "name": "comment.block.c" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } } }, { "match": "(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/))", "captures": { "1": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "2": { "name": "comment.block.c" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } } } ] }, { "match": "(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/))", "captures": { "1": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "2": { "name": "comment.block.c" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } } } ] }, "line_comment": { "patterns": [ { "begin": "\\s*+(\\/\\/)", "end": "(?<=\\n)(?\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:atomic_uint_least64_t|atomic_uint_least16_t|atomic_uint_least32_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_fast64_t|atomic_uint_fast32_t|atomic_int_least64_t|atomic_int_least32_t|pthread_rwlockattr_t|atomic_uint_fast16_t|pthread_mutexattr_t|atomic_int_fast16_t|atomic_uint_fast8_t|atomic_int_fast64_t|atomic_int_least8_t|atomic_int_fast32_t|atomic_int_fast8_t|pthread_condattr_t|atomic_uintptr_t|atomic_ptrdiff_t|pthread_rwlock_t|atomic_uintmax_t|pthread_mutex_t|atomic_intmax_t|atomic_intptr_t|atomic_char32_t|atomic_char16_t|pthread_attr_t|atomic_wchar_t|uint_least64_t|uint_least32_t|uint_least16_t|pthread_cond_t|pthread_once_t|uint_fast64_t|uint_fast16_t|atomic_size_t|uint_least8_t|int_least64_t|int_least32_t|int_least16_t|pthread_key_t|atomic_ullong|atomic_ushort|uint_fast32_t|atomic_schar|atomic_short|uint_fast8_t|int_fast64_t|int_fast32_t|int_fast16_t|atomic_ulong|atomic_llong|int_least8_t|atomic_uchar|memory_order|suseconds_t|int_fast8_t|atomic_bool|atomic_char|atomic_uint|atomic_long|atomic_int|useconds_t|_Imaginary|blksize_t|pthread_t|in_addr_t|uintptr_t|in_port_t|uintmax_t|uintmax_t|blkcnt_t|uint16_t|unsigned|_Complex|uint32_t|intptr_t|intmax_t|intmax_t|uint64_t|u_quad_t|int64_t|int32_t|ssize_t|caddr_t|clock_t|uint8_t|u_short|swblk_t|segsz_t|int16_t|fixpt_t|daddr_t|nlink_t|qaddr_t|size_t|time_t|mode_t|signed|quad_t|ushort|u_long|u_char|double|int8_t|ino_t|uid_t|pid_t|_Bool|float|dev_t|div_t|short|gid_t|off_t|u_int|key_t|id_t|uint|long|void|char|bool|id_t|int)\\b)[a-zA-Z_]\\w*\\b(?!\\())", "captures": { "1": { "name": "variable.other.object.access.c" }, "2": { "name": "punctuation.separator.dot-access.c" }, "3": { "name": "punctuation.separator.pointer-access.c" }, "4": { "patterns": [ { "include": "#member_access" }, { "include": "#method_access" }, { "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))", "captures": { "1": { "name": "variable.other.object.access.c" }, "2": { "name": "punctuation.separator.dot-access.c" }, "3": { "name": "punctuation.separator.pointer-access.c" } } } ] }, "5": { "name": "variable.other.member.c" } } }, "method_access": { "contentName": "meta.function-call.member.c", "begin": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*([a-zA-Z_]\\w*)(\\()", "beginCaptures": { "1": { "name": "variable.other.object.access.c" }, "2": { "name": "punctuation.separator.dot-access.c" }, "3": { "name": "punctuation.separator.pointer-access.c" }, "4": { "patterns": [ { "include": "#member_access" }, { "include": "#method_access" }, { "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))", "captures": { "1": { "name": "variable.other.object.access.c" }, "2": { "name": "punctuation.separator.dot-access.c" }, "3": { "name": "punctuation.separator.pointer-access.c" } } } ] }, "5": { "name": "entity.name.function.member.c" }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.function.member.c" } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.section.arguments.end.bracket.round.function.member.c" } }, "patterns": [ { "include": "#function-call-innards" } ] }, "numbers": { "match": "(?>=|\\|=", "name": "keyword.operator.assignment.compound.bitwise.c" }, { "match": "<<|>>", "name": "keyword.operator.bitwise.shift.c" }, { "match": "!=|<=|>=|==|<|>", "name": "keyword.operator.comparison.c" }, { "match": "&&|!|\\|\\|", "name": "keyword.operator.logical.c" }, { "match": "&|\\||\\^|~", "name": "keyword.operator.c" }, { "match": "=", "name": "keyword.operator.assignment.c" }, { "match": "%|\\*|/|-|\\+", "name": "keyword.operator.c" }, { "begin": "(\\?)", "beginCaptures": { "1": { "name": "keyword.operator.ternary.c" } }, "end": "(:)", "endCaptures": { "1": { "name": "keyword.operator.ternary.c" } }, "patterns": [ { "include": "#function-call-innards" }, { "include": "$self" } ] } ] }, "parens": { "name": "meta.parens.c", "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.c" } }, "patterns": [ { "include": "$self" } ] }, "parens-block": { "name": "meta.parens.block.c", "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.c" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.c" } }, "patterns": [ { "include": "#block_innards" }, { "match": "(?-mix:(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" }, "2": { "name": "punctuation.section.arguments.begin.bracket.round.c" } }, "end": "(\\))|(?\\]\\)]))\\s*([a-zA-Z_]\\w*)\\s*(?=(?:\\[\\]\\s*)?(?:,|\\)))", "captures": { "1": { "name": "variable.parameter.probably.c" } } }, "static_assert": { "begin": "((?>(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))((?(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))(\\()", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "3": { "name": "comment.block.c" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] }, "5": { "name": "keyword.other.static_assert.c" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "8": { "name": "comment.block.c" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] }, "10": { "name": "punctuation.section.arguments.begin.bracket.round.static_assert.c" } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.section.arguments.end.bracket.round.static_assert.c" } }, "patterns": [ { "name": "meta.static_assert.message.c", "begin": "(,)\\s*(?=(?:L|u8|u|U\\s*\\\")?)", "beginCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.c" } }, "end": "(?=\\))", "patterns": [ { "include": "#string_context" } ] }, { "include": "#evaluation_context" } ] }, "storage_types": { "patterns": [ { "match": "(?-mix:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:\\n|$)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "3": { "name": "comment.block.c" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } } }, { "include": "#comments" }, { "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\()", "beginCaptures": { "1": { "name": "punctuation.section.parens.begin.bracket.round.assembly.c" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "4": { "name": "comment.block.c" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.section.parens.end.bracket.round.assembly.c" } }, "patterns": [ { "name": "string.quoted.double.c", "contentName": "meta.embedded.assembly.c", "begin": "(R?)(\")", "beginCaptures": { "1": { "name": "meta.encoding.c" }, "2": { "name": "punctuation.definition.string.begin.assembly.c" } }, "end": "(\")", "endCaptures": { "1": { "name": "punctuation.definition.string.end.assembly.c" } }, "patterns": [ { "include": "source.asm" }, { "include": "source.x86" }, { "include": "source.x86_64" }, { "include": "source.arm" }, { "include": "#backslash_escapes" }, { "include": "#string_escaped_char" } ] }, { "begin": "(\\()", "beginCaptures": { "1": { "name": "punctuation.section.parens.begin.bracket.round.assembly.inner.c" } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.section.parens.end.bracket.round.assembly.inner.c" } }, "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "\\[((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))([a-zA-Z_]\\w*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\]", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "3": { "name": "comment.block.c" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] }, "5": { "name": "variable.other.asm.label.c" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "8": { "name": "comment.block.c" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] } } }, { "match": ":", "name": "punctuation.separator.delimiter.colon.assembly.c" }, { "include": "#comments" } ] } ] } ] }, "string_escaped_char": { "patterns": [ { "match": "(?x)\\\\ (\n\\\\\t\t\t |\n[abefnprtv'\"?] |\n[0-3]\\d{,2}\t |\n[4-7]\\d?\t\t|\nx[a-fA-F0-9]{,2} |\nu[a-fA-F0-9]{,4} |\nU[a-fA-F0-9]{,8} )", "name": "constant.character.escape.c" }, { "match": "\\\\.", "name": "invalid.illegal.unknown-escape.c" } ] }, "string_placeholder": { "patterns": [ { "match": "(?x) %\n(\\d+\\$)?\t\t\t\t\t\t # field (argument #)\n[#0\\- +']*\t\t\t\t\t\t # flags\n[,;:_]?\t\t\t\t\t\t\t # separator character (AltiVec)\n((-?\\d+)|\\*(-?\\d+\\$)?)?\t\t # minimum field width\n(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?\t# precision\n(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier\n[diouxXDOUeEfFgGaACcSspn%]\t\t # conversion type", "name": "constant.other.placeholder.c" }, { "match": "(%)(?!\"\\s*(PRI|SCN))", "captures": { "1": { "name": "invalid.illegal.placeholder.c" } } } ] }, "strings": { "patterns": [ { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.c" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.c" } }, "name": "string.quoted.double.c", "patterns": [ { "include": "#string_escaped_char" }, { "include": "#string_placeholder" }, { "include": "#line_continuation_character" } ] }, { "begin": "'", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.c" } }, "end": "'", "endCaptures": { "0": { "name": "punctuation.definition.string.end.c" } }, "name": "string.quoted.single.c", "patterns": [ { "include": "#string_escaped_char" }, { "include": "#line_continuation_character" } ] } ] }, "switch_conditional_parentheses": { "name": "meta.conditional.switch.c", "begin": "((?>(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))(\\()", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.c punctuation.definition.comment.begin.c" }, "3": { "name": "comment.block.c" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.c punctuation.definition.comment.end.c" }, { "match": "\\*", "name": "comment.block.c" } ] }, "5": { "name": "punctuation.section.parens.begin.bracket.round.conditional.switch.c" } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.section.parens.end.bracket.round.conditional.switch.c" } }, "patterns": [ { "include": "#evaluation_context" }, { "include": "#c_conditional_context" } ] }, "switch_statement": { "name": "meta.block.switch.c", "begin": "(((?>(?:(?:(?>(?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))((?|\\?\\?>)|(?=[;>\\[\\]=]))", "patterns": [ { "name": "meta.head.switch.c", "begin": "\\G ?", "end": "((?:\\{|<%|\\?\\?<|(?=;)))", "endCaptures": { "1": { "name": "punctuation.section.block.begin.bracket.curly.switch.c" } }, "patterns": [ { "include": "#switch_conditional_parentheses" }, { "include": "$self" } ] }, { "name": "meta.body.switch.c", "begin": "(?<=\\{|<%|\\?\\?<)", "end": "(\\}|%>|\\?\\?>)", "endCaptures": { "1": { "name": "punctuation.section.block.end.bracket.curly.switch.c" } }, "patterns": [ { "include": "#default_statement" }, { "include": "#case_statement" }, { "include": "$self" }, { "include": "#block_innards" } ] }, { "name": "meta.tail.switch.c", "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", "end": "[\\s\\n]*(?=;)", "patterns": [ { "include": "$self" } ] } ] }, "vararg_ellipses": { "match": "(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\{)", "end": "\\}|(?=(?|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::))?(?:\\s+)?((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?=(?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "punctuation.definition.function.return-type.cpp" }, "2": { "patterns": [ { "include": "source.cpp#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?|(?=(?])|(?<=\\Wreturn|^return))(?:\\s+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))[\\[\\];=]))", "end": "(?<=[;}])|(?=(?", "end": "(?=\\{)|(?=(?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\()", "end": "\\)|(?=(?|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "source.cpp#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.property.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "source.cpp#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.access.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "include": "source.cpp#member_access" }, { "include": "#method_access" } ] }, "10": { "name": "entity.name.function.member.cpp" }, "11": { "name": "punctuation.section.arguments.begin.bracket.round.function.member.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.member.cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "ms_attributes": { "begin": "__declspec\\(", "end": "\\)|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?>=|\\|=", "name": "keyword.operator.assignment.compound.bitwise.cpp" }, { "match": "<<|>>", "name": "keyword.operator.bitwise.shift.cpp" }, { "match": "!=|<=|>=|==|<|>", "name": "keyword.operator.comparison.cpp" }, { "match": "&&|!|\\|\\|", "name": "keyword.operator.logical.cpp" }, { "match": "&|\\||\\^|~", "name": "keyword.operator.bitwise.cpp" }, { "include": "source.cpp#assignment_operator" }, { "match": "%|\\*|\\/|-|\\+", "name": "keyword.operator.arithmetic.cpp" }, { "include": "#ternary_operator" } ] }, "parameter": { "begin": "((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=\\w)", "end": "(?:(?=\\))|(,))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?=(?|(?=(?|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>|(?=(?|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)?((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.class.cpp" } }, "name": "meta.body.class.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.class.cpp", "patterns": [ { "include": "$self" } ] } ] }, "class_declare": { "match": "((?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.italic.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.bold.doxygen.cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))\\s+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cpp" }, "2": { "name": "markup.inline.raw.string.cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:\\s+)?(?:in|out)(?:\\s+)?)+)\\])?(\\s+((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.constructor.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "patterns": [ { "include": "#functional_specifiers_pre_parameters" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "8": { "name": "comment.block.cpp" }, "9": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "10": { "name": "storage.type.modifier.calling-convention.cpp" }, "11": { "patterns": [ { "include": "#inline_comment" } ] }, "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "13": { "name": "comment.block.cpp" }, "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "15": { "name": "entity.name.function.constructor.cpp entity.name.function.definition.special.constructor.cpp" } }, "endCaptures": {}, "name": "meta.function.definition.special.constructor.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.constructor.cpp" } }, "name": "meta.head.function.definition.special.constructor.cpp", "patterns": [ { "include": "#ever_present_context" }, { "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "name": "keyword.other.default.function.cpp keyword.other.default.constructor.cpp" }, "7": { "name": "keyword.other.delete.function.cpp keyword.other.delete.constructor.cpp" } } }, { "include": "#functional_specifiers_pre_parameters" }, { "begin": ":", "end": "(?=\\{)", "beginCaptures": { "0": { "name": "punctuation.separator.initializers.cpp" } }, "endCaptures": {}, "patterns": [ { "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cpp" }, "2": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "3": {}, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.initializer.cpp" } }, "contentName": "meta.parameter.initialization", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cpp" } }, "name": "meta.body.function.definition.special.constructor.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.constructor.cpp", "patterns": [ { "include": "$self" } ] } ] }, "constructor_root": { "begin": "\\s*+((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.constructor.cpp" }, "1": { "name": "storage.type.modifier.calling-convention.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.constructor.cpp" }, { "match": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cpp" }, "2": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "3": {}, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.initializer.cpp" } }, "contentName": "meta.parameter.initialization", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cpp" } }, "name": "meta.body.function.definition.special.constructor.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.constructor.cpp", "patterns": [ { "include": "$self" } ] } ] }, "control_flow_keywords": { "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\{)", "end": "\\}", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;))))(?:\\s+)?(;?)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "3": { "name": "keyword.control.directive.import.cpp" }, "5": { "name": "string.quoted.other.lt-gt.include.cpp" }, "6": { "name": "punctuation.definition.string.begin.cpp" }, "7": { "name": "punctuation.definition.string.end.cpp" }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "10": { "name": "string.quoted.double.include.cpp" }, "11": { "name": "punctuation.definition.string.begin.cpp" }, "12": { "name": "punctuation.definition.string.end.cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "15": { "name": "entity.name.other.preprocessor.macro.include.cpp" }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "18": { "patterns": [ { "include": "#inline_comment" } ] }, "19": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "22": { "name": "punctuation.terminator.statement.cpp" } }, "name": "meta.preprocessor.import.cpp" }, "d9bc4796b0b_preprocessor_number_literal": { "match": "(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.member.destructor.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "storage.type.modifier.calling-convention.cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "8": { "name": "comment.block.cpp" }, "9": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "10": { "patterns": [ { "include": "#functional_specifiers_pre_parameters" } ] }, "11": { "patterns": [ { "include": "#inline_comment" } ] }, "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "13": { "name": "comment.block.cpp" }, "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "15": { "name": "entity.name.function.destructor.cpp entity.name.function.definition.special.member.destructor.cpp" } }, "endCaptures": {}, "name": "meta.function.definition.special.member.destructor.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.member.destructor.cpp" } }, "name": "meta.head.function.definition.special.member.destructor.cpp", "patterns": [ { "include": "#ever_present_context" }, { "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "name": "keyword.other.default.function.cpp keyword.other.default.constructor.cpp keyword.other.default.destructor.cpp" }, "7": { "name": "keyword.other.delete.function.cpp keyword.other.delete.constructor.cpp keyword.other.delete.destructor.cpp" } } }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cpp" } }, "contentName": "meta.function.definition.parameters.special.member.destructor", "patterns": [] }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cpp" } }, "name": "meta.body.function.definition.special.member.destructor.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.member.destructor.cpp", "patterns": [ { "include": "$self" } ] } ] }, "destructor_root": { "begin": "((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.member.destructor.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "storage.type.modifier.calling-convention.cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "8": { "name": "comment.block.cpp" }, "9": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "10": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.destructor.cpp" }, { "match": "(?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cpp" } }, "name": "meta.body.function.definition.special.member.destructor.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.member.destructor.cpp", "patterns": [ { "include": "$self" } ] } ] }, "diagnostic": { "begin": "(^((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(#)(?:\\s+)?((?:error|warning)))\\b(?:\\s+)?", "end": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::))?(?:\\s+)?((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.enum.cpp" }, "1": { "name": "storage.type.enum.cpp" }, "2": { "name": "storage.type.enum.enum-key.$2.cpp" }, "3": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "4": { "name": "entity.name.type.enum.cpp" }, "5": { "name": "punctuation.separator.colon.type-specifier.cpp" }, "6": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "7": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, "8": { "patterns": [ { "include": "#template_call_range" } ] }, "9": {}, "10": { "name": "entity.name.scope-resolution.cpp" }, "11": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "12": {}, "13": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "14": { "name": "comment.block.cpp" }, "15": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "16": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, "17": { "name": "storage.type.integral.$17.cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cpp" }, "2": { "name": "punctuation.terminator.statement.cpp" } }, "name": "meta.block.enum.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.enum.cpp" } }, "name": "meta.head.enum.cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.enum.cpp" } }, "name": "meta.body.enum.cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#enumerator_list" }, { "include": "#comments" }, { "include": "#comma" }, { "include": "#semicolon" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.enum.cpp", "patterns": [ { "include": "$self" } ] } ] }, "enum_declare": { "match": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.extern.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "storage.type.extern.cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cpp" }, "2": { "name": "punctuation.terminator.statement.cpp" } }, "name": "meta.block.extern.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.extern.cpp" } }, "name": "meta.head.extern.cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.extern.cpp" } }, "name": "meta.body.extern.cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.extern.cpp", "patterns": [ { "include": "$self" } ] }, { "include": "$self" } ] }, "function_body_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#using_namespace" }, { "include": "#type_alias" }, { "include": "#using_name" }, { "include": "#namespace_alias" }, { "include": "#typedef_class" }, { "include": "#typedef_struct" }, { "include": "#typedef_union" }, { "include": "#misc_keywords" }, { "include": "#standard_declares" }, { "include": "#class_block" }, { "include": "#struct_block" }, { "include": "#union_block" }, { "include": "#enum_block" }, { "include": "#access_control_keywords" }, { "include": "#block" }, { "include": "#static_assert" }, { "include": "#assembly" }, { "include": "#function_pointer" }, { "include": "#switch_statement" }, { "include": "#goto_statement" }, { "include": "#evaluation_context" }, { "include": "#label" } ] }, "function_call": { "begin": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.function.call.cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "8": { "name": "comment.block.cpp" }, "9": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "10": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "11": {}, "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "13": { "name": "comment.block.cpp" }, "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "15": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "function_definition": { "begin": "(?:(?:^|\\G|(?<=;|\\}))|(?<=>|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.cpp" }, "1": { "name": "storage.type.template.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "match": "((?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "14": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "17": { "name": "comment.block.cpp" }, "18": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "21": { "name": "comment.block.cpp" }, "22": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "23": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "punctuation.definition.function.return-type.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "7": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "10": { "name": "comment.block.cpp" }, "11": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "14": { "name": "comment.block.cpp" }, "15": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "16": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.cpp" } }, "name": "meta.body.function.definition.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.cpp", "patterns": [ { "include": "$self" } ] } ] }, "function_parameter_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#parameter" }, { "include": "#comma" } ] }, "function_pointer": { "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;))))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "3": { "name": "keyword.control.directive.$5.cpp" }, "4": { "name": "punctuation.definition.directive.cpp" }, "6": { "name": "string.quoted.other.lt-gt.include.cpp" }, "7": { "name": "punctuation.definition.string.begin.cpp" }, "8": { "name": "punctuation.definition.string.end.cpp" }, "9": { "patterns": [ { "include": "#inline_comment" } ] }, "10": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "11": { "name": "string.quoted.double.include.cpp" }, "12": { "name": "punctuation.definition.string.begin.cpp" }, "13": { "name": "punctuation.definition.string.end.cpp" }, "14": { "patterns": [ { "include": "#inline_comment" } ] }, "15": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "16": { "name": "entity.name.other.preprocessor.macro.include.cpp" }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "21": { "patterns": [ { "include": "#inline_comment" } ] }, "22": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] } }, "name": "meta.preprocessor.include.cpp" }, "inheritance_context": { "patterns": [ { "include": "#ever_present_context" }, { "match": ",", "name": "punctuation.separator.delimiter.comma.inheritance.cpp" }, { "match": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "7": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?])|(?<=\\Wreturn|^return))(?:\\s+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))[\\[\\];=]))", "end": "(?<=[;}])", "beginCaptures": { "1": { "name": "punctuation.definition.capture.begin.lambda.cpp" }, "2": { "name": "meta.lambda.capture.cpp", "patterns": [ { "include": "#the_this_keyword" }, { "match": "((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?=\\]|\\z|$)|(,))|(\\=))", "captures": { "1": { "name": "variable.parameter.capture.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "name": "punctuation.separator.delimiter.comma.cpp" }, "7": { "name": "keyword.operator.assignment.cpp" } } }, { "include": "#evaluation_context" } ] }, "3": {}, "4": { "name": "punctuation.definition.capture.end.lambda.cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "7": { "name": "comment.block.cpp" }, "8": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } }, "endCaptures": {}, "patterns": [ { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.definition.parameters.begin.lambda.cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.parameters.end.lambda.cpp" } }, "name": "meta.function.definition.parameters.lambda.cpp", "patterns": [ { "include": "#function_parameter_context" } ] }, { "match": "(?", "end": "(?=\\{)", "beginCaptures": { "0": { "name": "punctuation.definition.lambda.return-type.cpp" } }, "endCaptures": {}, "patterns": [ { "include": "#comments" }, { "match": "\\S+", "name": "storage.type.return-type.lambda.cpp" } ] }, { "begin": "\\{", "end": "\\}", "beginCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.lambda.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.lambda.cpp" } }, "name": "meta.function.definition.body.lambda.cpp", "patterns": [ { "include": "$self" } ] } ] }, "language_constants": { "match": "(?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(\\b(?!uint_least32_t[^\\w]|uint_least16_t[^\\w]|uint_least64_t[^\\w]|int_least32_t[^\\w]|int_least64_t[^\\w]|uint_fast32_t[^\\w]|uint_fast64_t[^\\w]|uint_least8_t[^\\w]|uint_fast16_t[^\\w]|int_least16_t[^\\w]|int_fast16_t[^\\w]|int_least8_t[^\\w]|uint_fast8_t[^\\w]|int_fast64_t[^\\w]|int_fast32_t[^\\w]|int_fast8_t[^\\w]|suseconds_t[^\\w]|useconds_t[^\\w]|in_addr_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|in_port_t[^\\w]|uintptr_t[^\\w]|blksize_t[^\\w]|uint32_t[^\\w]|uint64_t[^\\w]|u_quad_t[^\\w]|intmax_t[^\\w]|intmax_t[^\\w]|unsigned[^\\w]|blkcnt_t[^\\w]|uint16_t[^\\w]|intptr_t[^\\w]|swblk_t[^\\w]|wchar_t[^\\w]|u_short[^\\w]|qaddr_t[^\\w]|caddr_t[^\\w]|daddr_t[^\\w]|fixpt_t[^\\w]|nlink_t[^\\w]|segsz_t[^\\w]|clock_t[^\\w]|ssize_t[^\\w]|int16_t[^\\w]|int32_t[^\\w]|int64_t[^\\w]|uint8_t[^\\w]|int8_t[^\\w]|mode_t[^\\w]|quad_t[^\\w]|ushort[^\\w]|u_long[^\\w]|u_char[^\\w]|double[^\\w]|signed[^\\w]|time_t[^\\w]|size_t[^\\w]|key_t[^\\w]|div_t[^\\w]|ino_t[^\\w]|uid_t[^\\w]|gid_t[^\\w]|off_t[^\\w]|pid_t[^\\w]|float[^\\w]|dev_t[^\\w]|u_int[^\\w]|short[^\\w]|bool[^\\w]|id_t[^\\w]|uint[^\\w]|long[^\\w]|char[^\\w]|void[^\\w]|auto[^\\w]|id_t[^\\w]|int[^\\w])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?!\\())", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "3": { "name": "variable.language.this.cpp" }, "4": { "name": "variable.other.object.access.cpp" }, "5": { "name": "punctuation.separator.dot-access.cpp" }, "6": { "name": "punctuation.separator.pointer-access.cpp" }, "7": { "patterns": [ { "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.property.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.access.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "include": "#member_access" }, { "include": "#method_access" } ] }, "8": { "name": "variable.other.property.cpp" } } }, "memory_operators": { "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(delete)(?:\\s+)?(\\[\\])|(delete))|(new))(?!\\w))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "3": { "name": "keyword.operator.wordlike.cpp" }, "4": { "name": "keyword.operator.delete.array.cpp" }, "5": { "name": "keyword.operator.delete.array.bracket.cpp" }, "6": { "name": "keyword.operator.delete.cpp" }, "7": { "name": "keyword.operator.new.cpp" } } }, "method_access": { "begin": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.access.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" }, "9": { "patterns": [ { "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.property.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "variable.language.this.cpp" }, "6": { "name": "variable.other.object.access.cpp" }, "7": { "name": "punctuation.separator.dot-access.cpp" }, "8": { "name": "punctuation.separator.pointer-access.cpp" } } }, { "include": "#member_access" }, { "include": "#method_access" } ] }, "10": { "name": "entity.name.function.member.cpp" }, "11": { "name": "punctuation.section.arguments.begin.bracket.round.function.member.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.member.cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "misc_keywords": { "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.namespace.cpp" }, "1": { "name": "keyword.other.namespace.definition.cpp storage.type.namespace.definition.cpp" } }, "endCaptures": {}, "name": "meta.block.namespace.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.namespace.cpp" } }, "name": "meta.head.namespace.cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#attributes_context" }, { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.namespace.cpp" } }, "name": "meta.body.namespace.cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.namespace.cpp", "patterns": [ { "include": "$self" } ] } ] }, "noexcept_operator": { "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.operator-overload.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "include": "#inline_comment" } ] }, "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "13": { "name": "comment.block.cpp" }, "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "15": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.operator-overload.cpp" } }, "name": "meta.body.function.definition.special.operator-overload.cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.operator-overload.cpp", "patterns": [ { "include": "$self" } ] } ] }, "operators": { "patterns": [ { "begin": "((?>=|\\|=", "name": "keyword.operator.assignment.compound.bitwise.cpp" }, { "match": "<<|>>", "name": "keyword.operator.bitwise.shift.cpp" }, { "match": "!=|<=|>=|==|<|>", "name": "keyword.operator.comparison.cpp" }, { "match": "&&|!|\\|\\|", "name": "keyword.operator.logical.cpp" }, { "match": "&|\\||\\^|~", "name": "keyword.operator.bitwise.cpp" }, { "include": "#assignment_operator" }, { "match": "%|\\*|\\/|-|\\+", "name": "keyword.operator.arithmetic.cpp" }, { "include": "#ternary_operator" } ] }, "over_qualified_types": { "patterns": [ { "match": "(\\bstruct)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.])", "captures": { "0": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "1": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "6": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_call": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_call_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.call.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" } } }, "scope_resolution_function_definition": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_definition_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_definition_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_definition_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.definition.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" } } }, "scope_resolution_function_definition_operator_overload": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_definition_operator_overload_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_definition_operator_overload_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_definition_operator_overload_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.definition.operator-overload.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" } } }, "scope_resolution_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" } } }, "scope_resolution_namespace_alias": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_alias_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_alias_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_alias_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.alias.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" } } }, "scope_resolution_namespace_block": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_block_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_block_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_block_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.block.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" } } }, "scope_resolution_namespace_using": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_using_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_using_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_using_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.using.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" } } }, "scope_resolution_parameter": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_parameter_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_parameter_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_parameter_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.parameter.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" } } }, "scope_resolution_template_call": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_template_call_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_template_call_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_template_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.template.call.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" } } }, "scope_resolution_template_definition": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_template_definition_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.template.definition.cpp" }, "6": { "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" } } }, "semicolon": { "match": ";", "name": "punctuation.terminator.statement.cpp" }, "simple_type": { "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?", "captures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "7": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.struct.cpp" } }, "name": "meta.body.struct.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.struct.cpp", "patterns": [ { "include": "$self" } ] } ] }, "struct_declare": { "match": "((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.switch.cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { "name": "keyword.control.switch.cpp" } }, "endCaptures": {}, "name": "meta.block.switch.cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.switch.cpp" } }, "name": "meta.head.switch.cpp", "patterns": [ { "include": "#switch_conditional_parentheses" }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.switch.cpp" } }, "name": "meta.body.switch.cpp", "patterns": [ { "include": "#default_statement" }, { "include": "#case_statement" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.switch.cpp", "patterns": [ { "include": "$self" } ] } ] }, "template_argument_defaulted": { "match": "(?<=<|,)(?:\\s+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s+((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(\\=)", "captures": { "1": { "name": "storage.type.template.argument.$1.cpp" }, "2": { "name": "entity.name.type.template.cpp" }, "3": { "name": "keyword.operator.assignment.cpp" } } }, "template_call_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#template_call_range" }, { "include": "#storage_types" }, { "include": "#language_constants" }, { "include": "#scope_resolution_template_call_inner_generated" }, { "include": "#operators" }, { "include": "#number_literal" }, { "include": "#string_context" }, { "include": "#comma_in_template_argument" }, { "include": "#qualified_type" } ] }, "template_call_innards": { "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+", "captures": { "0": { "patterns": [ { "include": "#template_call_range" } ] }, "2": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { "name": "comment.block.cpp" }, "4": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } }, "name": "meta.template.call.cpp" }, "template_call_range": { "begin": "<", "end": ">", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, "template_definition": { "begin": "(?", "beginCaptures": { "1": { "name": "storage.type.template.cpp" }, "2": { "name": "punctuation.section.angle-brackets.begin.template.definition.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.definition.cpp" } }, "name": "meta.template.definition.cpp", "patterns": [ { "begin": "(?<=\\w)(?:\\s+)?<", "end": ">", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "patterns": [ { "include": "#template_call_context" } ] }, { "include": "#template_definition_context" } ] }, "template_definition_argument": { "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\.\\.\\.)(?:\\s+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|(?)(?:\\s+)?(class|typename)(?:\\s+((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))?)(?:\\s+)?(?:(\\=)(?:\\s+)?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?(?:(,)|(?=>|$))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "3": { "name": "storage.type.template.argument.$3.cpp" }, "4": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "storage.type.template.argument.$0.cpp" } ] }, "5": { "name": "entity.name.type.template.cpp" }, "6": { "name": "storage.type.template.argument.$6.cpp" }, "7": { "name": "punctuation.vararg-ellipses.template.definition.cpp" }, "8": { "name": "entity.name.type.template.cpp" }, "9": { "name": "storage.type.template.cpp" }, "10": { "name": "punctuation.section.angle-brackets.begin.template.definition.cpp" }, "11": { "name": "storage.type.template.argument.$11.cpp" }, "12": { "name": "entity.name.type.template.cpp" }, "13": { "name": "punctuation.section.angle-brackets.end.template.definition.cpp" }, "14": { "name": "storage.type.template.argument.$14.cpp" }, "15": { "name": "entity.name.type.template.cpp" }, "16": { "name": "keyword.operator.assignment.cpp" }, "17": { "name": "punctuation.separator.delimiter.comma.template.argument.cpp" } } }, "template_definition_context": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" }, { "include": "#template_definition_argument" }, { "include": "#template_argument_defaulted" }, { "include": "#template_call_innards" }, { "include": "#evaluation_context" } ] }, "template_explicit_instantiation": { "match": "(?)(?:\\s+)?$", "captures": { "1": { "name": "storage.type.template.cpp" }, "2": { "name": "punctuation.section.angle-brackets.begin.template.definition.cpp" }, "3": { "name": "meta.template.definition.cpp", "patterns": [ { "include": "#template_definition_context" } ] }, "4": { "name": "punctuation.section.angle-brackets.end.template.definition.cpp" } } }, "ternary_operator": { "begin": "\\?", "end": ":", "beginCaptures": { "0": { "name": "keyword.operator.ternary.cpp" } }, "endCaptures": { "0": { "name": "keyword.operator.ternary.cpp" } }, "patterns": [ { "include": "#ever_present_context" }, { "include": "#string_context" }, { "include": "#number_literal" }, { "include": "#method_access" }, { "include": "#member_access" }, { "include": "#predefined_macros" }, { "include": "#operators" }, { "include": "#memory_operators" }, { "include": "#wordlike_operators" }, { "include": "#type_casting_operators" }, { "include": "#control_flow_keywords" }, { "include": "#exception_keywords" }, { "include": "#the_this_keyword" }, { "include": "#language_constants" }, { "include": "#builtin_storage_type_initilizer" }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "#functional_specifiers_pre_parameters" }, { "include": "#storage_types" }, { "include": "#lambdas" }, { "include": "#attributes_context" }, { "include": "#parentheses" }, { "include": "#function_call" }, { "include": "#scope_resolution_inner_generated" }, { "include": "#square_brackets" }, { "include": "#semicolon" }, { "include": "#comma" } ], "applyEndPatternLast": 1 }, "the_this_keyword": { "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))|(.*(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "9": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "14": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.class.cpp" } }, "name": "meta.body.class.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.class.cpp", "patterns": [ { "match": "(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "5": { "name": "comment.block.cpp" }, "6": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.struct.cpp" } }, "name": "meta.body.struct.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.struct.cpp", "patterns": [ { "match": "(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.union.cpp" } }, "name": "meta.body.union.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.union.cpp", "patterns": [ { "match": "(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "storage.modifier.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "6": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cpp" } }, "name": "meta.template.call.cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, "7": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+", "captures": { "1": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { "name": "comment.block.cpp" }, "3": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } } } ] }, "12": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.type.cpp" }, { "match": "(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cpp" }, "1": { "name": "storage.type.$1.cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { "name": "comment.block.cpp" }, "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "9": { "name": "comment.block.cpp" }, "10": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { "patterns": [ { "match": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.union.cpp" } }, "name": "meta.body.union.cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.union.cpp", "patterns": [ { "include": "$self" } ] } ] }, "union_declare": { "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)?((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(((?:(?:protected)|(?:private)|(?:public)))(?:(?:\\s)+)?(:))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "storage.type.modifier.access.control.$4.cuda-cpp" }, "4": {}, "5": { "name": "punctuation.separator.colon.access.control.cuda-cpp" } } }, "alignas_attribute": { "begin": "alignas\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.attribute.begin.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.attribute.end.cuda-cpp" } }, "name": "support.other.attribute.cuda-cpp", "patterns": [ { "include": "#attributes_context" }, { "begin": "\\(", "end": "\\)", "beginCaptures": {}, "endCaptures": {}, "patterns": [ { "include": "#attributes_context" }, { "include": "#string_context" } ] }, { "match": "(using)(?:\\s)+((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.alignas.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.alignas.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.alignas.cuda-cpp" } }, "contentName": "meta.arguments.operator.alignas", "patterns": [ { "include": "#evaluation_context" } ] }, "alignof_operator": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.alignof.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.alignof.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.alignof.cuda-cpp" } }, "contentName": "meta.arguments.operator.alignof", "patterns": [ { "include": "#evaluation_context" } ] }, "assembly": { "begin": "(\\b(?:__asm__|asm)\\b)(?:(?:\\s)+)?((?:volatile)?)", "end": "(?!\\G)", "beginCaptures": { "1": { "name": "storage.type.asm.cuda-cpp" }, "2": { "name": "storage.modifier.cuda-cpp" } }, "endCaptures": {}, "name": "meta.asm.cuda-cpp", "patterns": [ { "match": "^((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:\\n)|$)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#comments" }, { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.assembly.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.assembly.cuda-cpp" } }, "patterns": [ { "begin": "(R?)(\")", "end": "\"", "beginCaptures": { "1": { "name": "meta.encoding.cuda-cpp" }, "2": { "name": "punctuation.definition.string.begin.assembly.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.string.end.assembly.cuda-cpp" } }, "name": "string.quoted.double.cuda-cpp", "contentName": "meta.embedded.assembly", "patterns": [ { "include": "source.asm" }, { "include": "source.x86" }, { "include": "source.x86_64" }, { "include": "source.arm" }, { "include": "#backslash_escapes" }, { "include": "#string_escaped_char" } ] }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.assembly.inner.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.assembly.inner.cuda-cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "\\[((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.other.asm.label.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": ":", "name": "punctuation.separator.delimiter.colon.assembly.cuda-cpp" }, { "include": "#comments" } ] } ] }, "assignment_operator": { "match": "\\=", "name": "keyword.operator.assignment.cuda-cpp" }, "attributes_context": { "patterns": [ { "include": "#cpp_attributes" }, { "include": "#gcc_attributes" }, { "include": "#ms_attributes" }, { "include": "#alignas_attribute" } ] }, "backslash_escapes": { "match": "(?x)\\\\ (\n\\\\\t\t\t |\n[abefnprtv'\"?] |\n[0-3][0-7]{,2}\t |\n[4-7]\\d?\t\t|\nx[a-fA-F0-9]{,2} |\nu[a-fA-F0-9]{,4} |\nU[a-fA-F0-9]{,8} )", "name": "constant.character.escape" }, "block": { "begin": "{", "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", "beginCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.cuda-cpp" } }, "name": "meta.block.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, "block_comment": { "begin": "\\s*+(\\/\\*)", "end": "\\*\\/", "beginCaptures": { "1": { "name": "punctuation.definition.comment.begin.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.comment.end.cuda-cpp" } }, "name": "comment.block.cuda-cpp" }, "builtin_storage_type_initilizer": { "begin": "(?:\\s)*+(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.class.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.class.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.class.cuda-cpp" } }, "name": "meta.head.class.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.class.cuda-cpp" } }, "name": "meta.body.class.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.class.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "class_declare": { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.class.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.class.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "comma": { "match": ",", "name": "punctuation.separator.delimiter.comma.cuda-cpp" }, "comma_in_template_argument": { "match": ",", "name": "punctuation.separator.delimiter.comma.template.argument.cuda-cpp" }, "comments": { "patterns": [ { "begin": "^(?:(?:\\s)+)?+(\\/\\/[!\\/]+)", "end": "(?<=\\n)(?|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.italic.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.bold.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.inline.raw.string.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:(?:\\s)+)?(?:in|out)(?:(?:\\s)+)?)+)\\])?(?:\\s)+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.cuda-cpp" } ] }, "3": { "name": "variable.parameter.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|throws|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|startuml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc.cuda-cpp" } ] }, { "match": "(\\/\\*[!*]+(?=\\s))(.+)([!*]*\\*\\/)", "captures": { "1": { "name": "punctuation.definition.comment.begin.documentation.cuda-cpp" }, "2": { "patterns": [ { "match": "(?<=[\\s*!\\/])[\\\\@](?:callergraph|callgraph|else|endif|f\\$|f\\[|f\\]|hidecallergraph|hidecallgraph|hiderefby|hiderefs|hideinitializer|htmlinclude|n|nosubgrouping|private|privatesection|protected|protectedsection|public|publicsection|pure|showinitializer|showrefby|showrefs|tableofcontents|\\$|\\#|<|>|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.italic.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.bold.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.inline.raw.string.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:(?:\\s)+)?(?:in|out)(?:(?:\\s)+)?)+)\\])?(?:\\s)+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.cuda-cpp" } ] }, "3": { "name": "variable.parameter.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|throws|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|startuml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc.cuda-cpp" } ] }, "3": { "name": "punctuation.definition.comment.end.documentation.cuda-cpp" } }, "name": "comment.block.documentation.cuda-cpp" }, { "begin": "(?:(?:\\s)+)?+\\/\\*[!*]+(?:(?:(?:\\n)|$)|(?=\\s))", "end": "[!*]*\\*\\/", "beginCaptures": { "0": { "name": "punctuation.definition.comment.begin.documentation.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.comment.end.documentation.cuda-cpp" } }, "name": "comment.block.documentation.cuda-cpp", "patterns": [ { "match": "(?<=[\\s*!\\/])[\\\\@](?:callergraph|callgraph|else|endif|f\\$|f\\[|f\\]|hidecallergraph|hidecallgraph|hiderefby|hiderefs|hideinitializer|htmlinclude|n|nosubgrouping|private|privatesection|protected|protectedsection|public|publicsection|pure|showinitializer|showrefby|showrefs|tableofcontents|\\$|\\#|<|>|%|\"|\\.|=|::|\\||\\-\\-|\\-\\-\\-)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:a|em|e))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.italic.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@]b)(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.bold.doxygen.cuda-cpp" } } }, { "match": "((?<=[\\s*!\\/])[\\\\@](?:c|p))(?:\\s)+(\\S+)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "name": "markup.inline.raw.string.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:a|anchor|b|c|cite|copybrief|copydetail|copydoc|def|dir|dontinclude|e|em|emoji|enum|example|extends|file|idlexcept|implements|include|includedoc|includelineno|latexinclude|link|memberof|namespace|p|package|ref|refitem|related|relates|relatedalso|relatesalso|verbinclude)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:addindex|addtogroup|category|class|defgroup|diafile|dotfile|elseif|fn|headerfile|if|ifnot|image|ingroup|interface|line|mainpage|mscfile|name|overload|page|property|protocol|section|skip|skipline|snippet|snippetdoc|snippetlineno|struct|subpage|subsection|subsubsection|typedef|union|until|vhdlflow|weakgroup)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "((?<=[\\s*!\\/])[\\\\@]param)(?:\\s*\\[((?:,?(?:(?:\\s)+)?(?:in|out)(?:(?:\\s)+)?)+)\\])?(?:\\s)+(\\b\\w+\\b)", "captures": { "1": { "name": "storage.type.class.doxygen.cuda-cpp" }, "2": { "patterns": [ { "match": "in|out", "name": "keyword.other.parameter.direction.$0.cuda-cpp" } ] }, "3": { "name": "variable.parameter.cuda-cpp" } } }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:arg|attention|author|authors|brief|bug|copyright|date|deprecated|details|exception|invariant|li|note|par|paragraph|param|post|pre|remark|remarks|result|return|returns|retval|sa|see|short|since|test|throw|throws|todo|tparam|version|warning|xrefitem)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?<=[\\s*!\\/])[\\\\@](?:code|cond|docbookonly|dot|htmlonly|internal|latexonly|link|manonly|msc|parblock|rtfonly|secreflist|startuml|verbatim|xmlonly|endcode|endcond|enddocbookonly|enddot|endhtmlonly|endinternal|endlatexonly|endlink|endmanonly|endmsc|endparblock|endrtfonly|endsecreflist|enduml|endverbatim|endxmlonly)\\b(?:\\{[^}]*\\})?", "name": "storage.type.class.doxygen.cuda-cpp" }, { "match": "(?:\\b[A-Z]+:|@[a-z_]+:)", "name": "storage.type.class.gtkdoc.cuda-cpp" } ] }, { "include": "#emacs_file_banner" }, { "include": "#block_comment" }, { "include": "#line_comment" }, { "include": "#invalid_comment_end" } ] }, "constructor_inline": { "begin": "^((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(?:__forceinline__)|(?:__noinline__)|(?:__global__)|(?:__device__)|(?:constexpr)|(?:explicit)|(?:__host__)|(?:mutable)|(?:virtual)|(?:inline)|(?:friend))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.constructor.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "patterns": [ { "include": "#functional_specifiers_pre_parameters" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "12": { "name": "comment.block.cuda-cpp" }, "13": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "14": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "17": { "name": "comment.block.cuda-cpp" }, "18": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "19": { "name": "entity.name.function.constructor.cuda-cpp entity.name.function.definition.special.constructor.cuda-cpp" } }, "endCaptures": {}, "name": "meta.function.definition.special.constructor.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.constructor.cuda-cpp" } }, "name": "meta.head.function.definition.special.constructor.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "match": "(\\=)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "keyword.other.default.constructor.cuda-cpp" }, "7": { "name": "keyword.other.delete.constructor.cuda-cpp" } } }, { "include": "#functional_specifiers_pre_parameters" }, { "begin": ":", "end": "(?=\\{)", "beginCaptures": { "0": { "name": "punctuation.separator.initializers.cuda-cpp" } }, "endCaptures": {}, "patterns": [ { "begin": "((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cuda-cpp" }, "2": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "3": {}, "4": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.initializer.cuda-cpp" } }, "contentName": "meta.parameter.initialization", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cuda-cpp" } }, "name": "meta.body.function.definition.special.constructor.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.constructor.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "constructor_root": { "begin": "\\s*+((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?::)*+)(((?>(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))::((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\14((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\())", "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.constructor.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.constructor.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "keyword.other.default.constructor.cuda-cpp" }, "7": { "name": "keyword.other.delete.constructor.cuda-cpp" } } }, { "include": "#functional_specifiers_pre_parameters" }, { "begin": ":", "end": "(?=\\{)", "beginCaptures": { "0": { "name": "punctuation.separator.initializers.cuda-cpp" } }, "endCaptures": {}, "patterns": [ { "begin": "((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cuda-cpp" }, "2": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "3": {}, "4": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.initializer.cuda-cpp" } }, "contentName": "meta.parameter.initialization", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cuda-cpp" } }, "name": "meta.body.function.definition.special.constructor.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.constructor.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "control_flow_keywords": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.control.$3.cuda-cpp" } } }, "cpp_attributes": { "begin": "\\[\\[", "end": "\\]\\]", "beginCaptures": { "0": { "name": "punctuation.section.attribute.begin.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.attribute.end.cuda-cpp" } }, "name": "support.other.attribute.cuda-cpp", "patterns": [ { "include": "#attributes_context" }, { "begin": "\\(", "end": "\\)", "beginCaptures": {}, "endCaptures": {}, "patterns": [ { "include": "#attributes_context" }, { "include": "#string_context" } ] }, { "match": "(using)(?:\\s)+((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)?(?![\\w<:.]))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\{)", "end": "\\}", "beginCaptures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((import))(?:(?:\\s)+)?(?:(?:(?:((<)[^>]*(>?)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/)))|((\\\")[^\\\"]*((?:\\\")?)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/))))|(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;)))))|((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;))))(?:(?:\\s)+)?(;?)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.control.directive.import.cuda-cpp" }, "5": { "name": "string.quoted.other.lt-gt.include.cuda-cpp" }, "6": { "name": "punctuation.definition.string.begin.cuda-cpp" }, "7": { "name": "punctuation.definition.string.end.cuda-cpp" }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "name": "string.quoted.double.include.cuda-cpp" }, "11": { "name": "punctuation.definition.string.begin.cuda-cpp" }, "12": { "name": "punctuation.definition.string.end.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "15": { "name": "entity.name.other.preprocessor.macro.include.cuda-cpp" }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "18": { "patterns": [ { "include": "#inline_comment" } ] }, "19": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "22": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.preprocessor.import.cuda-cpp" }, "d9bc4796b0b_preprocessor_number_literal": { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.other.decltype.cuda-cpp storage.type.decltype.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.decltype.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.decltype.cuda-cpp" } }, "contentName": "meta.arguments.decltype", "patterns": [ { "include": "#evaluation_context" } ] }, "decltype_specifier": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.other.decltype.cuda-cpp storage.type.decltype.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.decltype.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.decltype.cuda-cpp" } }, "contentName": "meta.arguments.decltype", "patterns": [ { "include": "#evaluation_context" } ] }, "default_statement": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(?:__forceinline__)|(?:__noinline__)|(?:__global__)|(?:__device__)|(?:constexpr)|(?:explicit)|(?:__host__)|(?:mutable)|(?:virtual)|(?:inline)|(?:friend))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*)(~(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.member.destructor.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "7": { "name": "comment.block.cuda-cpp" }, "8": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "9": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "12": { "name": "comment.block.cuda-cpp" }, "13": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "14": { "patterns": [ { "include": "#functional_specifiers_pre_parameters" } ] }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "17": { "name": "comment.block.cuda-cpp" }, "18": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "19": { "name": "entity.name.function.destructor.cuda-cpp entity.name.function.definition.special.member.destructor.cuda-cpp" } }, "endCaptures": {}, "name": "meta.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.member.destructor.cuda-cpp" } }, "name": "meta.head.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "match": "(\\=)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "keyword.other.default.constructor.cuda-cpp" }, "7": { "name": "keyword.other.delete.constructor.cuda-cpp" } } }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cuda-cpp" } }, "contentName": "meta.function.definition.parameters.special.member.destructor", "patterns": [] }, { "match": "((?:(?:final)|(?:override)))+", "captures": { "1": { "name": "keyword.operator.wordlike.cuda-cpp keyword.operator.$1.cuda-cpp" } } }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cuda-cpp" } }, "name": "meta.body.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "destructor_root": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?::)*+)(((?>(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))::((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))~\\14((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\())", "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.member.destructor.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.destructor.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "keyword.other.default.constructor.cuda-cpp" }, "7": { "name": "keyword.other.delete.constructor.cuda-cpp" } } }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cuda-cpp" } }, "contentName": "meta.function.definition.parameters.special.member.destructor", "patterns": [] }, { "match": "((?:(?:final)|(?:override)))+", "captures": { "1": { "name": "keyword.operator.wordlike.cuda-cpp keyword.operator.$1.cuda-cpp" } } }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cuda-cpp" } }, "name": "meta.body.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.member.destructor.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "diagnostic": { "begin": "(^((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?((?:error|warning)))\\b(?:(?:\\s)+)?", "end": "(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?(::))?(?:(?:\\s)+)?((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.enum.cuda-cpp" }, "1": { "name": "storage.type.enum.cuda-cpp" }, "2": { "name": "storage.type.enum.enum-key.$2.cuda-cpp" }, "3": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "4": { "name": "entity.name.type.enum.cuda-cpp" }, "5": { "name": "punctuation.separator.colon.type-specifier.cuda-cpp" }, "6": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "7": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, "8": { "patterns": [ { "include": "#template_call_range" } ] }, "9": {}, "10": { "name": "entity.name.scope-resolution.cuda-cpp" }, "11": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "12": {}, "13": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, "14": { "name": "storage.type.integral.$14.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.enum.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.enum.cuda-cpp" } }, "name": "meta.head.enum.cuda-cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.enum.cuda-cpp" } }, "name": "meta.body.enum.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#enumerator_list" }, { "include": "#comments" }, { "include": "#comma" }, { "include": "#semicolon" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.enum.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "enum_declare": { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.enum.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.enum.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "enumerator_list": { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.control.exception.$3.cuda-cpp" } } }, "extern_block": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(extern)(?=\\s*\\\")", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.extern.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "storage.type.extern.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.extern.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.extern.cuda-cpp" } }, "name": "meta.head.extern.cuda-cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.extern.cuda-cpp" } }, "name": "meta.body.extern.cuda-cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.extern.cuda-cpp", "patterns": [ { "include": "$self" } ] }, { "include": "$self" } ] }, "function_body_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#using_namespace" }, { "include": "#type_alias" }, { "include": "#using_name" }, { "include": "#namespace_alias" }, { "include": "#typedef_class" }, { "include": "#typedef_struct" }, { "include": "#typedef_union" }, { "include": "#misc_keywords" }, { "include": "#standard_declares" }, { "include": "#class_block" }, { "include": "#struct_block" }, { "include": "#union_block" }, { "include": "#enum_block" }, { "include": "#access_control_keywords" }, { "include": "#block" }, { "include": "#static_assert" }, { "include": "#assembly" }, { "include": "#function_pointer" }, { "include": "#switch_statement" }, { "include": "#goto_statement" }, { "include": "#evaluation_context" }, { "include": "#label" } ] }, "function_call": { "begin": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<11>?)+>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<11>?)+>)(?:\\s)*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.call.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.function.call.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "11": {}, "12": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.call.cuda-cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "function_definition": { "begin": "(?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<60>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<60>?)+>)?(?![\\w<:.]))(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<60>?)+>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\()", "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "storage.type.template.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.modifier.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "storage.modifier.$12.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "15": { "name": "comment.block.cuda-cpp" }, "16": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "17": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "18": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "21": { "name": "comment.block.cuda-cpp" }, "22": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "23": { "patterns": [ { "include": "#inline_comment" } ] }, "24": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "25": { "name": "comment.block.cuda-cpp" }, "26": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "27": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "36": { "patterns": [ { "include": "#inline_comment" } ] }, "37": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "38": { "name": "comment.block.cuda-cpp" }, "39": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "40": { "patterns": [ { "include": "#inline_comment" } ] }, "41": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "42": { "name": "comment.block.cuda-cpp" }, "43": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "44": { "patterns": [ { "include": "#inline_comment" } ] }, "45": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "46": { "name": "comment.block.cuda-cpp" }, "47": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "48": { "patterns": [ { "include": "#inline_comment" } ] }, "49": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "50": { "name": "comment.block.cuda-cpp" }, "51": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "52": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "53": { "patterns": [ { "include": "#inline_comment" } ] }, "54": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "55": { "name": "comment.block.cuda-cpp" }, "56": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "57": { "patterns": [ { "include": "#scope_resolution_function_definition_inner_generated" } ] }, "58": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.cuda-cpp" }, "59": { "patterns": [ { "include": "#template_call_range" } ] }, "60": {}, "61": { "name": "entity.name.function.definition.cuda-cpp" }, "62": { "patterns": [ { "include": "#inline_comment" } ] }, "63": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "64": { "name": "comment.block.cuda-cpp" }, "65": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": {}, "name": "meta.function.definition.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.cuda-cpp" } }, "name": "meta.head.function.definition.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parameters.begin.bracket.round.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.cuda-cpp" } }, "contentName": "meta.function.definition.parameters", "patterns": [ { "include": "#ever_present_context" }, { "include": "#parameter_or_maybe_value" }, { "include": "#comma" }, { "include": "#evaluation_context" } ] }, { "match": "(?<=^|\\))(?:(?:\\s)+)?(->)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<23>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<23>?)+>)?(?![\\w<:.]))", "captures": { "1": { "name": "punctuation.definition.function.return-type.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "10": { "name": "comment.block.cuda-cpp" }, "11": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.cuda-cpp" } }, "name": "meta.body.function.definition.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "function_parameter_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#parameter" }, { "include": "#comma" } ] }, "function_pointer": { "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)?(?![\\w<:.]))(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", "end": "(\\))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "22": { "name": "comment.block.cuda-cpp" }, "23": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "24": { "patterns": [ { "include": "#inline_comment" } ] }, "25": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "26": { "name": "comment.block.cuda-cpp" }, "27": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "28": { "patterns": [ { "include": "#inline_comment" } ] }, "29": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "30": { "name": "comment.block.cuda-cpp" }, "31": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "32": { "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cuda-cpp" }, "33": { "name": "punctuation.definition.function.pointer.dereference.cuda-cpp" }, "34": { "name": "variable.other.definition.pointer.function.cuda-cpp" }, "35": { "name": "punctuation.definition.begin.bracket.square.cuda-cpp" }, "36": { "patterns": [ { "include": "#evaluation_context" } ] }, "37": { "name": "punctuation.definition.end.bracket.square.cuda-cpp" }, "38": { "name": "punctuation.section.parens.end.bracket.round.function.pointer.cuda-cpp" }, "39": { "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "patterns": [ { "include": "#function_parameter_context" } ] }, "function_pointer_parameter": { "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)?(?![\\w<:.]))(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", "end": "(\\))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "22": { "name": "comment.block.cuda-cpp" }, "23": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "24": { "patterns": [ { "include": "#inline_comment" } ] }, "25": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "26": { "name": "comment.block.cuda-cpp" }, "27": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "28": { "patterns": [ { "include": "#inline_comment" } ] }, "29": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "30": { "name": "comment.block.cuda-cpp" }, "31": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "32": { "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cuda-cpp" }, "33": { "name": "punctuation.definition.function.pointer.dereference.cuda-cpp" }, "34": { "name": "variable.parameter.pointer.function.cuda-cpp" }, "35": { "name": "punctuation.definition.begin.bracket.square.cuda-cpp" }, "36": { "patterns": [ { "include": "#evaluation_context" } ] }, "37": { "name": "punctuation.definition.end.bracket.square.cuda-cpp" }, "38": { "name": "punctuation.section.parens.end.bracket.round.function.pointer.cuda-cpp" }, "39": { "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "patterns": [ { "include": "#function_parameter_context" } ] }, "functional_specifiers_pre_parameters": { "match": "(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)", "captures": { "1": { "name": "keyword.control.goto.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.label.call.cuda-cpp" } } }, "identifier": { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*" }, "include": { "match": "^((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((#)(?:(?:\\s)+)?((?:include|include_next))\\b)(?:(?:\\s)+)?(?:(?:(?:((<)[^>]*(>?)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/)))|((\\\")[^\\\"]*((?:\\\")?)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/))))|(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;)))))|((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;))))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.control.directive.$5.cuda-cpp" }, "4": { "name": "punctuation.definition.directive.cuda-cpp" }, "6": { "name": "string.quoted.other.lt-gt.include.cuda-cpp" }, "7": { "name": "punctuation.definition.string.begin.cuda-cpp" }, "8": { "name": "punctuation.definition.string.end.cuda-cpp" }, "9": { "patterns": [ { "include": "#inline_comment" } ] }, "10": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "11": { "name": "string.quoted.double.include.cuda-cpp" }, "12": { "name": "punctuation.definition.string.begin.cuda-cpp" }, "13": { "name": "punctuation.definition.string.end.cuda-cpp" }, "14": { "patterns": [ { "include": "#inline_comment" } ] }, "15": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "16": { "name": "entity.name.other.preprocessor.macro.include.cuda-cpp" }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "21": { "patterns": [ { "include": "#inline_comment" } ] }, "22": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } }, "name": "meta.preprocessor.include.cuda-cpp" }, "inheritance_context": { "patterns": [ { "include": "#ever_present_context" }, { "match": ",", "name": "punctuation.separator.delimiter.comma.inheritance.cuda-cpp" }, { "match": "(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": {} } } ] }, "inline_builtin_storage_type": { "match": "(?:\\s)*+(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "entity.name.label.cuda-cpp" }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "6": { "name": "punctuation.separator.label.cuda-cpp" } } }, "lambdas": { "begin": "(?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))(?:(?:\\s)+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))[\\[\\];]))", "end": "(?<=[;}])", "beginCaptures": { "1": { "name": "punctuation.definition.capture.begin.lambda.cuda-cpp" }, "2": { "name": "meta.lambda.capture.cuda-cpp", "patterns": [ { "include": "#the_this_keyword" }, { "match": "((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?=\\]|\\z|$)|(,))|(\\=))", "captures": { "1": { "name": "variable.parameter.capture.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" }, "7": { "name": "keyword.operator.assignment.cuda-cpp" } } }, { "include": "#evaluation_context" } ] }, "3": {}, "4": { "name": "punctuation.definition.capture.end.lambda.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "7": { "name": "comment.block.cuda-cpp" }, "8": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": {}, "patterns": [ { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.definition.parameters.begin.lambda.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.parameters.end.lambda.cuda-cpp" } }, "name": "meta.function.definition.parameters.lambda.cuda-cpp", "patterns": [ { "include": "#function_parameter_context" } ] }, { "match": "(?)((?:.+?(?=\\{|$))?)", "captures": { "1": { "name": "punctuation.definition.lambda.return-type.cuda-cpp" }, "2": { "name": "storage.type.return-type.lambda.cuda-cpp" } } }, { "begin": "\\{", "end": "\\}", "beginCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.lambda.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.lambda.cuda-cpp" } }, "name": "meta.function.definition.body.lambda.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "language_constants": { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?line\\b", "end": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?define\\b)(?:(?:\\s)+)?((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:(?:\\s)+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:(?:\\s)+)?)*)(?:(?:\\s)+)?(\\b(?!uint_least16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_least32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_least64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_least16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_least32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_least64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_least8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_fast16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_fast32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_fast64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_least8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_fast16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_fast32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_fast64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint_fast8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|suseconds_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int_fast8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|useconds_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulonglong1[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulonglong2[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulonglong3[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulonglong4[^Pattern.new(\n match: \\/\\w\\/,\n)]|blksize_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|in_addr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|in_port_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uintptr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uintmax_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uintmax_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uintmax_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|longlong1[^Pattern.new(\n match: \\/\\w\\/,\n)]|longlong2[^Pattern.new(\n match: \\/\\w\\/,\n)]|longlong3[^Pattern.new(\n match: \\/\\w\\/,\n)]|longlong4[^Pattern.new(\n match: \\/\\w\\/,\n)]|unsigned[^Pattern.new(\n match: \\/\\w\\/,\n)]|u_quad_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|blkcnt_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|intptr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|intmax_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|intmax_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|wchar_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|u_short[^Pattern.new(\n match: \\/\\w\\/,\n)]|qaddr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|caddr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|daddr_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|fixpt_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|nlink_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|segsz_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|swblk_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|clock_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|ssize_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int16_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int32_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int64_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|ushort1[^Pattern.new(\n match: \\/\\w\\/,\n)]|ushort2[^Pattern.new(\n match: \\/\\w\\/,\n)]|ushort3[^Pattern.new(\n match: \\/\\w\\/,\n)]|ushort4[^Pattern.new(\n match: \\/\\w\\/,\n)]|double1[^Pattern.new(\n match: \\/\\w\\/,\n)]|double2[^Pattern.new(\n match: \\/\\w\\/,\n)]|double3[^Pattern.new(\n match: \\/\\w\\/,\n)]|double4[^Pattern.new(\n match: \\/\\w\\/,\n)]|signed[^Pattern.new(\n match: \\/\\w\\/,\n)]|double[^Pattern.new(\n match: \\/\\w\\/,\n)]|u_char[^Pattern.new(\n match: \\/\\w\\/,\n)]|u_long[^Pattern.new(\n match: \\/\\w\\/,\n)]|ushort[^Pattern.new(\n match: \\/\\w\\/,\n)]|quad_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|mode_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|size_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|time_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int8_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uchar1[^Pattern.new(\n match: \\/\\w\\/,\n)]|uchar2[^Pattern.new(\n match: \\/\\w\\/,\n)]|uchar3[^Pattern.new(\n match: \\/\\w\\/,\n)]|uchar4[^Pattern.new(\n match: \\/\\w\\/,\n)]|short1[^Pattern.new(\n match: \\/\\w\\/,\n)]|short2[^Pattern.new(\n match: \\/\\w\\/,\n)]|short3[^Pattern.new(\n match: \\/\\w\\/,\n)]|short4[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulong4[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulong1[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulong2[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulong3[^Pattern.new(\n match: \\/\\w\\/,\n)]|ulong4[^Pattern.new(\n match: \\/\\w\\/,\n)]|float1[^Pattern.new(\n match: \\/\\w\\/,\n)]|float2[^Pattern.new(\n match: \\/\\w\\/,\n)]|float3[^Pattern.new(\n match: \\/\\w\\/,\n)]|float4[^Pattern.new(\n match: \\/\\w\\/,\n)]|short[^Pattern.new(\n match: \\/\\w\\/,\n)]|float[^Pattern.new(\n match: \\/\\w\\/,\n)]|u_int[^Pattern.new(\n match: \\/\\w\\/,\n)]|div_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|dev_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|gid_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|ino_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|key_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|pid_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|off_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|uid_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|char1[^Pattern.new(\n match: \\/\\w\\/,\n)]|char2[^Pattern.new(\n match: \\/\\w\\/,\n)]|char3[^Pattern.new(\n match: \\/\\w\\/,\n)]|char4[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint1[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint2[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint3[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint4[^Pattern.new(\n match: \\/\\w\\/,\n)]|long1[^Pattern.new(\n match: \\/\\w\\/,\n)]|long2[^Pattern.new(\n match: \\/\\w\\/,\n)]|long3[^Pattern.new(\n match: \\/\\w\\/,\n)]|auto[^Pattern.new(\n match: \\/\\w\\/,\n)]|void[^Pattern.new(\n match: \\/\\w\\/,\n)]|char[^Pattern.new(\n match: \\/\\w\\/,\n)]|long[^Pattern.new(\n match: \\/\\w\\/,\n)]|bool[^Pattern.new(\n match: \\/\\w\\/,\n)]|uint[^Pattern.new(\n match: \\/\\w\\/,\n)]|id_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|id_t[^Pattern.new(\n match: \\/\\w\\/,\n)]|int1[^Pattern.new(\n match: \\/\\w\\/,\n)]|int2[^Pattern.new(\n match: \\/\\w\\/,\n)]|int3[^Pattern.new(\n match: \\/\\w\\/,\n)]|int4[^Pattern.new(\n match: \\/\\w\\/,\n)]|dim3[^Pattern.new(\n match: \\/\\w\\/,\n)]|int[^Pattern.new(\n match: \\/\\w\\/,\n)])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?!\\())", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "variable.language.this.cuda-cpp" }, "4": { "name": "variable.other.object.access.cuda-cpp" }, "5": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "6": { "name": "punctuation.separator.pointer-access.cuda-cpp" }, "7": { "patterns": [ { "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:(?:\\s)+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.language.this.cuda-cpp" }, "6": { "name": "variable.other.object.property.cuda-cpp" }, "7": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "8": { "name": "punctuation.separator.pointer-access.cuda-cpp" } } }, { "match": "(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.language.this.cuda-cpp" }, "6": { "name": "variable.other.object.access.cuda-cpp" }, "7": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "8": { "name": "punctuation.separator.pointer-access.cuda-cpp" } } }, { "include": "#member_access" }, { "include": "#method_access" } ] }, "8": { "name": "variable.other.property.cuda-cpp" } } }, "memory_operators": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(delete)(?:(?:\\s)+)?(\\[\\])|(delete))|(new))(?!\\w))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.operator.wordlike.cuda-cpp" }, "4": { "name": "keyword.operator.delete.array.cuda-cpp" }, "5": { "name": "keyword.operator.delete.array.bracket.cuda-cpp" }, "6": { "name": "keyword.operator.delete.cuda-cpp" }, "7": { "name": "keyword.operator.new.cuda-cpp" } } }, "method_access": { "begin": "(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:(?:\\s)+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:(?:\\s)+)?)*)(?:(?:\\s)+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.language.this.cuda-cpp" }, "6": { "name": "variable.other.object.access.cuda-cpp" }, "7": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "8": { "name": "punctuation.separator.pointer-access.cuda-cpp" }, "9": { "patterns": [ { "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:(?:\\s)+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.language.this.cuda-cpp" }, "6": { "name": "variable.other.object.property.cuda-cpp" }, "7": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "8": { "name": "punctuation.separator.pointer-access.cuda-cpp" } } }, { "match": "(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?\\*|->)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.language.this.cuda-cpp" }, "6": { "name": "variable.other.object.access.cuda-cpp" }, "7": { "name": "punctuation.separator.dot-access.cuda-cpp" }, "8": { "name": "punctuation.separator.pointer-access.cuda-cpp" } } }, { "include": "#member_access" }, { "include": "#method_access" } ] }, "10": { "name": "entity.name.function.member.cuda-cpp" }, "11": { "name": "punctuation.section.arguments.begin.bracket.round.function.member.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.function.member.cuda-cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "misc_keywords": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.other.$3.cuda-cpp" } } }, "ms_attributes": { "begin": "__declspec\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.attribute.begin.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.attribute.end.cuda-cpp" } }, "name": "support.other.attribute.cuda-cpp", "patterns": [ { "include": "#attributes_context" }, { "begin": "\\(", "end": "\\)", "beginCaptures": {}, "endCaptures": {}, "patterns": [ { "include": "#attributes_context" }, { "include": "#string_context" } ] }, { "match": "(using)(?:\\s)+((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<8>?)+>)(?:\\s)*+)?::)*\\s*+)(?:(?:\\s)+)?((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.namespace.cuda-cpp" }, "1": { "name": "keyword.other.namespace.definition.cuda-cpp storage.type.namespace.definition.cuda-cpp" } }, "endCaptures": {}, "name": "meta.block.namespace.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.namespace.cuda-cpp" } }, "name": "meta.head.namespace.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#attributes_context" }, { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<4>?)+>)(?:\\s)*+)?::)*\\s*+)(?:(?:\\s)+)?((?|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.namespace.cuda-cpp" } }, "name": "meta.body.namespace.cuda-cpp", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.namespace.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "noexcept_operator": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.noexcept.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.noexcept.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.noexcept.cuda-cpp" } }, "contentName": "meta.arguments.operator.noexcept", "patterns": [ { "include": "#evaluation_context" } ] }, "number_literal": { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<55>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<55>?)+>)?(?![\\w<:.]))(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<55>?)+>)(?:\\s)*+)?::)*+)(operator)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<55>?)+>)(?:\\s)*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:new)|(?:\\->\\*)|(?:<<=)|(?:>>=)|(?:<=>)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:\\-\\-)|(?:<<)|(?:>>)|(?:<=)|(?:>=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|(?:\\/=)|(?:%=)|(?:&=)|(?:\\^=)|(?:\\|=)|(?:\\+)|(?:\\-)|!|~|(?:\\*)|&|(?:\\*)|(?:\\/)|%|(?:\\+)|(?:\\-)|<|>|&|(?:\\^)|(?:\\|)|=|,))|((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\<|\\()", "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.operator-overload.cuda-cpp" }, "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "22": { "name": "comment.block.cuda-cpp" }, "23": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "24": { "patterns": [ { "include": "#inline_comment" } ] }, "25": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "26": { "name": "comment.block.cuda-cpp" }, "27": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "28": { "patterns": [ { "include": "#inline_comment" } ] }, "29": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "30": { "name": "comment.block.cuda-cpp" }, "31": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "32": { "patterns": [ { "include": "#inline_comment" } ] }, "33": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "34": { "name": "comment.block.cuda-cpp" }, "35": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "36": { "name": "storage.type.modifier.calling-convention.cuda-cpp" }, "37": { "patterns": [ { "include": "#inline_comment" } ] }, "38": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "39": { "name": "comment.block.cuda-cpp" }, "40": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "41": { "patterns": [ { "include": "#inline_comment" } ] }, "42": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "43": { "name": "comment.block.cuda-cpp" }, "44": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "45": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.operator.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "entity.name.operator.type.reference.cuda-cpp" } ] }, "59": { "patterns": [ { "include": "#inline_comment" } ] }, "60": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "61": { "name": "comment.block.cuda-cpp" }, "62": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "63": { "patterns": [ { "include": "#inline_comment" } ] }, "64": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "65": { "name": "comment.block.cuda-cpp" }, "66": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "67": { "patterns": [ { "include": "#inline_comment" } ] }, "68": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "69": { "name": "comment.block.cuda-cpp" }, "70": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "71": { "name": "entity.name.operator.type.array.cuda-cpp" }, "72": { "name": "entity.name.operator.custom-literal.cuda-cpp" }, "73": { "patterns": [ { "include": "#inline_comment" } ] }, "74": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "75": { "name": "comment.block.cuda-cpp" }, "76": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "77": { "name": "entity.name.operator.custom-literal.cuda-cpp" }, "78": { "patterns": [ { "include": "#inline_comment" } ] }, "79": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "80": { "name": "comment.block.cuda-cpp" }, "81": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": {}, "name": "meta.function.definition.special.operator-overload.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.operator-overload.cuda-cpp" } }, "name": "meta.head.function.definition.special.operator-overload.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#template_call_range" }, { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parameters.begin.bracket.round.special.operator-overload.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parameters.end.bracket.round.special.operator-overload.cuda-cpp" } }, "contentName": "meta.function.definition.parameters.special.operator-overload", "patterns": [ { "include": "#function_parameter_context" }, { "include": "#evaluation_context" } ] }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.function.definition.special.operator-overload.cuda-cpp" } }, "name": "meta.body.function.definition.special.operator-overload.cuda-cpp", "patterns": [ { "include": "#function_body_context" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.function.definition.special.operator-overload.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "operators": { "patterns": [ { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.sizeof.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.sizeof.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.sizeof.cuda-cpp" } }, "contentName": "meta.arguments.operator.sizeof", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.alignof.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.alignof.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.alignof.cuda-cpp" } }, "contentName": "meta.arguments.operator.alignof", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.alignas.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.alignas.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.alignas.cuda-cpp" } }, "contentName": "meta.arguments.operator.alignas", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.typeid.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.typeid.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.typeid.cuda-cpp" } }, "contentName": "meta.arguments.operator.typeid", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.noexcept.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.noexcept.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.noexcept.cuda-cpp" } }, "contentName": "meta.arguments.operator.noexcept", "patterns": [ { "include": "#evaluation_context" } ] }, { "begin": "(\\bsizeof\\.\\.\\.)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.sizeof.variadic.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.sizeof.variadic.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.sizeof.variadic.cuda-cpp" } }, "contentName": "meta.arguments.operator.sizeof.variadic", "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "--", "name": "keyword.operator.decrement.cuda-cpp" }, { "match": "\\+\\+", "name": "keyword.operator.increment.cuda-cpp" }, { "match": "%=|\\+=|-=|\\*=|(?>=|\\|=", "name": "keyword.operator.assignment.compound.bitwise.cuda-cpp" }, { "match": "<<|>>", "name": "keyword.operator.bitwise.shift.cuda-cpp" }, { "match": "!=|<=|>=|==|<|>", "name": "keyword.operator.comparison.cuda-cpp" }, { "match": "&&|!|\\|\\|", "name": "keyword.operator.logical.cuda-cpp" }, { "match": "&|\\||\\^|~", "name": "keyword.operator.cuda-cpp" }, { "include": "#assignment_operator" }, { "match": "%|\\*|\\/|-|\\+", "name": "keyword.operator.cuda-cpp" }, { "include": "#ternary_operator" } ] }, "over_qualified_types": { "patterns": [ { "match": "(struct)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.struct.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.struct.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "(enum)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.enum.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.enum.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "(union)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.union.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.union.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "(class)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.class.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.class.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } } ] }, "parameter": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\w)", "end": "(?:(?=\\))|(,))", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" } }, "name": "meta.parameter.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#function_pointer_parameter" }, { "include": "#decltype" }, { "include": "#vararg_ellipses" }, { "match": "((?:((?:(?:__constant__)|(?:__restrict__)|(?:__managed__)|(?:__shared__)|(?:volatile)|(?:register)|(?:restrict)|(?:static)|(?:extern)|(?:const)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))+)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:\\s)*+(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=,|\\)|=)", "captures": { "1": { "patterns": [ { "include": "#storage_types" } ] }, "2": { "name": "storage.modifier.specifier.parameter.cuda-cpp" }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "name": "storage.type.primitive.cuda-cpp storage.type.built-in.primitive.cuda-cpp" }, "12": { "name": "storage.type.cuda-cpp storage.type.built-in.cuda-cpp" }, "13": { "name": "support.type.posix-reserved.pthread.cuda-cpp support.type.built-in.posix-reserved.pthread.cuda-cpp" }, "14": { "name": "support.type.posix-reserved.cuda-cpp support.type.built-in.posix-reserved.cuda-cpp" }, "15": { "name": "entity.name.type.parameter.cuda-cpp" }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#storage_types" }, { "include": "#scope_resolution_parameter_inner_generated" }, { "match": "(?:(?:struct)|(?:class)|(?:union)|(?:enum))", "name": "storage.type.$0.cuda-cpp" }, { "begin": "(?<==)", "end": "(?:(?=\\))|(,))", "beginCaptures": {}, "endCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "\\=", "name": "keyword.operator.assignment.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\)|,|\\[|=|\\n)", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.parameter.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#attributes_context" }, { "begin": "\\[", "end": "\\]", "beginCaptures": { "0": { "name": "punctuation.definition.begin.bracket.square.array.type.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.end.bracket.square.array.type.cuda-cpp" } }, "name": "meta.bracket.square.array.cuda-cpp", "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*))", "captures": { "0": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "7": { "name": "comment.block.cuda-cpp" }, "8": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "parameter_class": { "match": "(class)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.class.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.class.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "parameter_enum": { "match": "(enum)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.enum.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.enum.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "parameter_or_maybe_value": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\w)", "end": "(?:(?=\\))|(,))", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "endCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" } }, "name": "meta.parameter.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#function_pointer_parameter" }, { "include": "#memory_operators" }, { "include": "#builtin_storage_type_initilizer" }, { "include": "#curly_initializer" }, { "include": "#decltype" }, { "include": "#vararg_ellipses" }, { "match": "((?:((?:(?:__constant__)|(?:__restrict__)|(?:__managed__)|(?:__shared__)|(?:volatile)|(?:register)|(?:restrict)|(?:static)|(?:extern)|(?:const)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))+)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:\\s)*+(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=,|\\)|=)", "captures": { "1": { "patterns": [ { "include": "#storage_types" } ] }, "2": { "name": "storage.modifier.specifier.parameter.cuda-cpp" }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "name": "storage.type.primitive.cuda-cpp storage.type.built-in.primitive.cuda-cpp" }, "12": { "name": "storage.type.cuda-cpp storage.type.built-in.cuda-cpp" }, "13": { "name": "support.type.posix-reserved.pthread.cuda-cpp support.type.built-in.posix-reserved.pthread.cuda-cpp" }, "14": { "name": "support.type.posix-reserved.cuda-cpp support.type.built-in.posix-reserved.cuda-cpp" }, "15": { "name": "entity.name.type.parameter.cuda-cpp" }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#storage_types" }, { "include": "#function_call" }, { "include": "#scope_resolution_parameter_inner_generated" }, { "match": "(?:(?:struct)|(?:class)|(?:union)|(?:enum))", "name": "storage.type.$0.cuda-cpp" }, { "begin": "(?<==)", "end": "(?:(?=\\))|(,))", "beginCaptures": {}, "endCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" } }, "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=(?:\\)|,|\\[|=|\\/\\/|(?:(?:\\n)|$)))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "variable.parameter.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#attributes_context" }, { "begin": "\\[", "end": "\\]", "beginCaptures": { "0": { "name": "punctuation.definition.begin.bracket.square.array.type.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.end.bracket.square.array.type.cuda-cpp" } }, "name": "meta.bracket.square.array.cuda-cpp", "patterns": [ { "include": "#evaluation_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*))", "captures": { "0": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "7": { "name": "comment.block.cuda-cpp" }, "8": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "include": "#evaluation_context" } ] }, "parameter_struct": { "match": "(struct)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.struct.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.struct.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "parameter_union": { "match": "(union)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:\\[((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\]((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=,|\\)|\\n)", "captures": { "1": { "name": "storage.type.union.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.union.parameter.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "variable.other.object.declare.cuda-cpp" }, "15": { "patterns": [ { "include": "#inline_comment" } ] }, "16": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": { "patterns": [ { "include": "#inline_comment" } ] }, "18": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "19": { "patterns": [ { "include": "#inline_comment" } ] }, "20": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "parentheses": { "begin": "\\(", "end": "\\)", "beginCaptures": { "0": { "name": "punctuation.section.parens.begin.bracket.round.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.cuda-cpp" } }, "name": "meta.parens.cuda-cpp", "patterns": [ { "include": "#over_qualified_types" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?pragma\\b", "end": "(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?pragma(?:\\s)+mark)(?:\\s)+(.*)", "captures": { "1": { "name": "keyword.control.directive.pragma.pragma-mark.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "punctuation.definition.directive.cuda-cpp" }, "5": { "name": "entity.name.tag.pragma-mark.cuda-cpp" } }, "name": "meta.preprocessor.pragma.cuda-cpp" }, "predefined_macros": { "patterns": [ { "match": "\\b(__cplusplus|__DATE__|__FILE__|__LINE__|__STDC__|__STDC_HOSTED__|__STDC_NO_COMPLEX__|__STDC_VERSION__|__STDCPP_THREADS__|__TIME__|NDEBUG|__OBJC__|__ASSEMBLER__|__ATOM__|__AVX__|__AVX2__|_CHAR_UNSIGNED|__CLR_VER|_CONTROL_FLOW_GUARD|__COUNTER__|__cplusplus_cli|__cplusplus_winrt|_CPPRTTI|_CPPUNWIND|_DEBUG|_DLL|__FUNCDNAME__|__FUNCSIG__|__FUNCTION__|_INTEGRAL_MAX_BITS|__INTELLISENSE__|_ISO_VOLATILE|_KERNEL_MODE|_M_AMD64|_M_ARM|_M_ARM_ARMV7VE|_M_ARM_FP|_M_ARM64|_M_CEE|_M_CEE_PURE|_M_CEE_SAFE|_M_FP_EXCEPT|_M_FP_FAST|_M_FP_PRECISE|_M_FP_STRICT|_M_IX86|_M_IX86_FP|_M_X64|_MANAGED|_MSC_BUILD|_MSC_EXTENSIONS|_MSC_FULL_VER|_MSC_VER|_MSVC_LANG|__MSVC_RUNTIME_CHECKS|_MT|_NATIVE_WCHAR_T_DEFINED|_OPENMP|_PREFAST|__TIMESTAMP__|_VC_NO_DEFAULTLIB|_WCHAR_T_DEFINED|_WIN32|_WIN64|_WINRT_DLL|_ATL_VER|_MFC_VER|__GFORTRAN__|__GNUC__|__GNUC_MINOR__|__GNUC_PATCHLEVEL__|__GNUG__|__STRICT_ANSI__|__BASE_FILE__|__INCLUDE_LEVEL__|__ELF__|__VERSION__|__OPTIMIZE__|__OPTIMIZE_SIZE__|__NO_INLINE__|__GNUC_STDC_INLINE__|__CHAR_UNSIGNED__|__WCHAR_UNSIGNED__|__REGISTER_PREFIX__|__REGISTER_PREFIX__|__SIZE_TYPE__|__PTRDIFF_TYPE__|__WCHAR_TYPE__|__WINT_TYPE__|__INTMAX_TYPE__|__UINTMAX_TYPE__|__SIG_ATOMIC_TYPE__|__INT8_TYPE__|__INT16_TYPE__|__INT32_TYPE__|__INT64_TYPE__|__UINT8_TYPE__|__UINT16_TYPE__|__UINT32_TYPE__|__UINT64_TYPE__|__INT_LEAST8_TYPE__|__INT_LEAST16_TYPE__|__INT_LEAST32_TYPE__|__INT_LEAST64_TYPE__|__UINT_LEAST8_TYPE__|__UINT_LEAST16_TYPE__|__UINT_LEAST32_TYPE__|__UINT_LEAST64_TYPE__|__INT_FAST8_TYPE__|__INT_FAST16_TYPE__|__INT_FAST32_TYPE__|__INT_FAST64_TYPE__|__UINT_FAST8_TYPE__|__UINT_FAST16_TYPE__|__UINT_FAST32_TYPE__|__UINT_FAST64_TYPE__|__INTPTR_TYPE__|__UINTPTR_TYPE__|__CHAR_BIT__|__SCHAR_MAX__|__WCHAR_MAX__|__SHRT_MAX__|__INT_MAX__|__LONG_MAX__|__LONG_LONG_MAX__|__WINT_MAX__|__SIZE_MAX__|__PTRDIFF_MAX__|__INTMAX_MAX__|__UINTMAX_MAX__|__SIG_ATOMIC_MAX__|__INT8_MAX__|__INT16_MAX__|__INT32_MAX__|__INT64_MAX__|__UINT8_MAX__|__UINT16_MAX__|__UINT32_MAX__|__UINT64_MAX__|__INT_LEAST8_MAX__|__INT_LEAST16_MAX__|__INT_LEAST32_MAX__|__INT_LEAST64_MAX__|__UINT_LEAST8_MAX__|__UINT_LEAST16_MAX__|__UINT_LEAST32_MAX__|__UINT_LEAST64_MAX__|__INT_FAST8_MAX__|__INT_FAST16_MAX__|__INT_FAST32_MAX__|__INT_FAST64_MAX__|__UINT_FAST8_MAX__|__UINT_FAST16_MAX__|__UINT_FAST32_MAX__|__UINT_FAST64_MAX__|__INTPTR_MAX__|__UINTPTR_MAX__|__WCHAR_MIN__|__WINT_MIN__|__SIG_ATOMIC_MIN__|__SCHAR_WIDTH__|__SHRT_WIDTH__|__INT_WIDTH__|__LONG_WIDTH__|__LONG_LONG_WIDTH__|__PTRDIFF_WIDTH__|__SIG_ATOMIC_WIDTH__|__SIZE_WIDTH__|__WCHAR_WIDTH__|__WINT_WIDTH__|__INT_LEAST8_WIDTH__|__INT_LEAST16_WIDTH__|__INT_LEAST32_WIDTH__|__INT_LEAST64_WIDTH__|__INT_FAST8_WIDTH__|__INT_FAST16_WIDTH__|__INT_FAST32_WIDTH__|__INT_FAST64_WIDTH__|__INTPTR_WIDTH__|__INTMAX_WIDTH__|__SIZEOF_INT__|__SIZEOF_LONG__|__SIZEOF_LONG_LONG__|__SIZEOF_SHORT__|__SIZEOF_POINTER__|__SIZEOF_FLOAT__|__SIZEOF_DOUBLE__|__SIZEOF_LONG_DOUBLE__|__SIZEOF_SIZE_T__|__SIZEOF_WCHAR_T__|__SIZEOF_WINT_T__|__SIZEOF_PTRDIFF_T__|__BYTE_ORDER__|__ORDER_LITTLE_ENDIAN__|__ORDER_BIG_ENDIAN__|__ORDER_PDP_ENDIAN__|__FLOAT_WORD_ORDER__|__DEPRECATED|__EXCEPTIONS|__GXX_RTTI|__USING_SJLJ_EXCEPTIONS__|__GXX_EXPERIMENTAL_CXX0X__|__GXX_WEAK__|__NEXT_RUNTIME__|__LP64__|_LP64|__SSP__|__SSP_ALL__|__SSP_STRONG__|__SSP_EXPLICIT__|__SANITIZE_ADDRESS__|__SANITIZE_THREAD__|__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1|__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2|__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4|__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8|__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16|__HAVE_SPECULATION_SAFE_VALUE|__GCC_HAVE_DWARF2_CFI_ASM|__FP_FAST_FMA|__FP_FAST_FMAF|__FP_FAST_FMAL|__FP_FAST_FMAF16|__FP_FAST_FMAF32|__FP_FAST_FMAF64|__FP_FAST_FMAF128|__FP_FAST_FMAF32X|__FP_FAST_FMAF64X|__FP_FAST_FMAF128X|__GCC_IEC_559|__GCC_IEC_559_COMPLEX|__NO_MATH_ERRNO__|__has_builtin|__has_feature|__has_extension|__has_cpp_attribute|__has_c_attribute|__has_attribute|__has_declspec_attribute|__is_identifier|__has_include|__has_include_next|__has_warning|__BASE_FILE__|__FILE_NAME__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__fp16|_Float16)\\b", "captures": { "1": { "name": "entity.name.other.preprocessor.macro.predefined.$1.cuda-cpp" } } }, { "match": "\\b__([A-Z_]+)__\\b", "name": "entity.name.other.preprocessor.macro.predefined.probably.$1.cuda-cpp" } ] }, "preprocessor_conditional_context": { "patterns": [ { "include": "#preprocessor_conditional_defined" }, { "include": "#comments" }, { "include": "#language_constants" }, { "include": "#string_context" }, { "include": "#d9bc4796b0b_preprocessor_number_literal" }, { "include": "#operators" }, { "include": "#predefined_macros" }, { "include": "#macro_name" }, { "include": "#line_continuation_character" } ] }, "preprocessor_conditional_defined": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?((?:(?:ifndef|ifdef)|if))", "end": "^(?!\\s*+#\\s*(?:else|endif))", "beginCaptures": { "0": { "name": "keyword.control.directive.conditional.$6.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "punctuation.definition.directive.cuda-cpp" }, "6": {} }, "endCaptures": {}, "patterns": [ { "begin": "\\G(?<=ifndef|ifdef|if)", "end": "(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "punctuation.definition.directive.cuda-cpp" } }, "name": "keyword.control.directive.$4.cuda-cpp" }, "preprocessor_context": { "patterns": [ { "include": "#pragma_mark" }, { "include": "#pragma" }, { "include": "#include" }, { "include": "#line" }, { "include": "#diagnostic" }, { "include": "#undef" }, { "include": "#preprocessor_conditional_range" }, { "include": "#single_line_macro" }, { "include": "#macro" }, { "include": "#preprocessor_conditional_standalone" }, { "include": "#macro_argument" } ] }, "qualified_type": { "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<11>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<11>?)+>)?(?![\\w<:.])", "captures": { "0": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "1": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "6": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } }, "name": "meta.qualified_type.cuda-cpp" }, "qualifiers_and_specifiers_post_parameters": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?:((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "storage.modifier.specifier.functional.post-parameters.$3.cuda-cpp" }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "scope_resolution": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_call": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.call.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_call_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.call.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.call.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.call.cuda-cpp" } } }, "scope_resolution_function_definition": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_definition_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_definition_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_definition_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.definition.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.cuda-cpp" } } }, "scope_resolution_function_definition_operator_overload": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_function_definition_operator_overload_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_function_definition_operator_overload_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_function_definition_operator_overload_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.function.definition.operator-overload.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cuda-cpp" } } }, "scope_resolution_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" } } }, "scope_resolution_namespace_alias": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_alias_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.alias.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_alias_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_alias_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.alias.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.alias.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.alias.cuda-cpp" } } }, "scope_resolution_namespace_block": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_block_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.block.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_block_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_block_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.block.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.block.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.block.cuda-cpp" } } }, "scope_resolution_namespace_using": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_namespace_using_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.using.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_namespace_using_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_namespace_using_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.using.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.namespace.using.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.namespace.using.cuda-cpp" } } }, "scope_resolution_parameter": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_parameter_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.parameter.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_parameter_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_parameter_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.parameter.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.parameter.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.parameter.cuda-cpp" } } }, "scope_resolution_template_call": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_template_call_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.call.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_template_call_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_template_call_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.call.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.template.call.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.call.cuda-cpp" } } }, "scope_resolution_template_definition": { "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<3>?)+>)(?:\\s)*+)?::)*\\s*+", "captures": { "0": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" } ] }, "1": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.definition.cuda-cpp" }, "2": { "patterns": [ { "include": "#template_call_range" } ] } } }, "scope_resolution_template_definition_inner_generated": { "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<7>?)+>)(?:\\s)*+)?(::)", "captures": { "1": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" } ] }, "2": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.definition.cuda-cpp" }, "3": { "patterns": [ { "include": "#template_call_range" } ] }, "4": {}, "5": { "name": "entity.name.scope-resolution.template.definition.cuda-cpp" }, "6": { "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_range" } ] }, "7": {}, "8": { "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.template.definition.cuda-cpp" } } }, "semicolon": { "match": ";", "name": "punctuation.terminator.statement.cuda-cpp" }, "simple_type": { "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<12>?)+>)?(?![\\w<:.]))(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?", "captures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": {}, "13": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "14": { "patterns": [ { "include": "#inline_comment" } ] }, "15": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "single_line_macro": { "match": "^((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))#define.*(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "sizeof_operator": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.sizeof.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.sizeof.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.sizeof.cuda-cpp" } }, "contentName": "meta.arguments.operator.sizeof", "patterns": [ { "include": "#evaluation_context" } ] }, "sizeof_variadic_operator": { "begin": "(\\bsizeof\\.\\.\\.)((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.sizeof.variadic.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.sizeof.variadic.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.sizeof.variadic.cuda-cpp" } }, "contentName": "meta.arguments.operator.sizeof.variadic", "patterns": [ { "include": "#evaluation_context" } ] }, "square_brackets": { "name": "meta.bracket.square.access", "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))?(\\[)(?!\\])", "beginCaptures": { "1": { "name": "variable.other.object" }, "2": { "name": "punctuation.definition.begin.bracket.square" } }, "end": "\\]", "endCaptures": { "0": { "name": "punctuation.definition.end.bracket.square" } }, "patterns": [ { "include": "#evaluation_context" } ] }, "standard_declares": { "patterns": [ { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.struct.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.struct.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.union.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.union.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.enum.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.enum.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.class.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.class.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } } ] }, "static_assert": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "keyword.other.static_assert.cuda-cpp" }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "name": "punctuation.section.arguments.begin.bracket.round.static_assert.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.static_assert.cuda-cpp" } }, "patterns": [ { "begin": "(,)(?:(?:\\s)+)?(?=(?:L|u8|u|U(?:(?:\\s)+)?\\\")?)", "end": "(?=\\))", "beginCaptures": { "1": { "name": "punctuation.separator.delimiter.comma.cuda-cpp" } }, "endCaptures": {}, "name": "meta.static_assert.message.cuda-cpp", "patterns": [ { "include": "#string_context" } ] }, { "include": "#evaluation_context" } ] }, "std_space": { "match": "(?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))", "captures": { "0": { "patterns": [ { "include": "#inline_comment" } ] }, "1": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "storage_specifiers": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "storage.modifier.specifier.$3.cuda-cpp" } } }, "storage_types": { "patterns": [ { "include": "#storage_specifiers" }, { "include": "#inline_builtin_storage_type" }, { "include": "#decltype" }, { "include": "#typename" } ] }, "string_context": { "patterns": [ { "begin": "((?:u|u8|U|L)?)\"", "end": "\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cuda-cpp" }, "1": { "name": "meta.encoding.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.definition.string.end.cuda-cpp" } }, "name": "string.quoted.double.cuda-cpp", "patterns": [ { "match": "(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})", "name": "constant.character.escape.cuda-cpp" }, { "match": "\\\\['\"?\\\\abfnrtv]", "name": "constant.character.escape.cuda-cpp" }, { "match": "\\\\[0-7]{1,3}", "name": "constant.character.escape.cuda-cpp" }, { "match": "(?:(\\\\x0*[0-9a-fA-F]{2}(?![0-9a-fA-F]))|((?:\\\\x[0-9a-fA-F]*|\\\\x)))", "captures": { "1": { "name": "constant.character.escape.cuda-cpp" }, "2": { "name": "invalid.illegal.unknown-escape.cuda-cpp" } } }, { "include": "#string_escapes_context_c" } ] }, { "begin": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.struct.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.struct.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.struct.cuda-cpp" } }, "name": "meta.head.struct.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.struct.cuda-cpp" } }, "name": "meta.body.struct.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.struct.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "struct_declare": { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.struct.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.struct.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "switch_conditional_parentheses": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "punctuation.section.parens.begin.bracket.round.conditional.switch.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.parens.end.bracket.round.conditional.switch.cuda-cpp" } }, "name": "meta.conditional.switch.cuda-cpp", "patterns": [ { "include": "#evaluation_context" }, { "include": "#c_conditional_context" } ] }, "switch_statement": { "begin": "((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.switch.cuda-cpp" }, "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "5": { "name": "keyword.control.switch.cuda-cpp" } }, "endCaptures": {}, "name": "meta.block.switch.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.switch.cuda-cpp" } }, "name": "meta.head.switch.cuda-cpp", "patterns": [ { "include": "#switch_conditional_parentheses" }, { "include": "$self" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.switch.cuda-cpp" } }, "name": "meta.body.switch.cuda-cpp", "patterns": [ { "include": "#default_statement" }, { "include": "#case_statement" }, { "include": "$self" }, { "include": "#block_innards" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.switch.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "template_argument_defaulted": { "match": "(?<=<|,)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s)+)*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?([=])", "captures": { "1": { "name": "storage.type.template.cuda-cpp" }, "2": { "name": "entity.name.type.template.cuda-cpp" }, "3": { "name": "keyword.operator.assignment.cuda-cpp" } } }, "template_call_context": { "patterns": [ { "include": "#ever_present_context" }, { "include": "#template_call_range" }, { "include": "#storage_types" }, { "include": "#language_constants" }, { "include": "#scope_resolution_template_call_inner_generated" }, { "include": "#operators" }, { "include": "#number_literal" }, { "include": "#string_context" }, { "include": "#comma_in_template_argument" }, { "include": "#qualified_type" } ] }, "template_call_innards": { "match": "((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<1>?)+>)(?:\\s)*+", "captures": { "0": { "patterns": [ { "include": "#template_call_range" } ] } }, "name": "meta.template.call.cuda-cpp" }, "template_call_range": { "begin": "<", "end": ">", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, "template_definition": { "begin": "(?", "beginCaptures": { "1": { "name": "storage.type.template.cuda-cpp" }, "2": { "name": "punctuation.section.angle-brackets.start.template.definition.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.definition.cuda-cpp" } }, "name": "meta.template.definition.cuda-cpp", "patterns": [ { "begin": "(?<=\\w)(?:(?:\\s)+)?<", "end": ">", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "patterns": [ { "include": "#template_call_context" } ] }, { "include": "#template_definition_context" } ] }, "template_definition_argument": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s)+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?(\\.\\.\\.)(?:(?:\\s)+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))(?:(?:\\s)+)?(?:(,)|(?=>|$))", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "storage.type.template.argument.$3.cuda-cpp" }, "4": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "storage.type.template.argument.$0.cuda-cpp" } ] }, "5": { "name": "entity.name.type.template.cuda-cpp" }, "6": { "name": "storage.type.template.cuda-cpp" }, "7": { "name": "punctuation.vararg-ellipses.template.definition.cuda-cpp" }, "8": { "name": "entity.name.type.template.cuda-cpp" }, "9": { "name": "punctuation.separator.delimiter.comma.template.argument.cuda-cpp" } } }, "template_definition_context": { "patterns": [ { "include": "#scope_resolution_template_definition_inner_generated" }, { "include": "#template_definition_argument" }, { "include": "#template_argument_defaulted" }, { "include": "#template_call_innards" }, { "include": "#evaluation_context" } ] }, "template_isolated_definition": { "match": "(?(?:(?:\\s)+)?$)", "captures": { "1": { "name": "storage.type.template.cuda-cpp" }, "2": { "name": "punctuation.section.angle-brackets.start.template.definition.cuda-cpp" }, "3": { "name": "meta.template.definition.cuda-cpp", "patterns": [ { "include": "#template_definition_context" } ] }, "4": { "name": "punctuation.section.angle-brackets.end.template.definition.cuda-cpp" } } }, "ternary_operator": { "begin": "\\?", "end": ":", "beginCaptures": { "0": { "name": "keyword.operator.ternary.cuda-cpp" } }, "endCaptures": { "0": { "name": "keyword.operator.ternary.cuda-cpp" } }, "patterns": [ { "include": "#ever_present_context" }, { "include": "#string_context" }, { "include": "#number_literal" }, { "include": "#method_access" }, { "include": "#member_access" }, { "include": "#predefined_macros" }, { "include": "#operators" }, { "include": "#memory_operators" }, { "include": "#wordlike_operators" }, { "include": "#type_casting_operators" }, { "include": "#control_flow_keywords" }, { "include": "#exception_keywords" }, { "include": "#the_this_keyword" }, { "include": "#language_constants" }, { "include": "#builtin_storage_type_initilizer" }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "#functional_specifiers_pre_parameters" }, { "include": "#storage_types" }, { "include": "#lambdas" }, { "include": "#attributes_context" }, { "include": "#parentheses" }, { "include": "#function_call" }, { "include": "#scope_resolution_inner_generated" }, { "include": "#square_brackets" }, { "include": "#semicolon" }, { "include": "#comma" } ], "applyEndPatternLast": 1 }, "the_this_keyword": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "variable.language.this.cuda-cpp" } } }, "type_alias": { "match": "(using)(?:(?:\\s)+)?(?!namespace)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<29>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<29>?)+>)?(?![\\w<:.]))(?:(?:\\s)+)?(\\=)(?:(?:\\s)+)?((?:typename)?)(?:(?:\\s)+)?((?:(?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<29>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<29>?)+>)?(?![\\w<:.]))|(.*(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)?(?:(?:\\s)+)?(?:(;)|\\n)", "captures": { "1": { "name": "keyword.other.using.directive.cuda-cpp" }, "2": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "3": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "14": { "name": "keyword.operator.assignment.cuda-cpp" }, "15": { "name": "keyword.other.typename.cuda-cpp" }, "16": { "patterns": [ { "include": "#storage_specifiers" } ] }, "17": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "18": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "19": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "22": { "patterns": [ { "include": "#inline_comment" } ] }, "23": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "24": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "30": { "name": "meta.declaration.type.alias.value.unknown.cuda-cpp", "patterns": [ { "include": "#evaluation_context" } ] }, "31": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "32": { "patterns": [ { "include": "#inline_comment" } ] }, "33": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "34": { "patterns": [ { "include": "#inline_comment" } ] }, "35": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "36": { "patterns": [ { "include": "#inline_comment" } ] }, "37": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "38": { "name": "punctuation.definition.begin.bracket.square.cuda-cpp" }, "39": { "patterns": [ { "include": "#evaluation_context" } ] }, "40": { "name": "punctuation.definition.end.bracket.square.cuda-cpp" }, "41": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.declaration.type.alias.cuda-cpp" }, "type_casting_operators": { "match": "((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "3": { "name": "keyword.operator.wordlike.cuda-cpp keyword.operator.cast.$3.cuda-cpp" } } }, "typedef_class": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.class.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.class.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.class.cuda-cpp" } }, "name": "meta.head.class.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.class.cuda-cpp" } }, "name": "meta.body.class.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.class.cuda-cpp", "patterns": [ { "match": "(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "12": { "name": "comment.block.cuda-cpp" }, "13": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "14": { "name": "entity.name.type.alias.cuda-cpp" } } }, { "match": "," } ] } ] } ] }, "typedef_function_pointer": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)(?:\\s)*+)?::)*+)?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<18>?)+>)?(?![\\w<:.]))(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", "end": "(\\))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "3": { "patterns": [ { "include": "#inline_comment" } ] }, "4": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "5": { "name": "comment.block.cuda-cpp" }, "6": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "20": { "patterns": [ { "include": "#inline_comment" } ] }, "21": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "22": { "name": "comment.block.cuda-cpp" }, "23": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "24": { "patterns": [ { "include": "#inline_comment" } ] }, "25": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "26": { "name": "comment.block.cuda-cpp" }, "27": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "28": { "patterns": [ { "include": "#inline_comment" } ] }, "29": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "30": { "name": "comment.block.cuda-cpp" }, "31": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "32": { "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cuda-cpp" }, "33": { "name": "punctuation.definition.function.pointer.dereference.cuda-cpp" }, "34": { "name": "entity.name.type.alias.cuda-cpp entity.name.type.pointer.function.cuda-cpp" }, "35": { "name": "punctuation.definition.begin.bracket.square.cuda-cpp" }, "36": { "patterns": [ { "include": "#evaluation_context" } ] }, "37": { "name": "punctuation.definition.end.bracket.square.cuda-cpp" }, "38": { "name": "punctuation.section.parens.end.bracket.round.function.pointer.cuda-cpp" }, "39": { "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "patterns": [ { "include": "#function_parameter_context" } ] } ] }, "typedef_struct": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.struct.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.struct.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.struct.cuda-cpp" } }, "name": "meta.head.struct.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.struct.cuda-cpp" } }, "name": "meta.body.struct.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.struct.cuda-cpp", "patterns": [ { "match": "(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "12": { "name": "comment.block.cuda-cpp" }, "13": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "14": { "name": "entity.name.type.alias.cuda-cpp" } } }, { "match": "," } ] } ] } ] }, "typedef_union": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.union.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.union.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.union.cuda-cpp" } }, "name": "meta.head.union.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.union.cuda-cpp" } }, "name": "meta.body.union.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.union.cuda-cpp", "patterns": [ { "match": "(((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "8": { "name": "comment.block.cuda-cpp" }, "9": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "12": { "name": "comment.block.cuda-cpp" }, "13": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "14": { "name": "entity.name.type.alias.cuda-cpp" } } }, { "match": "," } ] } ] } ] }, "typeid_operator": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\()", "end": "\\)", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cuda-cpp keyword.operator.typeid.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "punctuation.section.arguments.begin.bracket.round.operator.typeid.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.arguments.end.bracket.round.operator.typeid.cuda-cpp" } }, "contentName": "meta.arguments.operator.typeid", "patterns": [ { "include": "#evaluation_context" } ] }, "typename": { "match": "(((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|__forceinline__|atomic_noexcept|__has_include|atomic_cancel|atomic_commit|dynamic_cast|__constant__|__restrict__|__noinline__|thread_local|synchronized|static_cast|__managed__|const_cast|__shared__|__global__|__device__|co_return|constexpr|constexpr|constexpr|consteval|protected|namespace|co_return|noexcept|noexcept|continue|co_await|co_yield|volatile|register|restrict|explicit|__host__|volatile|noexcept|template|operator|decltype|typename|requires|co_await|co_yield|reflexpr|alignof|alignas|default|mutable|virtual|mutable|private|include|warning|_Pragma|defined|typedef|__asm__|concept|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|compl|bitor|throw|or_eq|while|catch|break|class|union|const|const|endif|ifdef|undef|error|using|else|goto|case|enum|elif|else|line|this|not|new|xor|and|for|try|asm|or|do|if|if)\\b)(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<17>?)+>)(?:\\s)*+)?::)*+)?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:__forceinline__)|(?:atomic_noexcept)|(?:__has_include)|(?:atomic_cancel)|(?:atomic_commit)|(?:dynamic_cast)|(?:__constant__)|(?:__restrict__)|(?:__noinline__)|(?:thread_local)|(?:synchronized)|(?:static_cast)|(?:__managed__)|(?:const_cast)|(?:__shared__)|(?:__global__)|(?:__device__)|(?:co_return)|(?:constexpr)|(?:constexpr)|(?:constexpr)|(?:consteval)|(?:protected)|(?:threadIdx)|(?:namespace)|(?:co_return)|(?:noexcept)|(?:noexcept)|(?:continue)|(?:co_await)|(?:co_yield)|(?:volatile)|(?:register)|(?:restrict)|(?:explicit)|(?:__host__)|(?:override)|(?:volatile)|(?:noexcept)|(?:blockIdx)|(?:blockDim)|(?:warpSize)|(?:template)|(?:operator)|(?:decltype)|(?:typename)|(?:requires)|(?:co_await)|(?:co_yield)|(?:reflexpr)|(?:alignof)|(?:alignas)|(?:default)|(?:nullptr)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:gridDim)|(?:typedef)|(?:__asm__)|(?:concept)|(?:sizeof)|(?:delete)|(?:not_eq)|(?:bitand)|(?:and_eq)|(?:xor_eq)|(?:typeid)|(?:switch)|(?:return)|(?:static)|(?:extern)|(?:inline)|(?:friend)|(?:public)|(?:ifndef)|(?:define)|(?:pragma)|(?:export)|(?:import)|(?:module)|(?:compl)|(?:bitor)|(?:throw)|(?:or_eq)|(?:while)|(?:catch)|(?:break)|(?:false)|(?:const)|(?:final)|(?:const)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:using)|(?:audit)|(?:axiom)|(?:else)|(?:goto)|(?:case)|(?:NULL)|(?:true)|(?:elif)|(?:else)|(?:line)|(?:this)|(?:not)|(?:new)|(?:xor)|(?:and)|(?:for)|(?:try)|(?:asm)|(?:or)|(?:do)|(?:if)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<17>?)+>)?(?![\\w<:.]))", "captures": { "1": { "name": "storage.modifier.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "patterns": [ { "include": "#inline_comment" } ] }, "5": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "6": { "name": "meta.qualified_type.cuda-cpp", "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.cuda-cpp" }, { "match": "(?", "beginCaptures": { "0": { "name": "punctuation.section.angle-brackets.begin.template.call.cuda-cpp" } }, "endCaptures": { "0": { "name": "punctuation.section.angle-brackets.end.template.call.cuda-cpp" } }, "name": "meta.template.call.cuda-cpp", "patterns": [ { "include": "#template_call_context" } ] }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cuda-cpp" } ] }, "7": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "patterns": [ { "match": "::", "name": "punctuation.separator.namespace.access.cuda-cpp punctuation.separator.scope-resolution.type.cuda-cpp" }, { "match": "(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "17": {} } }, "undef": { "match": "(^((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?undef\\b)((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "punctuation.definition.directive.cuda-cpp" }, "5": { "patterns": [ { "include": "#inline_comment" } ] }, "6": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "7": { "name": "entity.name.function.preprocessor.cuda-cpp" } }, "name": "meta.preprocessor.undef.cuda-cpp" }, "union_block": { "begin": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:(?={)|(?:((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?((?:(?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*+)?(?:((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(:(?!:)))?)", "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cuda-cpp" }, "1": { "name": "storage.type.$1.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#attributes_context" }, { "include": "#number_literal" } ] }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "11": { "patterns": [ { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))", "captures": { "1": { "name": "storage.type.modifier.final.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?:((?(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))?(?=:|{|$)", "captures": { "1": { "name": "entity.name.type.union.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "4": { "name": "comment.block.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "6": { "name": "storage.type.modifier.final.cuda-cpp" }, "7": { "patterns": [ { "include": "#inline_comment" } ] }, "8": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "9": { "name": "comment.block.cuda-cpp" }, "10": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } }, { "match": "DLLEXPORT", "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cuda-cpp" }, { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.other.preprocessor.macro.predefined.probably.$0.cuda-cpp" } ] }, "12": { "patterns": [ { "include": "#inline_comment" } ] }, "13": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "14": { "name": "comment.block.cuda-cpp" }, "15": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "16": { "patterns": [ { "include": "#inline_comment" } ] }, "17": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "18": { "name": "comment.block.cuda-cpp" }, "19": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] }, "20": { "name": "punctuation.separator.colon.inheritance.cuda-cpp" } }, "endCaptures": { "1": { "name": "punctuation.terminator.statement.cuda-cpp" }, "2": { "name": "punctuation.terminator.statement.cuda-cpp" } }, "name": "meta.block.union.cuda-cpp", "patterns": [ { "begin": "\\G ?", "end": "(?:\\{|<%|\\?\\?<|(?=;))", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.begin.bracket.curly.union.cuda-cpp" } }, "name": "meta.head.union.cuda-cpp", "patterns": [ { "include": "#ever_present_context" }, { "include": "#inheritance_context" }, { "include": "#template_call_range" } ] }, { "begin": "(?<=\\{|<%|\\?\\?<)", "end": "\\}|%>|\\?\\?>", "beginCaptures": {}, "endCaptures": { "0": { "name": "punctuation.section.block.end.bracket.curly.union.cuda-cpp" } }, "name": "meta.body.union.cuda-cpp", "patterns": [ { "include": "#function_pointer" }, { "include": "#static_assert" }, { "include": "#constructor_inline" }, { "include": "#destructor_inline" }, { "include": "$self" } ] }, { "begin": "(?<=\\}|%>|\\?\\?>)[\\s]*", "end": "[\\s]*(?=;)", "beginCaptures": {}, "endCaptures": {}, "name": "meta.tail.union.cuda-cpp", "patterns": [ { "include": "$self" } ] } ] }, "union_declare": { "match": "((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:((?:(?>(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?(?:\\s)+)|\\/\\*(?:[^\\*]|(?:\\*)++[^\\/])*+(?:\\*)++\\/)+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))(?=\\S)(?![:{a-zA-Z])", "captures": { "1": { "name": "storage.type.union.declare.cuda-cpp" }, "2": { "patterns": [ { "include": "#inline_comment" } ] }, "3": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "4": { "name": "entity.name.type.union.cuda-cpp" }, "5": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cuda-cpp" }, { "match": "(?:\\&((?:(?:(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))+)|(?:\\b)|(?=\\W)|(?<=\\W)|(?:\\A)|(?:\\Z)))){2,}\\&", "captures": { "1": { "patterns": [ { "include": "#inline_comment" } ] }, "2": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "3": { "name": "comment.block.cuda-cpp" }, "4": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } }, "name": "invalid.illegal.reference-type.cuda-cpp" }, { "match": "\\&", "name": "storage.modifier.reference.cuda-cpp" } ] }, "6": { "patterns": [ { "include": "#inline_comment" } ] }, "7": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "8": { "patterns": [ { "include": "#inline_comment" } ] }, "9": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "10": { "patterns": [ { "include": "#inline_comment" } ] }, "11": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] }, "12": { "name": "variable.other.object.declare.cuda-cpp" }, "13": { "patterns": [ { "include": "#inline_comment" } ] }, "14": { "patterns": [ { "match": "(?:(?>(?:\\s)+)|(\\/\\*)((?:[^\\*]|(?:\\*)++[^\\/])*+((?:\\*)++\\/)))", "captures": { "1": { "name": "comment.block.cuda-cpp punctuation.definition.comment.begin.cuda-cpp" }, "2": { "name": "comment.block.cuda-cpp" }, "3": { "patterns": [ { "match": "\\*\\/", "name": "comment.block.cuda-cpp punctuation.definition.comment.end.cuda-cpp" }, { "match": "\\*", "name": "comment.block.cuda-cpp" } ] } } } ] } } }, "using_name": { "match": "(using)(?:\\s)+(?!namespace\\b)", "captures": { "1": { "name": "keyword.other.using.directive.cuda-cpp" } } }, "using_namespace": { "begin": "(?]*+|\"(?:[^\"]*|\\\\\")\")|'(?:[^']*|\\\\')')\\g<6>?)+>)(?:\\s)*+)?::)*\\s*+)?((?" ], [ "'", "'" ], [ "\"", "\"" ] ], "folding": { "markers": { "start": "^\\s*#region\\b", "end": "^\\s*#endregion\\b" } }, "onEnterRules": [ // Add // when pressing enter from inside line comment // We do not want to match /// (a documentation comment) { "beforeText": { "pattern": "[^\/]\/\/[^\/].*" }, "afterText": { "pattern": "^(?!\\s*$).+" }, "action": { "indent": "none", "appendText": "// " } }, // Add /// when pressing enter from anywhere inside a documentation comment. // Documentation comments are not valid after non-whitespace. { "beforeText": { "pattern": "^\\s*\/\/\/" }, "action": { "indent": "none", "appendText": "/// " } }, ] } ================================================ FILE: extensions/csharp/package.json ================================================ { "name": "csharp", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "0.10.x" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin dotnet/csharp-tmLanguage grammars/csharp.tmLanguage ./syntaxes/csharp.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "configurationDefaults": { "[csharp]": { "editor.maxTokenizationLineLength": 2500 } }, "languages": [ { "id": "csharp", "extensions": [ ".cs", ".csx", ".cake" ], "aliases": [ "C#", "csharp" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "csharp", "scopeName": "source.cs", "path": "./syntaxes/csharp.tmLanguage.json", "tokenTypes": { "meta.interpolation": "other" } } ], "snippets": [ { "language": "csharp", "path": "./snippets/csharp.code-snippets" } ] }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/csharp/package.nls.json ================================================ { "displayName": "C# Language Basics", "description": "Provides snippets, syntax highlighting, bracket matching and folding in C# files." } ================================================ FILE: extensions/csharp/snippets/csharp.code-snippets ================================================ { "Region Start": { "prefix": "#region", "body": [ "#region $0" ], "description": "Folding Region Start" }, "Region End": { "prefix": "#endregion", "body": [ "#endregion" ], "description": "Folding Region End" } } ================================================ FILE: extensions/csharp/syntaxes/csharp.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/dotnet/csharp-tmLanguage/blob/master/grammars/csharp.tmLanguage", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/dotnet/csharp-tmLanguage/commit/1381bedfb087c18aca67af8278050d11bc9d9349", "name": "C#", "scopeName": "source.cs", "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#directives" }, { "include": "#declarations" }, { "include": "#script-top-level" } ], "repository": { "directives": { "patterns": [ { "include": "#extern-alias-directive" }, { "include": "#using-directive" }, { "include": "#attribute-section" }, { "include": "#punctuation-semicolon" } ] }, "declarations": { "patterns": [ { "include": "#namespace-declaration" }, { "include": "#type-declarations" }, { "include": "#punctuation-semicolon" } ] }, "script-top-level": { "patterns": [ { "include": "#statement" }, { "include": "#method-declaration" }, { "include": "#punctuation-semicolon" } ] }, "type-declarations": { "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#storage-modifier" }, { "include": "#class-declaration" }, { "include": "#delegate-declaration" }, { "include": "#enum-declaration" }, { "include": "#interface-declaration" }, { "include": "#struct-declaration" }, { "include": "#record-declaration" }, { "include": "#attribute-section" }, { "include": "#punctuation-semicolon" } ] }, "class-or-struct-members": { "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#storage-modifier" }, { "include": "#type-declarations" }, { "include": "#property-declaration" }, { "include": "#field-declaration" }, { "include": "#event-declaration" }, { "include": "#indexer-declaration" }, { "include": "#variable-initializer" }, { "include": "#constructor-declaration" }, { "include": "#destructor-declaration" }, { "include": "#operator-declaration" }, { "include": "#conversion-operator-declaration" }, { "include": "#method-declaration" }, { "include": "#attribute-section" }, { "include": "#punctuation-semicolon" } ] }, "interface-members": { "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#storage-modifier" }, { "include": "#property-declaration" }, { "include": "#event-declaration" }, { "include": "#indexer-declaration" }, { "include": "#method-declaration" }, { "include": "#operator-declaration" }, { "include": "#attribute-section" }, { "include": "#punctuation-semicolon" } ] }, "statement": { "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#while-statement" }, { "include": "#do-statement" }, { "include": "#for-statement" }, { "include": "#foreach-statement" }, { "include": "#if-statement" }, { "include": "#else-part" }, { "include": "#goto-statement" }, { "include": "#return-statement" }, { "include": "#break-or-continue-statement" }, { "include": "#throw-statement" }, { "include": "#yield-statement" }, { "include": "#await-statement" }, { "include": "#try-statement" }, { "include": "#expression-operator-expression" }, { "include": "#context-control-statement" }, { "include": "#context-control-paren-statement" }, { "include": "#labeled-statement" }, { "include": "#object-creation-expression" }, { "include": "#array-creation-expression" }, { "include": "#anonymous-object-creation-expression" }, { "include": "#local-declaration" }, { "include": "#block" }, { "include": "#expression" }, { "include": "#punctuation-semicolon" } ] }, "expression": { "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#expression-operator-expression" }, { "include": "#type-operator-expression" }, { "include": "#default-literal-expression" }, { "include": "#throw-expression" }, { "include": "#raw-interpolated-string" }, { "include": "#interpolated-string" }, { "include": "#verbatim-interpolated-string" }, { "include": "#type-builtin" }, { "include": "#language-variable" }, { "include": "#switch-statement-or-expression" }, { "include": "#with-expression" }, { "include": "#conditional-operator" }, { "include": "#assignment-expression" }, { "include": "#expression-operators" }, { "include": "#await-expression" }, { "include": "#query-expression" }, { "include": "#as-expression" }, { "include": "#is-expression" }, { "include": "#anonymous-method-expression" }, { "include": "#object-creation-expression" }, { "include": "#array-creation-expression" }, { "include": "#anonymous-object-creation-expression" }, { "include": "#invocation-expression" }, { "include": "#member-access-expression" }, { "include": "#element-access-expression" }, { "include": "#cast-expression" }, { "include": "#literal" }, { "include": "#parenthesized-expression" }, { "include": "#tuple-deconstruction-assignment" }, { "include": "#initializer-expression" }, { "include": "#identifier" } ] }, "extern-alias-directive": { "begin": "\\b(extern)\\s+(alias)\\b", "beginCaptures": { "1": { "name": "keyword.other.directive.extern.cs" }, "2": { "name": "keyword.other.directive.alias.cs" } }, "end": "(?=;)", "patterns": [ { "match": "\\@?[_[:alpha:]][_[:alnum:]]*", "name": "variable.other.alias.cs" } ] }, "using-directive": { "patterns": [ { "begin": "\\b(?:(global)\\s+)?(using)\\s+(static)\\b\\s*(?:(unsafe)\\b\\s*)?", "beginCaptures": { "1": { "name": "keyword.other.directive.global.cs" }, "2": { "name": "keyword.other.directive.using.cs" }, "3": { "name": "keyword.other.directive.static.cs" }, "4": { "name": "storage.modifier.unsafe.cs" } }, "end": "(?=;)", "patterns": [ { "include": "#type" } ] }, { "begin": "\\b(?:(global)\\s+)?(using)\\b\\s*(?:(unsafe)\\b\\s*)?(@?[_[:alpha:]][_[:alnum:]]*)\\s*(=)", "beginCaptures": { "1": { "name": "keyword.other.directive.global.cs" }, "2": { "name": "keyword.other.directive.using.cs" }, "3": { "name": "storage.modifier.unsafe.cs" }, "4": { "name": "entity.name.type.alias.cs" }, "5": { "name": "keyword.operator.assignment.cs" } }, "end": "(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#type" } ] }, { "begin": "\\b(?:(global)\\s+)?(using)\\b\\s*+(?!\\(|var\\b)", "beginCaptures": { "1": { "name": "keyword.other.directive.global.cs" }, "2": { "name": "keyword.other.directive.using.cs" } }, "end": "(?=;)", "patterns": [ { "include": "#comment" }, { "name": "entity.name.type.namespace.cs", "match": "\\@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-accessor" }, { "include": "#operator-assignment" } ] } ] }, "attribute-section": { "begin": "(\\[)(assembly|module|field|event|method|param|property|return|type)?(\\:)?", "beginCaptures": { "1": { "name": "punctuation.squarebracket.open.cs" }, "2": { "name": "keyword.other.attribute-specifier.cs" }, "3": { "name": "punctuation.separator.colon.cs" } }, "end": "(\\])", "endCaptures": { "1": { "name": "punctuation.squarebracket.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#attribute" }, { "include": "#punctuation-comma" } ] }, "attribute": { "patterns": [ { "include": "#type-name" }, { "include": "#type-arguments" }, { "include": "#attribute-arguments" } ] }, "attribute-arguments": { "begin": "(\\()", "beginCaptures": { "1": { "name": "punctuation.parenthesis.open.cs" } }, "end": "(\\))", "endCaptures": { "1": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#attribute-named-argument" }, { "include": "#expression" }, { "include": "#punctuation-comma" } ] }, "attribute-named-argument": { "begin": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(?==)", "beginCaptures": { "1": { "name": "entity.name.variable.property.cs" } }, "end": "(?=(,|\\)))", "patterns": [ { "include": "#operator-assignment" }, { "include": "#expression" } ] }, "namespace-declaration": { "begin": "\\b(namespace)\\s+", "beginCaptures": { "1": { "name": "storage.type.namespace.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "name": "entity.name.type.namespace.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-accessor" }, { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#declarations" }, { "include": "#using-directive" }, { "include": "#punctuation-semicolon" } ] } ] }, "storage-modifier": { "name": "storage.modifier.$1.cs", "match": "(?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s+\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", "beginCaptures": { "1": { "name": "storage.type.delegate.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.type.delegate.cs" }, "8": { "patterns": [ { "include": "#type-parameter-list" } ] } }, "end": "(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#generic-constraints" } ] }, "enum-declaration": { "begin": "(?=\\benum\\b)", "end": "(?<=\\})|(?=;)", "patterns": [ { "begin": "(?=enum)", "end": "(?=\\{)|(?=;)", "patterns": [ { "include": "#comment" }, { "match": "(enum)\\s+(@?[_[:alpha:]][_[:alnum:]]*)", "captures": { "1": { "name": "storage.type.enum.cs" }, "2": { "name": "entity.name.type.enum.cs" } } }, { "begin": ":", "beginCaptures": { "0": { "name": "punctuation.separator.colon.cs" } }, "end": "(?=\\{)", "patterns": [ { "include": "#type" } ] } ] }, { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#attribute-section" }, { "include": "#punctuation-comma" }, { "begin": "@?[_[:alpha:]][_[:alnum:]]*", "beginCaptures": { "0": { "name": "entity.name.variable.enum-member.cs" } }, "end": "(?=(,|\\}))", "patterns": [ { "include": "#comment" }, { "include": "#variable-initializer" } ] } ] }, { "include": "#preprocessor" }, { "include": "#comment" } ] }, "interface-declaration": { "begin": "(?=\\binterface\\b)", "end": "(?<=\\})|(?=;)", "patterns": [ { "begin": "(?x)\n(interface)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "1": { "name": "storage.type.interface.cs" }, "2": { "name": "entity.name.type.interface.cs" } }, "end": "(?=\\{)|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#type-parameter-list" }, { "include": "#base-types" }, { "include": "#generic-constraints" } ] }, { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#interface-members" } ] }, { "include": "#preprocessor" }, { "include": "#comment" } ] }, "record-declaration": { "begin": "(?=\\brecord\\b)", "end": "(?<=\\})|(?=;)", "patterns": [ { "begin": "(?x)\n(record)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "1": { "name": "storage.type.record.cs" }, "2": { "name": "entity.name.type.class.cs" } }, "end": "(?=\\{)|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#type-parameter-list" }, { "include": "#parenthesized-parameter-list" }, { "include": "#base-types" }, { "include": "#generic-constraints" } ] }, { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#class-or-struct-members" } ] }, { "include": "#preprocessor" }, { "include": "#comment" } ] }, "struct-declaration": { "begin": "(?=(\\brecord\\b\\s+)?\\bstruct\\b)", "end": "(?<=\\})|(?=;)", "patterns": [ { "begin": "(?x)\n(\\b(record)\\b\\s+)?\n(struct)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "2": { "name": "storage.type.record.cs" }, "3": { "name": "storage.type.struct.cs" }, "4": { "name": "entity.name.type.struct.cs" } }, "end": "(?=\\{)|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#type-parameter-list" }, { "include": "#parenthesized-parameter-list" }, { "include": "#base-types" }, { "include": "#generic-constraints" } ] }, { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#class-or-struct-members" } ] }, { "include": "#preprocessor" }, { "include": "#comment" } ] }, "type-parameter-list": { "begin": "\\<", "beginCaptures": { "0": { "name": "punctuation.definition.typeparameters.begin.cs" } }, "end": "\\>", "endCaptures": { "0": { "name": "punctuation.definition.typeparameters.end.cs" } }, "patterns": [ { "match": "\\b(in|out)\\b", "name": "storage.modifier.$1.cs" }, { "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\b", "name": "entity.name.type.type-parameter.cs" }, { "include": "#comment" }, { "include": "#punctuation-comma" }, { "include": "#attribute-section" } ] }, "base-types": { "begin": ":", "beginCaptures": { "0": { "name": "punctuation.separator.colon.cs" } }, "end": "(?=\\{|where|;)", "patterns": [ { "include": "#type" }, { "include": "#punctuation-comma" }, { "include": "#preprocessor" } ] }, "generic-constraints": { "begin": "(where)\\s+(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)", "beginCaptures": { "1": { "name": "storage.modifier.where.cs" }, "2": { "name": "entity.name.type.type-parameter.cs" }, "3": { "name": "punctuation.separator.colon.cs" } }, "end": "(?=\\{|where|;|=>)", "patterns": [ { "name": "storage.type.class.cs", "match": "\\bclass\\b" }, { "name": "storage.type.struct.cs", "match": "\\bstruct\\b" }, { "name": "keyword.other.constraint.default.cs", "match": "\\bdefault\\b" }, { "name": "keyword.other.constraint.notnull.cs", "match": "\\bnotnull\\b" }, { "name": "keyword.other.constraint.unmanaged.cs", "match": "\\bunmanaged\\b" }, { "match": "(new)\\s*(\\()\\s*(\\))", "captures": { "1": { "name": "keyword.operator.expression.new.cs" }, "2": { "name": "punctuation.parenthesis.open.cs" }, "3": { "name": "punctuation.parenthesis.close.cs" } } }, { "include": "#type" }, { "include": "#punctuation-comma" }, { "include": "#generic-constraints" } ] }, "field-declaration": { "begin": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s+\n(\\g)\\s* # first field name\n(?!=>|==)(?=,|;|=|$)", "beginCaptures": { "1": { "patterns": [ { "include": "#type" } ] }, "6": { "name": "entity.name.variable.field.cs" } }, "end": "(?=;)", "patterns": [ { "name": "entity.name.variable.field.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" }, { "include": "#comment" }, { "include": "#variable-initializer" }, { "include": "#class-or-struct-members" } ] }, "property-declaration": { "begin": "(?x)\n\n# The negative lookahead below ensures that we don't match nested types\n# or other declarations as properties.\n(?![[:word:][:space:]]*\\b(?:class|interface|struct|enum|event)\\b)\n\n(?\n (?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?\\g)\\s*\n(?=\\{|=>|//|/\\*|$)", "beginCaptures": { "1": { "patterns": [ { "include": "#type" } ] }, "7": { "patterns": [ { "include": "#type" }, { "include": "#punctuation-accessor" } ] }, "8": { "name": "entity.name.variable.property.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#property-accessors" }, { "include": "#accessor-getter-expression" }, { "include": "#variable-initializer" }, { "include": "#class-or-struct-members" } ] }, "indexer-declaration": { "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?this)\\s*\n(?=\\[)", "beginCaptures": { "1": { "patterns": [ { "include": "#type" } ] }, "7": { "patterns": [ { "include": "#type" }, { "include": "#punctuation-accessor" } ] }, "8": { "name": "variable.language.this.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#bracketed-parameter-list" }, { "include": "#property-accessors" }, { "include": "#accessor-getter-expression" }, { "include": "#variable-initializer" } ] }, "event-declaration": { "begin": "(?x)\n\\b(event)\\b\\s*\n(?\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(\\g)\\s* # first event name\n(?=\\{|;|,|=|//|/\\*|$)", "beginCaptures": { "1": { "name": "storage.type.event.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "8": { "patterns": [ { "include": "#type" }, { "include": "#punctuation-accessor" } ] }, "9": { "name": "entity.name.variable.event.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#event-accessors" }, { "name": "entity.name.variable.event.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" }, { "begin": "=", "beginCaptures": { "0": { "name": "keyword.operator.assignment.cs" } }, "end": "(?<=,)|(?=;)", "patterns": [ { "include": "#expression" }, { "include": "#punctuation-comma" } ] } ] }, "property-accessors": { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#attribute-section" }, { "name": "storage.modifier.$1.cs", "match": "\\b(private|protected|internal)\\b" }, { "begin": "\\b(get)\\b\\s*(?=\\{|;|=>|//|/\\*|$)", "beginCaptures": { "1": { "name": "storage.type.accessor.$1.cs" } }, "end": "(?<=\\}|;)|(?=\\})", "patterns": [ { "include": "#accessor-getter" } ] }, { "begin": "\\b(set|init)\\b\\s*(?=\\{|;|=>|//|/\\*|$)", "beginCaptures": { "1": { "name": "storage.type.accessor.$1.cs" } }, "end": "(?<=\\}|;)|(?=\\})", "patterns": [ { "include": "#accessor-setter" } ] } ] }, "event-accessors": { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#attribute-section" }, { "begin": "\\b(add|remove)\\b\\s*(?=\\{|;|=>|//|/\\*|$)", "beginCaptures": { "1": { "name": "storage.type.accessor.$1.cs" } }, "end": "(?<=\\}|;)|(?=\\})", "patterns": [ { "include": "#accessor-setter" } ] } ] }, "accessor-getter": { "patterns": [ { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "contentName": "meta.accessor.getter.cs", "patterns": [ { "include": "#statement" } ] }, { "include": "#accessor-getter-expression" }, { "include": "#punctuation-semicolon" } ] }, "accessor-getter-expression": { "begin": "=>", "beginCaptures": { "0": { "name": "keyword.operator.arrow.cs" } }, "end": "(?=;|\\})", "contentName": "meta.accessor.getter.cs", "patterns": [ { "include": "#ref-modifier" }, { "include": "#expression" } ] }, "accessor-setter": { "patterns": [ { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "contentName": "meta.accessor.setter.cs", "patterns": [ { "include": "#statement" } ] }, { "begin": "=>", "beginCaptures": { "0": { "name": "keyword.operator.arrow.cs" } }, "end": "(?=;|\\})", "contentName": "meta.accessor.setter.cs", "patterns": [ { "include": "#ref-modifier" }, { "include": "#expression" } ] }, { "include": "#punctuation-semicolon" } ] }, "method-declaration": { "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ { "include": "#type" } ] }, "7": { "patterns": [ { "include": "#type" }, { "include": "#punctuation-accessor" } ] }, "8": { "name": "entity.name.function.cs" }, "9": { "patterns": [ { "include": "#type-parameter-list" } ] } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#generic-constraints" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "constructor-declaration": { "begin": "(?=@?[_[:alpha:]][_[:alnum:]]*\\s*\\()", "end": "(?<=\\})|(?=;)", "patterns": [ { "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\b", "captures": { "1": { "name": "entity.name.function.cs" } } }, { "begin": "(:)", "beginCaptures": { "1": { "name": "punctuation.separator.colon.cs" } }, "end": "(?=\\{|=>)", "patterns": [ { "include": "#constructor-initializer" } ] }, { "include": "#parenthesized-parameter-list" }, { "include": "#preprocessor" }, { "include": "#comment" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "constructor-initializer": { "begin": "\\b(base|this)\\b\\s*(?=\\()", "beginCaptures": { "1": { "name": "variable.language.$1.cs" } }, "end": "(?<=\\))", "patterns": [ { "include": "#argument-list" } ] }, "destructor-declaration": { "begin": "(~)(@?[_[:alpha:]][_[:alnum:]]*)\\s*(?=\\()", "beginCaptures": { "1": { "name": "punctuation.tilde.cs" }, "2": { "name": "entity.name.function.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "operator-declaration": { "begin": "(?x)\n(?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n\\b(?operator)\\b\\s*\n(?[+\\-*/%&|\\^!=~<>]+|true|false)\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ { "include": "#type" } ] }, "6": { "name": "storage.type.operator.cs" }, "7": { "name": "entity.name.function.cs" } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "conversion-operator-declaration": { "begin": "(?x)\n(?(?:\\b(?:explicit|implicit)))\\s*\n(?(?:\\b(?:operator)))\\s*\n(?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ { "match": "\\b(explicit)\\b", "captures": { "1": { "name": "storage.modifier.explicit.cs" } } }, { "match": "\\b(implicit)\\b", "captures": { "1": { "name": "storage.modifier.implicit.cs" } } } ] }, "2": { "name": "storage.type.operator.cs" }, "3": { "patterns": [ { "include": "#type" } ] } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "block": { "begin": "\\{", "beginCaptures": { "0": { "name": "punctuation.curlybrace.open.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.curlybrace.close.cs" } }, "patterns": [ { "include": "#statement" } ] }, "variable-initializer": { "begin": "(?)", "beginCaptures": { "1": { "name": "keyword.operator.assignment.cs" } }, "end": "(?=[,\\)\\];}])", "patterns": [ { "include": "#ref-modifier" }, { "include": "#expression" } ] }, "expression-body": { "begin": "=>", "beginCaptures": { "0": { "name": "keyword.operator.arrow.cs" } }, "end": "(?=[,\\);}])", "patterns": [ { "include": "#ref-modifier" }, { "include": "#expression" } ] }, "goto-statement": { "begin": "(?", "beginCaptures": { "0": { "name": "keyword.operator.arrow.cs" } }, "end": "(?=,|})", "patterns": [ { "include": "#expression" } ] }, { "begin": "\\b(when)\\b", "beginCaptures": { "1": { "name": "keyword.control.conditional.when.cs" } }, "end": "(?==>|,|})", "patterns": [ { "include": "#case-guard" } ] }, { "begin": "(?!\\s)", "end": "(?=\\bwhen\\b|=>|,|})", "patterns": [ { "include": "#pattern" } ] } ] }, "case-guard": { "patterns": [ { "include": "#parenthesized-expression" }, { "include": "#expression" } ] }, "is-expression": { "begin": "(?=?", "beginCaptures": { "0": { "name": "keyword.operator.relational.cs" } }, "end": "(?=[)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#expression" } ] }, "var-pattern": { "begin": "\\b(var)\\b", "beginCaptures": { "1": { "name": "storage.type.var.cs" } }, "end": "(?=[)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#designation-pattern" } ] }, "designation-pattern": { "patterns": [ { "include": "#intrusive" }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#punctuation-comma" }, { "include": "#designation-pattern" } ] }, { "include": "#simple-designation-pattern" } ] }, "simple-designation-pattern": { "patterns": [ { "include": "#discard-pattern" }, { "match": "@?[_[:alpha:]][_[:alnum:]]*", "name": "entity.name.variable.local.cs" } ] }, "type-pattern": { "begin": "(?=@?[_[:alpha:]][_[:alnum:]]*)", "end": "(?=[)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "begin": "\\G", "end": "(?!\\G[@_[:alpha:]])(?=[\\({@_[:alpha:])}\\],;:=&|^]|(?:\\s|^)\\?|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#intrusive" }, { "include": "#type-subpattern" } ] }, { "begin": "(?=[\\({@_[:alpha:]])", "end": "(?=[)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#intrusive" }, { "include": "#positional-pattern" }, { "include": "#property-pattern" }, { "include": "#simple-designation-pattern" } ] } ] }, "type-subpattern": { "patterns": [ { "include": "#type-builtin" }, { "begin": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(::)", "beginCaptures": { "1": { "name": "entity.name.type.alias.cs" }, "2": { "name": "punctuation.separator.coloncolon.cs" } }, "end": "(?<=[_[:alnum:]])|(?=[.<\\[\\({)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#intrusive" }, { "match": "\\@?[_[:alpha:]][_[:alnum:]]*", "name": "entity.name.type.cs" } ] }, { "match": "\\@?[_[:alpha:]][_[:alnum:]]*", "name": "entity.name.type.cs" }, { "begin": "\\.", "beginCaptures": { "0": { "name": "punctuation.accessor.cs" } }, "end": "(?<=[_[:alnum:]])|(?=[<\\[\\({)}\\],;:?=&|^]|!=|\\b(and|or|when)\\b)", "patterns": [ { "include": "#intrusive" }, { "match": "\\@?[_[:alpha:]][_[:alnum:]]*", "name": "entity.name.type.cs" } ] }, { "include": "#type-arguments" }, { "include": "#type-array-suffix" }, { "match": "(?\n (?:\n (?:ref\\s+)? # ref local\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\n)\\s+\n(\\g)\\s+\n\\b(in)\\b", "captures": { "1": { "name": "storage.modifier.ref.cs" }, "2": { "name": "storage.type.var.cs" }, "3": { "patterns": [ { "include": "#type" } ] }, "8": { "name": "entity.name.variable.local.cs" }, "9": { "name": "keyword.control.loop.in.cs" } } }, { "match": "(?x) # match foreach (var (x, y) in ...)\n(?:\\b(var)\\b\\s*)?\n(?\\((?:[^\\(\\)]|\\g)+\\))\\s+\n\\b(in)\\b", "captures": { "1": { "name": "storage.type.var.cs" }, "2": { "patterns": [ { "include": "#tuple-declaration-deconstruction-element-list" } ] }, "3": { "name": "keyword.control.loop.in.cs" } } }, { "include": "#expression" } ] } ] }, "try-statement": { "patterns": [ { "include": "#try-block" }, { "include": "#catch-clause" }, { "include": "#finally-clause" } ] }, "try-block": { "begin": "(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n(?:(\\g)\\b)?", "captures": { "1": { "patterns": [ { "include": "#type" } ] }, "6": { "name": "entity.name.variable.local.cs" } } } ] }, { "include": "#when-clause" }, { "include": "#comment" }, { "include": "#block" } ] }, "when-clause": { "begin": "(?\n (?:\n (?:ref\\s+(?:readonly\\s+)?)? # ref local\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*[?*]\\s*)? # nullable or pointer suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\n)\\s+\n(\\g)\\s*\n(?!=>)\n(?=,|;|=|\\))", "beginCaptures": { "1": { "name": "storage.modifier.ref.cs" }, "2": { "name": "storage.modifier.readonly.cs" }, "3": { "name": "storage.type.var.cs" }, "4": { "patterns": [ { "include": "#type" } ] }, "9": { "name": "entity.name.variable.local.cs" } }, "end": "(?=[;)}])", "patterns": [ { "name": "entity.name.variable.local.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" }, { "include": "#comment" }, { "include": "#variable-initializer" } ] }, "local-constant-declaration": { "begin": "(?x)\n(?\\b(?:const)\\b)\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s+\n(\\g)\\s*\n(?=,|;|=)", "beginCaptures": { "1": { "name": "storage.modifier.const.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.local.cs" } }, "end": "(?=;)", "patterns": [ { "name": "entity.name.variable.local.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" }, { "include": "#comment" }, { "include": "#variable-initializer" } ] }, "local-function-declaration": { "begin": "(?x)\n\\b((?:(?:async|unsafe|static|extern)\\s+)*)\n(?\n (?:ref\\s+(?:readonly\\s+)?)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n \\s*(?:,\\s*)* # commata for multi-dimensional arrays\n \\]\n (?:\\s*\\?)? # arrays can be nullable reference types\n )*\n)\\s+\n(\\g)\\s*\n(<[^<>]+>)?\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ { "include": "#storage-modifier" } ] }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.function.cs" }, "8": { "patterns": [ { "include": "#type-parameter-list" } ] } }, "end": "(?<=\\})|(?=;)", "patterns": [ { "include": "#comment" }, { "include": "#parenthesized-parameter-list" }, { "include": "#generic-constraints" }, { "include": "#expression-body" }, { "include": "#block" } ] }, "local-tuple-var-deconstruction": { "begin": "(?x) # e.g. var (x, y) = GetPoint();\n(?:\\b(var)\\b\\s*)\n(?\\((?:[^\\(\\)]|\\g)+\\))\\s*\n(?=;|=|\\))", "beginCaptures": { "1": { "name": "storage.type.var.cs" }, "2": { "patterns": [ { "include": "#tuple-declaration-deconstruction-element-list" } ] } }, "end": "(?=;|\\))", "patterns": [ { "include": "#comment" }, { "include": "#variable-initializer" } ] }, "tuple-deconstruction-assignment": { "match": "(?x)\n(?\\s*\\((?:[^\\(\\)]|\\g)+\\))\\s*\n(?!=>|==)(?==)", "captures": { "1": { "patterns": [ { "include": "#tuple-deconstruction-element-list" } ] } } }, "tuple-declaration-deconstruction-element-list": { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#tuple-declaration-deconstruction-element-list" }, { "include": "#declaration-expression-tuple" }, { "include": "#punctuation-comma" }, { "match": "(?x) # e.g. x\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "entity.name.variable.tuple-element.cs" } } } ] }, "tuple-deconstruction-element-list": { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#tuple-deconstruction-element-list" }, { "include": "#declaration-expression-tuple" }, { "include": "#punctuation-comma" }, { "match": "(?x) # e.g. x\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "variable.other.readwrite.cs" } } } ] }, "declaration-expression-local": { "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\n)\\s+\n(\\g)\\b\\s*\n(?=[,)\\]])", "captures": { "1": { "name": "storage.type.var.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.local.cs" } } }, "declaration-expression-tuple": { "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n )\n)\\s+\n(\\g)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "storage.type.var.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.tuple-element.cs" } } }, "expression-operator-expression": { "begin": "\\b(checked|unchecked|nameof)\\s*(\\()", "beginCaptures": { "1": { "name": "keyword.operator.expression.$1.cs" }, "2": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#expression" } ] }, "type-operator-expression": { "begin": "\\b(default|sizeof|typeof)\\s*(\\()", "beginCaptures": { "1": { "name": "keyword.operator.expression.$1.cs" }, "2": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#type" } ] }, "default-literal-expression": { "match": "\\b(default)\\b", "captures": { "1": { "name": "keyword.operator.expression.default.cs" } } }, "throw-expression": { "match": "\\b(throw)\\b", "captures": { "1": { "name": "keyword.control.flow.throw.cs" } } }, "interpolated-string": { "name": "string.quoted.double.cs", "begin": "\\$\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "(\")|((?:[^\\\\\\n])$)", "endCaptures": { "1": { "name": "punctuation.definition.string.end.cs" }, "2": { "name": "invalid.illegal.newline.cs" } }, "patterns": [ { "include": "#string-character-escape" }, { "include": "#interpolation" } ] }, "verbatim-interpolated-string": { "name": "string.quoted.double.cs", "begin": "(?:\\$@|@\\$)\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"(?=[^\"])", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#verbatim-string-character-escape" }, { "include": "#interpolation" } ] }, "interpolation": { "name": "meta.interpolation.cs", "begin": "(?<=[^\\{]|^)((?:\\{\\{)*)(\\{)(?=[^\\{])", "beginCaptures": { "1": { "name": "string.quoted.double.cs" }, "2": { "name": "punctuation.definition.interpolation.begin.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.definition.interpolation.end.cs" } }, "patterns": [ { "include": "#expression" } ] }, "raw-interpolated-string": { "patterns": [ { "include": "#raw-interpolated-string-five-or-more-quote-one-or-more-interpolation" }, { "include": "#raw-interpolated-string-three-or-more-quote-three-or-more-interpolation" }, { "include": "#raw-interpolated-string-quadruple-quote-double-interpolation" }, { "include": "#raw-interpolated-string-quadruple-quote-single-interpolation" }, { "include": "#raw-interpolated-string-triple-quote-double-interpolation" }, { "include": "#raw-interpolated-string-triple-quote-single-interpolation" } ] }, "raw-interpolated-string-triple-quote-single-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$\"\"\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#raw-interpolation" } ] }, "raw-interpolated-string-triple-quote-double-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$\\$\"\"\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#double-raw-interpolation" } ] }, "raw-interpolated-string-quadruple-quote-single-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$\"\"\"\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#raw-interpolation" } ] }, "raw-interpolated-string-quadruple-quote-double-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$\\$\"\"\"\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#double-raw-interpolation" } ] }, "raw-interpolated-string-three-or-more-quote-three-or-more-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$\\$\\$+\"\"\"+", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"+", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } } }, "raw-interpolated-string-five-or-more-quote-one-or-more-interpolation": { "name": "string.quoted.double.cs", "begin": "\\$+\"\"\"\"\"+", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\"\"\"\"\"+", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } } }, "raw-interpolation": { "name": "meta.interpolation.cs", "begin": "(?<=[^\\{]|^)((?:\\{)*)(\\{)(?=[^\\{])", "beginCaptures": { "1": { "name": "string.quoted.double.cs" }, "2": { "name": "punctuation.definition.interpolation.begin.cs" } }, "end": "\\}", "endCaptures": { "0": { "name": "punctuation.definition.interpolation.end.cs" } }, "patterns": [ { "include": "#expression" } ] }, "double-raw-interpolation": { "name": "meta.interpolation.cs", "begin": "(?<=[^\\{][^\\{]|^)((?:\\{)*)(\\{\\{)(?=[^\\{])", "beginCaptures": { "1": { "name": "string.quoted.double.cs" }, "2": { "name": "punctuation.definition.interpolation.begin.cs" } }, "end": "\\}\\}", "endCaptures": { "0": { "name": "punctuation.definition.interpolation.end.cs" } }, "patterns": [ { "include": "#expression" } ] }, "literal": { "patterns": [ { "include": "#boolean-literal" }, { "include": "#null-literal" }, { "include": "#numeric-literal" }, { "include": "#char-literal" }, { "include": "#raw-string-literal" }, { "include": "#string-literal" }, { "include": "#verbatim-string-literal" }, { "include": "#tuple-literal" } ] }, "boolean-literal": { "patterns": [ { "name": "constant.language.boolean.true.cs", "match": "(?>>?|\\|)?=(?!=|>)", "beginCaptures": { "0": { "patterns": [ { "include": "#assignment-operators" } ] } }, "end": "(?=[,\\)\\];}])", "patterns": [ { "include": "#ref-modifier" }, { "include": "#expression" } ] }, "assignment-operators": { "patterns": [ { "name": "keyword.operator.assignment.compound.cs", "match": "\\*=|/=|%=|\\+=|-=|\\?\\?=" }, { "name": "keyword.operator.assignment.compound.bitwise.cs", "match": "\\&=|\\^=|<<=|>>>?=|\\|=" }, { "name": "keyword.operator.assignment.cs", "match": "\\=" } ] }, "expression-operators": { "patterns": [ { "name": "keyword.operator.bitwise.shift.cs", "match": "<<|>>>?" }, { "name": "keyword.operator.comparison.cs", "match": "==|!=" }, { "name": "keyword.operator.relational.cs", "match": "<=|>=|<|>" }, { "name": "keyword.operator.logical.cs", "match": "\\!|&&|\\|\\|" }, { "name": "keyword.operator.bitwise.cs", "match": "\\&|~|\\^|\\|" }, { "name": "keyword.operator.decrement.cs", "match": "--" }, { "name": "keyword.operator.increment.cs", "match": "\\+\\+" }, { "name": "keyword.operator.arithmetic.cs", "match": "\\+|-(?!>)|\\*|/|%" }, { "name": "keyword.operator.null-coalescing.cs", "match": "\\?\\?" }, { "name": "keyword.operator.range.cs", "match": "\\.\\." } ] }, "with-expression": { "begin": "(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n(\\))(?=\\s*-*!*@?[_[:alnum:]\\(])", "captures": { "1": { "name": "punctuation.parenthesis.open.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "punctuation.parenthesis.close.cs" } } }, "as-expression": { "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?(?!\\?))? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n \\s*(?:,\\s*)* # commata for multi-dimensional arrays\n \\]\n (?:\\s*\\?(?!\\?))? # arrays can be nullable reference types\n )*\n )\n)?", "captures": { "1": { "name": "keyword.operator.expression.as.cs" }, "2": { "patterns": [ { "include": "#type" } ] } } }, "language-variable": { "patterns": [ { "name": "variable.language.$1.cs", "match": "\\b(base|this)\\b" }, { "name": "variable.other.$1.cs", "match": "\\b(value)\\b" } ] }, "invocation-expression": { "begin": "(?x)\n(?:\n (?:(\\?)\\s*)? # preceding null-conditional operator?\n (\\.)\\s*| # preceding dot?\n (->)\\s* # preceding pointer arrow?\n)?\n(@?[_[:alpha:]][_[:alnum:]]*)\\s* # method name\n(\n <\n (?\n [^<>()]|\n \\((?:[^<>()]|<[^<>()]*>|\\([^<>()]*\\))*\\)|\n <\\g*>\n )*\n >\\s*\n)? # type arguments\n(?=\\() # open paren of argument list", "beginCaptures": { "1": { "name": "keyword.operator.null-conditional.cs" }, "2": { "name": "punctuation.accessor.cs" }, "3": { "name": "punctuation.accessor.pointer.cs" }, "4": { "name": "entity.name.function.cs" }, "5": { "patterns": [ { "include": "#type-arguments" } ] } }, "end": "(?<=\\))", "patterns": [ { "include": "#argument-list" } ] }, "element-access-expression": { "begin": "(?x)\n(?:\n (?:(\\?)\\s*)? # preceding null-conditional operator?\n (\\.)\\s*| # preceding dot?\n (->)\\s* # preceding pointer arrow?\n)?\n(?:(@?[_[:alpha:]][_[:alnum:]]*)\\s*)? # property name\n(?:(\\?)\\s*)? # null-conditional operator?\n(?=\\[) # open bracket of argument list", "beginCaptures": { "1": { "name": "keyword.operator.null-conditional.cs" }, "2": { "name": "punctuation.accessor.cs" }, "3": { "name": "punctuation.accessor.pointer.cs" }, "4": { "name": "variable.other.object.property.cs" }, "5": { "name": "keyword.operator.null-conditional.cs" } }, "end": "(?<=\\])(?!\\s*\\[)", "patterns": [ { "include": "#bracketed-argument-list" } ] }, "member-access-expression": { "patterns": [ { "match": "(?x)\n(?:\n (?:(\\?)\\s*)? # preceding null-conditional operator?\n (\\.)\\s*| # preceding dot?\n (->)\\s* # preceding pointer arrow?\n)\n(@?[_[:alpha:]][_[:alnum:]]*)\\s* # property name\n(?![_[:alnum:]]|\\(|(\\?)?\\[|<) # next character is not alpha-numeric, nor a (, [, or <. Also, test for ?[", "captures": { "1": { "name": "keyword.operator.null-conditional.cs" }, "2": { "name": "punctuation.accessor.cs" }, "3": { "name": "punctuation.accessor.pointer.cs" }, "4": { "name": "variable.other.object.property.cs" } } }, { "match": "(?x)\n(\\.)?\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\n(?\\s*<([^<>]|\\g)+>\\s*)\n(?=\n (\\s*\\?)?\n \\s*\\.\\s*@?[_[:alpha:]][_[:alnum:]]*\n)", "captures": { "1": { "name": "punctuation.accessor.cs" }, "2": { "name": "variable.other.object.cs" }, "3": { "patterns": [ { "include": "#type-arguments" } ] } } }, { "match": "(?x)\n(@?[_[:alpha:]][_[:alnum:]]*)\n(?=\n \\s*(?:(?:\\?\\s*)?\\.|->)\n \\s*@?[_[:alpha:]][_[:alnum:]]*\n)", "captures": { "1": { "name": "variable.other.object.cs" } } } ] }, "object-creation-expression": { "patterns": [ { "include": "#object-creation-expression-with-parameters" }, { "include": "#object-creation-expression-with-no-parameters" } ] }, "object-creation-expression-with-parameters": { "begin": "(?x)\n(new)(?:\\s+\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n))?\\s*\n(?=\\()", "beginCaptures": { "1": { "name": "keyword.operator.expression.new.cs" }, "2": { "patterns": [ { "include": "#type" } ] } }, "end": "(?<=\\))", "patterns": [ { "include": "#argument-list" } ] }, "object-creation-expression-with-no-parameters": { "match": "(?x)\n(new)\\s+\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n(?=\\{|//|/\\*|$)", "captures": { "1": { "name": "keyword.operator.expression.new.cs" }, "2": { "patterns": [ { "include": "#type" } ] } } }, "array-creation-expression": { "begin": "(?x)\n\\b(new|stackalloc)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)?\\s*\n(?=\\[)", "beginCaptures": { "1": { "name": "keyword.operator.expression.$1.cs" }, "2": { "patterns": [ { "include": "#type" } ] } }, "end": "(?<=\\])", "patterns": [ { "include": "#bracketed-argument-list" } ] }, "anonymous-object-creation-expression": { "begin": "\\b(new)\\b\\s*(?=\\{|//|/\\*|$)", "beginCaptures": { "1": { "name": "keyword.operator.expression.new.cs" } }, "end": "(?<=\\})", "patterns": [ { "include": "#comment" }, { "include": "#initializer-expression" } ] }, "bracketed-parameter-list": { "begin": "(?=(\\[))", "beginCaptures": { "1": { "name": "punctuation.squarebracket.open.cs" } }, "end": "(?=(\\]))", "endCaptures": { "1": { "name": "punctuation.squarebracket.close.cs" } }, "patterns": [ { "begin": "(?<=\\[)", "end": "(?=\\])", "patterns": [ { "include": "#comment" }, { "include": "#attribute-section" }, { "include": "#parameter" }, { "include": "#punctuation-comma" }, { "include": "#variable-initializer" } ] } ] }, "parenthesized-parameter-list": { "begin": "(\\()", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "(\\))", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#comment" }, { "include": "#attribute-section" }, { "include": "#parameter" }, { "include": "#punctuation-comma" }, { "include": "#variable-initializer" } ] }, "parameter": { "match": "(?x)\n(?:(?:\\b(ref|params|out|in|this)\\b)\\s+)?\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^()]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s+\n(\\g)", "captures": { "1": { "name": "storage.modifier.$1.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.parameter.cs" } } }, "argument-list": { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#named-argument" }, { "include": "#argument" }, { "include": "#punctuation-comma" } ] }, "bracketed-argument-list": { "begin": "\\[", "beginCaptures": { "0": { "name": "punctuation.squarebracket.open.cs" } }, "end": "\\]", "endCaptures": { "0": { "name": "punctuation.squarebracket.close.cs" } }, "patterns": [ { "include": "#named-argument" }, { "include": "#argument" }, { "include": "#punctuation-comma" } ] }, "named-argument": { "begin": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)", "beginCaptures": { "1": { "name": "entity.name.variable.parameter.cs" }, "2": { "name": "punctuation.separator.colon.cs" } }, "end": "(?=(,|\\)|\\]))", "patterns": [ { "include": "#argument" } ] }, "argument": { "patterns": [ { "name": "storage.modifier.$1.cs", "match": "\\b(ref|in)\\b" }, { "begin": "\\b(out)\\b", "beginCaptures": { "1": { "name": "storage.modifier.out.cs" } }, "end": "(?=,|\\)|\\])", "patterns": [ { "include": "#declaration-expression-local" }, { "include": "#expression" } ] }, { "include": "#expression" } ] }, "query-expression": { "begin": "(?x)\n\\b(from)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)?\n\\s+(\\g)\\b\\s*\n\\b(in)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.from.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.range-variable.cs" }, "8": { "name": "keyword.operator.expression.query.in.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#query-body" }, { "include": "#expression" } ] }, "query-body": { "patterns": [ { "include": "#let-clause" }, { "include": "#where-clause" }, { "include": "#join-clause" }, { "include": "#orderby-clause" }, { "include": "#select-clause" }, { "include": "#group-clause" } ] }, "let-clause": { "begin": "(?x)\n\\b(let)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(=)\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.let.cs" }, "2": { "name": "entity.name.variable.range-variable.cs" }, "3": { "name": "keyword.operator.assignment.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#query-body" }, { "include": "#expression" } ] }, "where-clause": { "begin": "(?x)\n\\b(where)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.where.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#query-body" }, { "include": "#expression" } ] }, "join-clause": { "begin": "(?x)\n\\b(join)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)?\n\\s+(\\g)\\b\\s*\n\\b(in)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.join.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.range-variable.cs" }, "8": { "name": "keyword.operator.expression.query.in.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#join-on" }, { "include": "#join-equals" }, { "include": "#join-into" }, { "include": "#query-body" }, { "include": "#expression" } ] }, "join-on": { "match": "\\b(on)\\b\\s*", "captures": { "1": { "name": "keyword.operator.expression.query.on.cs" } } }, "join-equals": { "match": "\\b(equals)\\b\\s*", "captures": { "1": { "name": "keyword.operator.expression.query.equals.cs" } } }, "join-into": { "match": "(?x)\n\\b(into)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*", "captures": { "1": { "name": "keyword.operator.expression.query.into.cs" }, "2": { "name": "entity.name.variable.range-variable.cs" } } }, "orderby-clause": { "begin": "\\b(orderby)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.orderby.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#ordering-direction" }, { "include": "#query-body" }, { "include": "#expression" }, { "include": "#punctuation-comma" } ] }, "ordering-direction": { "match": "\\b(ascending|descending)\\b", "captures": { "1": { "name": "keyword.operator.expression.query.$1.cs" } } }, "select-clause": { "begin": "\\b(select)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.select.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#query-body" }, { "include": "#expression" } ] }, "group-clause": { "begin": "\\b(group)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.operator.expression.query.group.cs" } }, "end": "(?=;|\\))", "patterns": [ { "include": "#group-by" }, { "include": "#group-into" }, { "include": "#query-body" }, { "include": "#expression" } ] }, "group-by": { "match": "\\b(by)\\b\\s*", "captures": { "1": { "name": "keyword.operator.expression.query.by.cs" } } }, "group-into": { "match": "(?x)\n\\b(into)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*", "captures": { "1": { "name": "keyword.operator.expression.query.into.cs" }, "2": { "name": "entity.name.variable.range-variable.cs" } } }, "anonymous-method-expression": { "patterns": [ { "begin": "(?x)\n((?:\\b(?:async|static)\\b\\s*)*)\n(?:\n (@?[_[:alpha:]][_[:alnum:]]*)\\b|\n (\\()\n (?(?:[^()]|\\(\\g\\))*)\n (\\))\n)\\s*\n(=>)", "beginCaptures": { "1": { "patterns": [ { "match": "async|static", "name": "storage.modifier.$0.cs" } ] }, "2": { "name": "entity.name.variable.parameter.cs" }, "3": { "name": "punctuation.parenthesis.open.cs" }, "4": { "patterns": [ { "include": "#comment" }, { "include": "#explicit-anonymous-function-parameter" }, { "include": "#implicit-anonymous-function-parameter" }, { "include": "#default-argument" }, { "include": "#punctuation-comma" } ] }, "5": { "name": "punctuation.parenthesis.close.cs" }, "6": { "name": "keyword.operator.arrow.cs" } }, "end": "(?=[,;)}])", "patterns": [ { "include": "#intrusive" }, { "begin": "(?={)", "end": "(?=[,;)}])", "patterns": [ { "include": "#block" }, { "include": "#intrusive" } ] }, { "begin": "\\b(ref)\\b|(?=\\S)", "beginCaptures": { "1": { "name": "storage.modifier.ref.cs" } }, "end": "(?=[,;)}])", "patterns": [ { "include": "#expression" } ] } ] }, { "begin": "(?x)\n((?:\\b(?:async|static)\\b\\s*)*)\n\\b(delegate)\\b\\s*", "beginCaptures": { "1": { "patterns": [ { "match": "async|static", "name": "storage.modifier.$0.cs" } ] }, "2": { "name": "storage.type.delegate.cs" } }, "end": "(?<=})|(?=[,;)}])", "patterns": [ { "include": "#intrusive" }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#intrusive" }, { "include": "#explicit-anonymous-function-parameter" }, { "include": "#punctuation-comma" } ] }, { "include": "#block" } ] } ] }, "explicit-anonymous-function-parameter": { "match": "(?x)\n(?:\\b(ref|params|out|in)\\b\\s*)?\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?<(?:[^<>]|\\g)*>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^()]|\\g)*\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\\s*\n\\b(\\g)\\b", "captures": { "1": { "name": "storage.modifier.$1.cs" }, "2": { "patterns": [ { "include": "#type" } ] }, "7": { "name": "entity.name.variable.parameter.cs" } } }, "implicit-anonymous-function-parameter": { "match": "\\@?[_[:alpha:]][_[:alnum:]]*\\b", "name": "entity.name.variable.parameter.cs" }, "default-argument": { "begin": "=", "beginCaptures": { "0": { "name": "keyword.operator.assignment.cs" } }, "end": "(?=,|\\))", "patterns": [ { "include": "#expression" } ] }, "type": { "patterns": [ { "include": "#comment" }, { "include": "#ref-modifier" }, { "include": "#readonly-modifier" }, { "include": "#tuple-type" }, { "include": "#type-builtin" }, { "include": "#type-name" }, { "include": "#type-arguments" }, { "include": "#type-array-suffix" }, { "include": "#type-nullable-suffix" }, { "include": "#type-pointer-suffix" } ] }, "ref-modifier": { "name": "storage.modifier.ref.cs", "match": "\\bref\\b" }, "readonly-modifier": { "name": "storage.modifier.readonly.cs", "match": "\\breadonly\\b" }, "tuple-type": { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.parenthesis.open.cs" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.parenthesis.close.cs" } }, "patterns": [ { "include": "#tuple-element" }, { "include": "#punctuation-comma" } ] }, "tuple-element": { "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s* # array suffix?\n \\[\n (?:\\s*,\\s*)* # commata for multi-dimensional arrays\n \\]\n \\s*\n (?:\\?)? # arrays can be nullable reference types\n \\s*\n )*\n )\n)\n(?:(?\\g)\\b)?", "captures": { "1": { "patterns": [ { "include": "#type" } ] }, "6": { "name": "entity.name.variable.tuple-element.cs" } } }, "type-builtin": { "match": "\\b(bool|s?byte|u?short|n?u?int|u?long|float|double|decimal|char|string|object|void|dynamic)\\b", "captures": { "1": { "name": "keyword.type.$1.cs" } } }, "type-name": { "patterns": [ { "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(\\:\\:)", "captures": { "1": { "name": "entity.name.type.alias.cs" }, "2": { "name": "punctuation.separator.coloncolon.cs" } } }, { "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(\\.)", "captures": { "1": { "name": "entity.name.type.cs" }, "2": { "name": "punctuation.accessor.cs" } } }, { "match": "(\\.)\\s*(@?[_[:alpha:]][_[:alnum:]]*)", "captures": { "1": { "name": "punctuation.accessor.cs" }, "2": { "name": "entity.name.type.cs" } } }, { "name": "entity.name.type.cs", "match": "@?[_[:alpha:]][_[:alnum:]]*" } ] }, "type-arguments": { "begin": "<", "beginCaptures": { "0": { "name": "punctuation.definition.typeparameters.begin.cs" } }, "end": ">", "endCaptures": { "0": { "name": "punctuation.definition.typeparameters.end.cs" } }, "patterns": [ { "include": "#type" }, { "include": "#punctuation-comma" } ] }, "type-array-suffix": { "begin": "\\[", "beginCaptures": { "0": { "name": "punctuation.squarebracket.open.cs" } }, "end": "\\]", "endCaptures": { "0": { "name": "punctuation.squarebracket.close.cs" } }, "patterns": [ { "include": "#intrusive" }, { "include": "#punctuation-comma" } ] }, "type-nullable-suffix": { "match": "\\?", "name": "punctuation.separator.question-mark.cs" }, "type-pointer-suffix": { "match": "\\*", "name": "punctuation.separator.asterisk.cs" }, "operator-assignment": { "name": "keyword.operator.assignment.cs", "match": "(?)", "endCaptures": { "1": { "name": "punctuation.definition.tag.cs" } }, "patterns": [ { "include": "#xml-attribute" } ] }, "xml-attribute": { "patterns": [ { "match": "(?x)\n(?:^|\\s+)\n(\n (?:\n ([-_[:alnum:]]+)\n (:)\n )?\n ([-_[:alnum:]]+)\n)\n(=)", "captures": { "1": { "name": "entity.other.attribute-name.cs" }, "2": { "name": "entity.other.attribute-name.namespace.cs" }, "3": { "name": "punctuation.separator.colon.cs" }, "4": { "name": "entity.other.attribute-name.localname.cs" }, "5": { "name": "punctuation.separator.equals.cs" } } }, { "include": "#xml-string" } ] }, "xml-cdata": { "name": "string.unquoted.cdata.cs", "begin": "", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } } }, "xml-string": { "patterns": [ { "name": "string.quoted.single.cs", "begin": "\\'", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\\'", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#xml-character-entity" } ] }, { "name": "string.quoted.double.cs", "begin": "\\\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.cs" } }, "end": "\\\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.cs" } }, "patterns": [ { "include": "#xml-character-entity" } ] } ] }, "xml-character-entity": { "patterns": [ { "name": "constant.character.entity.cs", "match": "(?x)\n(&)\n(\n (?:[[:alpha:]:_][[:alnum:]:_.-]*)|\n (?:\\#[[:digit:]]+)|\n (?:\\#x[[:xdigit:]]+)\n)\n(;)", "captures": { "1": { "name": "punctuation.definition.constant.cs" }, "3": { "name": "punctuation.definition.constant.cs" } } }, { "name": "invalid.illegal.bad-ampersand.cs", "match": "&" } ] }, "xml-comment": { "name": "comment.block.cs", "begin": "", "endCaptures": { "0": { "name": "punctuation.definition.comment.cs" } } } } } ================================================ FILE: extensions/css/.vscode/launch.json ================================================ { "version": "0.2.0", "configurations": [ { "name": "Launch Grammar", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceRoot}" ] } ] } ================================================ FILE: extensions/css/.vscodeignore ================================================ test/** cgmanifest.json .vscode ================================================ FILE: extensions/css/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "microsoft/vscode-css", "repositoryUrl": "https://github.com/microsoft/vscode-css", "commitHash": "a927fe2f73927bf5c25d0b0c4dd0e63d69fd8887" } }, "licenseDetail": [ "MIT License", "", "Copyright (c) Microsoft Corporation.", "", "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.", "", "--------------------------------------------------------------------", "", "This package was derived from a TextMate bundle located at", "https://github.com/textmate/css.tmbundle and distributed under the following", "license, located in `README.mdown`:", "", "Permission to copy, use, modify, sell and distribute this", "software is granted. This software is provided \"as is\" without", "express or implied warranty, and with no claim as to its", "suitability for any purpose." ], "license": "MIT License", "description": "The file syntaxes/css.tmLanguage.json was derived from https://github.com/atom/language-css which was originally converted from the TextMate bundle https://github.com/textmate/css.tmbundle.", "version": "0.0.0" } ], "version": 1 } ================================================ FILE: extensions/css/language-configuration.json ================================================ { "comments": { "blockComment": ["/*", "*/"] }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ { "open": "{", "close": "}", "notIn": ["string", "comment"] }, { "open": "[", "close": "]", "notIn": ["string", "comment"] }, { "open": "(", "close": ")", "notIn": ["string", "comment"] }, { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, { "open": "'", "close": "'", "notIn": ["string", "comment"] } ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["\"", "\""], ["'", "'"] ], "folding": { "markers": { "start": "^\\s*\\/\\*\\s*#region\\b\\s*(.*?)\\s*\\*\\/", "end": "^\\s*\\/\\*\\s*#endregion\\b.*\\*\\/" } }, "indentationRules": { "increaseIndentPattern": "(^.*\\{[^}]*$)", "decreaseIndentPattern": "^\\s*\\}" }, "wordPattern": "(#?-?\\d*\\.\\d\\w*%?)|(::?[\\w-]*(?=[^,{;]*[,{]))|(([@#.!])?[\\w-?]+%?|[@#!.])" } ================================================ FILE: extensions/css/package.json ================================================ { "name": "css", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "0.10.x" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin microsoft/vscode-css grammars/css.cson ./syntaxes/css.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "css", "aliases": [ "CSS", "css" ], "extensions": [ ".css" ], "mimetypes": [ "text/css" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "css", "scopeName": "source.css", "path": "./syntaxes/css.tmLanguage.json", "tokenTypes": { "meta.function.url string.quoted": "other" } } ] }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/css/package.nls.json ================================================ { "displayName": "CSS Language Basics", "description": "Provides syntax highlighting and bracket matching for CSS, LESS and SCSS files." } ================================================ FILE: extensions/css/syntaxes/css.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/microsoft/vscode-css/blob/master/grammars/css.cson", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/microsoft/vscode-css/commit/a927fe2f73927bf5c25d0b0c4dd0e63d69fd8887", "name": "CSS", "scopeName": "source.css", "patterns": [ { "include": "#comment-block" }, { "include": "#escapes" }, { "include": "#combinators" }, { "include": "#selector" }, { "include": "#at-rules" }, { "include": "#rule-list" } ], "repository": { "at-rules": { "patterns": [ { "begin": "\\A(?:\\xEF\\xBB\\xBF)?(?i:(?=\\s*@charset\\b))", "end": ";|(?=$)", "endCaptures": { "0": { "name": "punctuation.terminator.rule.css" } }, "name": "meta.at-rule.charset.css", "patterns": [ { "captures": { "1": { "name": "invalid.illegal.not-lowercase.charset.css" }, "2": { "name": "invalid.illegal.leading-whitespace.charset.css" }, "3": { "name": "invalid.illegal.no-whitespace.charset.css" }, "4": { "name": "invalid.illegal.whitespace.charset.css" }, "5": { "name": "invalid.illegal.not-double-quoted.charset.css" }, "6": { "name": "invalid.illegal.unclosed-string.charset.css" }, "7": { "name": "invalid.illegal.unexpected-characters.charset.css" } }, "match": "(?x) # Possible errors:\n\\G\n((?!@charset)@\\w+) # Not lowercase (@charset is case-sensitive)\n|\n\\G(\\s+) # Preceding whitespace\n|\n(@charset\\S[^;]*) # No whitespace after @charset\n|\n(?<=@charset) # Before quoted charset name\n(\\x20{2,}|\\t+) # More than one space used, or a tab\n|\n(?<=@charset\\x20) # Beginning of charset name\n([^\";]+) # Not double-quoted\n|\n(\"[^\"]+$) # Unclosed quote\n|\n(?<=\") # After charset name\n([^;]+) # Unexpected junk instead of semicolon" }, { "captures": { "1": { "name": "keyword.control.at-rule.charset.css" }, "2": { "name": "punctuation.definition.keyword.css" } }, "match": "((@)charset)(?=\\s)" }, { "begin": "\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.css" } }, "end": "\"|$", "endCaptures": { "0": { "name": "punctuation.definition.string.end.css" } }, "name": "string.quoted.double.css", "patterns": [ { "begin": "(?:\\G|^)(?=(?:[^\"])+$)", "end": "$", "name": "invalid.illegal.unclosed.string.css" } ] } ] }, { "begin": "(?i)((@)import)(?:\\s+|$|(?=['\"]|/\\*))", "beginCaptures": { "1": { "name": "keyword.control.at-rule.import.css" }, "2": { "name": "punctuation.definition.keyword.css" } }, "end": ";", "endCaptures": { "0": { "name": "punctuation.terminator.rule.css" } }, "name": "meta.at-rule.import.css", "patterns": [ { "begin": "\\G\\s*(?=/\\*)", "end": "(?<=\\*/)\\s*", "patterns": [ { "include": "#comment-block" } ] }, { "include": "#string" }, { "include": "#url" }, { "include": "#media-query-list" } ] }, { "begin": "(?i)((@)font-face)(?=\\s*|{|/\\*|$)", "beginCaptures": { "1": { "name": "keyword.control.at-rule.font-face.css" }, "2": { "name": "punctuation.definition.keyword.css" } }, "end": "(?!\\G)", "name": "meta.at-rule.font-face.css", "patterns": [ { "include": "#comment-block" }, { "include": "#escapes" }, { "include": "#rule-list" } ] }, { "begin": "(?i)(@)page(?=[\\s:{]|/\\*|$)", "captures": { "0": { "name": "keyword.control.at-rule.page.css" }, "1": { "name": "punctuation.definition.keyword.css" } }, "end": "(?=\\s*($|[:{;]))", "name": "meta.at-rule.page.css", "patterns": [ { "include": "#rule-list" } ] }, { "begin": "(?i)(?=@media(\\s|\\(|/\\*|$))", "end": "(?<=})(?!\\G)", "patterns": [ { "begin": "(?i)\\G(@)media", "beginCaptures": { "0": { "name": "keyword.control.at-rule.media.css" }, "1": { "name": "punctuation.definition.keyword.css" } }, "end": "(?=\\s*[{;])", "name": "meta.at-rule.media.header.css", "patterns": [ { "include": "#media-query-list" } ] }, { "begin": "{", "beginCaptures": { "0": { "name": "punctuation.section.media.begin.bracket.curly.css" } }, "end": "}", "endCaptures": { "0": { "name": "punctuation.section.media.end.bracket.curly.css" } }, "name": "meta.at-rule.media.body.css", "patterns": [ { "include": "$self" } ] } ] }, { "begin": "(?i)(?=@counter-style([\\s'\"{;]|/\\*|$))", "end": "(?<=})(?!\\G)", "patterns": [ { "begin": "(?i)\\G(@)counter-style", "beginCaptures": { "0": { "name": "keyword.control.at-rule.counter-style.css" }, "1": { "name": "punctuation.definition.keyword.css" } }, "end": "(?=\\s*{)", "name": "meta.at-rule.counter-style.header.css", "patterns": [ { "include": "#comment-block" }, { "include": "#escapes" }, { "captures": { "0": { "patterns": [ { "include": "#escapes" } ] } }, "match": "(?x)\n(?:[-a-zA-Z_] | [^\\x00-\\x7F]) # First letter\n(?:[-a-zA-Z0-9_] | [^\\x00-\\x7F] # Remainder of identifier\n |\\\\(?:[0-9a-fA-F]{1,6}|.)\n)*", "name": "variable.parameter.style-name.css" } ] }, { "begin": "{", "beginCaptures": { "0": { "name": "punctuation.section.property-list.begin.bracket.curly.css" } }, "end": "}", "endCaptures": { "0": { "name": "punctuation.section.property-list.end.bracket.curly.css" } }, "name": "meta.at-rule.counter-style.body.css", "patterns": [ { "include": "#comment-block" }, { "include": "#escapes" }, { "include": "#rule-list-innards" } ] } ] }, { "begin": "(?i)(?=@document([\\s'\"{;]|/\\*|$))", "end": "(?<=})(?!\\G)", "patterns": [ { "begin": "(?i)\\G(@)document", "beginCaptures": { "0": { "name": "keyword.control.at-rule.document.css" }, "1": { "name": "punctuation.definition.keyword.css" } }, "end": "(?=\\s*[{;])", "name": "meta.at-rule.document.header.css", "patterns": [ { "begin": "(?i)(?>>", "name": "invalid.deprecated.combinator.css" }, { "match": ">>|>|\\+|~", "name": "keyword.operator.combinator.css" } ] }, "commas": { "match": ",", "name": "punctuation.separator.list.comma.css" }, "comment-block": { "begin": "/\\*", "beginCaptures": { "0": { "name": "punctuation.definition.comment.begin.css" } }, "end": "\\*/", "endCaptures": { "0": { "name": "punctuation.definition.comment.end.css" } }, "name": "comment.block.css" }, "escapes": { "patterns": [ { "match": "\\\\[0-9a-fA-F]{1,6}", "name": "constant.character.escape.codepoint.css" }, { "begin": "\\\\$\\s*", "end": "^(?<:=]|\\)|/\\*) # Terminates cleanly" }, "media-feature-keywords": { "match": "(?xi)\n(?<=^|\\s|:|\\*/)\n(?: portrait # Orientation\n | landscape\n | progressive # Scan types\n | interlace\n | fullscreen # Display modes\n | standalone\n | minimal-ui\n | browser\n | hover\n)\n(?=\\s|\\)|$)", "name": "support.constant.property-value.css" }, "media-query": { "begin": "\\G", "end": "(?=\\s*[{;])", "patterns": [ { "include": "#comment-block" }, { "include": "#escapes" }, { "include": "#media-types" }, { "match": "(?i)(?<=\\s|^|,|\\*/)(only|not)(?=\\s|{|/\\*|$)", "name": "keyword.operator.logical.$1.media.css" }, { "match": "(?i)(?<=\\s|^|\\*/|\\))and(?=\\s|/\\*|$)", "name": "keyword.operator.logical.and.media.css" }, { "match": ",(?:(?:\\s*,)+|(?=\\s*[;){]))", "name": "invalid.illegal.comma.css" }, { "include": "#commas" }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.definition.parameters.begin.bracket.round.css" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.parameters.end.bracket.round.css" } }, "patterns": [ { "include": "#media-features" }, { "include": "#media-feature-keywords" }, { "match": ":", "name": "punctuation.separator.key-value.css" }, { "match": ">=|<=|=|<|>", "name": "keyword.operator.comparison.css" }, { "captures": { "1": { "name": "constant.numeric.css" }, "2": { "name": "keyword.operator.arithmetic.css" }, "3": { "name": "constant.numeric.css" } }, "match": "(\\d+)\\s*(/)\\s*(\\d+)", "name": "meta.ratio.css" }, { "include": "#numeric-values" }, { "include": "#comment-block" } ] } ] }, "media-query-list": { "begin": "(?=\\s*[^{;])", "end": "(?=\\s*[{;])", "patterns": [ { "include": "#media-query" } ] }, "media-types": { "captures": { "1": { "name": "support.constant.media.css" }, "2": { "name": "invalid.deprecated.constant.media.css" } }, "match": "(?xi)\n(?<=^|\\s|,|\\*/)\n(?:\n # Valid media types\n (all|print|screen|speech)\n |\n # Deprecated in Media Queries 4: http://dev.w3.org/csswg/mediaqueries/#media-types\n (aural|braille|embossed|handheld|projection|tty|tv)\n)\n(?=$|[{,\\s;]|/\\*)" }, "numeric-values": { "patterns": [ { "captures": { "1": { "name": "punctuation.definition.constant.css" } }, "match": "(#)(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\\b", "name": "constant.other.color.rgb-value.hex.css" }, { "captures": { "1": { "name": "keyword.other.unit.percentage.css" }, "2": { "name": "keyword.other.unit.${2:/downcase}.css" } }, "match": "(?xi) (?+~|] # - Followed by another selector\n | /\\* # - Followed by a block comment\n )\n |\n # Name contains unescaped ASCII symbol\n (?: # Check for acceptable preceding characters\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # - Valid selector character\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence\n )*\n (?: # Invalid punctuation\n [!\"'%&(*;+~|] # - Another selector\n | /\\* # - A block comment\n)", "name": "entity.other.attribute-name.class.css" }, { "captures": { "1": { "name": "punctuation.definition.entity.css" }, "2": { "patterns": [ { "include": "#escapes" } ] } }, "match": "(?x)\n(\\#)\n(\n -?\n (?![0-9])\n (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n)\n(?=$|[\\s,.\\#)\\[:{>+~|]|/\\*)", "name": "entity.other.attribute-name.id.css" }, { "begin": "\\[", "beginCaptures": { "0": { "name": "punctuation.definition.entity.begin.bracket.square.css" } }, "end": "\\]", "endCaptures": { "0": { "name": "punctuation.definition.entity.end.bracket.square.css" } }, "name": "meta.attribute-selector.css", "patterns": [ { "include": "#comment-block" }, { "include": "#string" }, { "captures": { "1": { "name": "storage.modifier.ignore-case.css" } }, "match": "(?<=[\"'\\s]|^|\\*/)\\s*([iI])\\s*(?=[\\s\\]]|/\\*|$)" }, { "captures": { "1": { "name": "string.unquoted.attribute-value.css", "patterns": [ { "include": "#escapes" } ] } }, "match": "(?x)(?<==)\\s*((?!/\\*)(?:[^\\\\\"'\\s\\]]|\\\\.)+)" }, { "include": "#escapes" }, { "match": "[~|^$*]?=", "name": "keyword.operator.pattern.css" }, { "match": "\\|", "name": "punctuation.separator.css" }, { "captures": { "1": { "name": "entity.other.namespace-prefix.css", "patterns": [ { "include": "#escapes" } ] } }, "match": "(?x)\n# Qualified namespace prefix\n( -?(?!\\d)(?:[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n| \\*\n)\n# Lookahead to ensure there's a valid identifier ahead\n(?=\n \\| (?!\\s|=|$|\\])\n (?: -?(?!\\d)\n | [\\\\\\w-]\n | [^\\x00-\\x7F]\n )\n)" }, { "captures": { "1": { "name": "entity.other.attribute-name.css", "patterns": [ { "include": "#escapes" } ] } }, "match": "(?x)\n(-?(?!\\d)(?>[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+)\n\\s*\n(?=[~|^\\]$*=]|/\\*)" } ] }, { "include": "#pseudo-classes" }, { "include": "#pseudo-elements" }, { "include": "#functional-pseudo-classes" }, { "match": "(?x) (?\\s,.\\#|){:\\[]|/\\*|$)", "name": "entity.name.tag.css" }, "unicode-range": { "captures": { "0": { "name": "constant.other.unicode-range.css" }, "1": { "name": "punctuation.separator.dash.unicode-range.css" } }, "match": "(? { return new LanguageClient(id, name, worker, clientOptions); }; client = await startClient(context, newLanguageClient, { TextDecoder }); context.subscriptions.push(registerDropOrPasteResourceSupport({ language: 'css', scheme: '*' })); } catch (e) { console.log(e); } } export async function deactivate(): Promise { if (client) { await client.stop(); client = undefined; } } ================================================ FILE: extensions/css-language-features/client/src/cssClient.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { commands, CompletionItem, CompletionItemKind, ExtensionContext, languages, Position, Range, SnippetString, TextEdit, window, TextDocument, CompletionContext, CancellationToken, ProviderResult, CompletionList, FormattingOptions, workspace, l10n } from 'vscode'; import { Disposable, LanguageClientOptions, ProvideCompletionItemsSignature, NotificationType, BaseLanguageClient, DocumentRangeFormattingParams, DocumentRangeFormattingRequest } from 'vscode-languageclient'; import { getCustomDataSource } from './customData'; import { RequestService, serveFileSystemRequests } from './requests'; namespace CustomDataChangedNotification { export const type: NotificationType = new NotificationType('css/customDataChanged'); } export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient; export interface Runtime { TextDecoder: { new(encoding?: string): { decode(buffer: ArrayBuffer): string } }; fs?: RequestService; } interface FormatterRegistration { readonly languageId: string; readonly settingId: string; provider: Disposable | undefined; } interface CSSFormatSettings { newlineBetweenSelectors?: boolean; newlineBetweenRules?: boolean; spaceAroundSelectorSeparator?: boolean; braceStyle?: 'collapse' | 'expand'; preserveNewLines?: boolean; maxPreserveNewLines?: number | null; } const cssFormatSettingKeys: (keyof CSSFormatSettings)[] = ['newlineBetweenSelectors', 'newlineBetweenRules', 'spaceAroundSelectorSeparator', 'braceStyle', 'preserveNewLines', 'maxPreserveNewLines']; export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise { const customDataSource = getCustomDataSource(context.subscriptions); const documentSelector = ['css', 'scss', 'less']; const formatterRegistrations: FormatterRegistration[] = documentSelector.map(languageId => ({ languageId, settingId: `${languageId}.format.enable`, provider: undefined })); // Options to control the language client const clientOptions: LanguageClientOptions = { documentSelector, synchronize: { configurationSection: ['css', 'scss', 'less'] }, initializationOptions: { handledSchemas: ['file'], provideFormatter: false, // tell the server to not provide formatting capability customCapabilities: { rangeFormatting: { editLimit: 10000 } } }, middleware: { provideCompletionItem(document: TextDocument, position: Position, context: CompletionContext, token: CancellationToken, next: ProvideCompletionItemsSignature): ProviderResult { // testing the replace / insert mode function updateRanges(item: CompletionItem) { const range = item.range; if (range instanceof Range && range.end.isAfter(position) && range.start.isBeforeOrEqual(position)) { item.range = { inserting: new Range(range.start, position), replacing: range }; } } function updateLabel(item: CompletionItem) { if (item.kind === CompletionItemKind.Color) { item.label = { label: item.label as string, description: (item.documentation as string) }; } } // testing the new completion function updateProposals(r: CompletionItem[] | CompletionList | null | undefined): CompletionItem[] | CompletionList | null | undefined { if (r) { (Array.isArray(r) ? r : r.items).forEach(updateRanges); (Array.isArray(r) ? r : r.items).forEach(updateLabel); } return r; } const isThenable = (obj: ProviderResult): obj is Thenable => obj && (obj)['then']; const r = next(document, position, context, token); if (isThenable(r)) { return r.then(updateProposals); } return updateProposals(r); } } }; // Create the language client and start the client. const client = newLanguageClient('css', l10n.t('CSS Language Server'), clientOptions); client.registerProposedFeatures(); await client.start(); client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris); customDataSource.onDidChange(() => { client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris); }); // manually register / deregister format provider based on the `css/less/scss.format.enable` setting avoiding issues with late registration. See #71652. for (const registration of formatterRegistrations) { updateFormatterRegistration(registration); context.subscriptions.push({ dispose: () => registration.provider?.dispose() }); context.subscriptions.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration(registration.settingId) && updateFormatterRegistration(registration))); } serveFileSystemRequests(client, runtime); context.subscriptions.push(initCompletionProvider()); function initCompletionProvider(): Disposable { const regionCompletionRegExpr = /^(\s*)(\/(\*\s*(#\w*)?)?)?$/; return languages.registerCompletionItemProvider(documentSelector, { provideCompletionItems(doc: TextDocument, pos: Position) { const lineUntilPos = doc.getText(new Range(new Position(pos.line, 0), pos)); const match = lineUntilPos.match(regionCompletionRegExpr); if (match) { const range = new Range(new Position(pos.line, match[1].length), pos); const beginProposal = new CompletionItem('#region', CompletionItemKind.Snippet); beginProposal.range = range; TextEdit.replace(range, '/* #region */'); beginProposal.insertText = new SnippetString('/* #region $1*/'); beginProposal.documentation = l10n.t('Folding Region Start'); beginProposal.filterText = match[2]; beginProposal.sortText = 'za'; const endProposal = new CompletionItem('#endregion', CompletionItemKind.Snippet); endProposal.range = range; endProposal.insertText = '/* #endregion */'; endProposal.documentation = l10n.t('Folding Region End'); endProposal.sortText = 'zb'; endProposal.filterText = match[2]; return [beginProposal, endProposal]; } return null; } }); } commands.registerCommand('_css.applyCodeAction', applyCodeAction); function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) { const textEditor = window.activeTextEditor; if (textEditor && textEditor.document.uri.toString() === uri) { if (textEditor.document.version !== documentVersion) { window.showInformationMessage(l10n.t('CSS fix is outdated and can\'t be applied to the document.')); } textEditor.edit(mutator => { for (const edit of edits) { mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText); } }).then(success => { if (!success) { window.showErrorMessage(l10n.t('Failed to apply CSS fix to the document. Please consider opening an issue with steps to reproduce.')); } }); } } function updateFormatterRegistration(registration: FormatterRegistration) { const formatEnabled = workspace.getConfiguration().get(registration.settingId); if (!formatEnabled && registration.provider) { registration.provider.dispose(); registration.provider = undefined; } else if (formatEnabled && !registration.provider) { registration.provider = languages.registerDocumentRangeFormattingEditProvider(registration.languageId, { provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { const filesConfig = workspace.getConfiguration('files', document); const fileFormattingOptions = { trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), trimFinalNewlines: filesConfig.get('trimFinalNewlines'), insertFinalNewline: filesConfig.get('insertFinalNewline'), }; const params: DocumentRangeFormattingParams = { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), range: client.code2ProtocolConverter.asRange(range), options: client.code2ProtocolConverter.asFormattingOptions(options, fileFormattingOptions) }; // add the css formatter options from the settings const formatterSettings = workspace.getConfiguration(registration.languageId, document).get('format'); if (formatterSettings) { for (const key of cssFormatSettingKeys) { const val = formatterSettings[key]; if (val !== undefined && val !== null) { params.options[key] = val; } } } return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then( client.protocol2CodeConverter.asTextEdits, (error) => { client.handleFailedRequest(DocumentRangeFormattingRequest.type, undefined, error, []); return Promise.resolve([]); } ); } }); } } return client; } ================================================ FILE: extensions/css-language-features/client/src/customData.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { workspace, extensions, Uri, EventEmitter, Disposable } from 'vscode'; import { Utils } from 'vscode-uri'; export function getCustomDataSource(toDispose: Disposable[]) { let pathsInWorkspace = getCustomDataPathsInAllWorkspaces(); let pathsInExtensions = getCustomDataPathsFromAllExtensions(); const onChange = new EventEmitter(); toDispose.push(extensions.onDidChange(_ => { const newPathsInExtensions = getCustomDataPathsFromAllExtensions(); if (newPathsInExtensions.length !== pathsInExtensions.length || !newPathsInExtensions.every((val, idx) => val === pathsInExtensions[idx])) { pathsInExtensions = newPathsInExtensions; onChange.fire(); } })); toDispose.push(workspace.onDidChangeConfiguration(e => { if (e.affectsConfiguration('css.customData')) { pathsInWorkspace = getCustomDataPathsInAllWorkspaces(); onChange.fire(); } })); return { get uris() { return pathsInWorkspace.concat(pathsInExtensions); }, get onDidChange() { return onChange.event; } }; } function getCustomDataPathsInAllWorkspaces(): string[] { const workspaceFolders = workspace.workspaceFolders; const dataPaths: string[] = []; if (!workspaceFolders) { return dataPaths; } const collect = (paths: string[] | undefined, rootFolder: Uri) => { if (Array.isArray(paths)) { for (const path of paths) { if (typeof path === 'string') { dataPaths.push(Utils.resolvePath(rootFolder, path).toString()); } } } }; for (let i = 0; i < workspaceFolders.length; i++) { const folderUri = workspaceFolders[i].uri; const allCssConfig = workspace.getConfiguration('css', folderUri); const customDataInspect = allCssConfig.inspect('customData'); if (customDataInspect) { collect(customDataInspect.workspaceFolderValue, folderUri); if (i === 0) { if (workspace.workspaceFile) { collect(customDataInspect.workspaceValue, workspace.workspaceFile); } collect(customDataInspect.globalValue, folderUri); } } } return dataPaths; } function getCustomDataPathsFromAllExtensions(): string[] { const dataPaths: string[] = []; for (const extension of extensions.all) { const customData = extension.packageJSON?.contributes?.css?.customData; if (Array.isArray(customData)) { for (const rp of customData) { dataPaths.push(Utils.joinPath(extension.extensionUri, rp).toString()); } } } return dataPaths; } ================================================ FILE: extensions/css-language-features/client/src/dropOrPaste/dropOrPasteResource.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as vscode from 'vscode'; import { getDocumentDir, Mimes, Schemes } from './shared'; import { UriList } from './uriList'; class DropOrPasteResourceProvider implements vscode.DocumentDropEditProvider, vscode.DocumentPasteEditProvider { readonly kind = vscode.DocumentDropOrPasteEditKind.Empty.append('css', 'link', 'url'); async provideDocumentDropEdits( document: vscode.TextDocument, position: vscode.Position, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken, ): Promise { const uriList = await this.getUriList(dataTransfer); if (!uriList.entries.length || token.isCancellationRequested) { return; } const snippet = await this.createUriListSnippet(document.uri, uriList); if (!snippet || token.isCancellationRequested) { return; } return { kind: this.kind, title: snippet.label, insertText: snippet.snippet.value, yieldTo: this.pasteAsCssUrlByDefault(document, position) ? [] : [vscode.DocumentDropOrPasteEditKind.Empty.append('uri')] }; } async provideDocumentPasteEdits( document: vscode.TextDocument, ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _context: vscode.DocumentPasteEditContext, token: vscode.CancellationToken ): Promise { const uriList = await this.getUriList(dataTransfer); if (!uriList.entries.length || token.isCancellationRequested) { return; } const snippet = await this.createUriListSnippet(document.uri, uriList); if (!snippet || token.isCancellationRequested) { return; } return [{ kind: this.kind, title: snippet.label, insertText: snippet.snippet.value, yieldTo: this.pasteAsCssUrlByDefault(document, ranges[0].start) ? [] : [vscode.DocumentDropOrPasteEditKind.Empty.append('uri')] }]; } private async getUriList(dataTransfer: vscode.DataTransfer): Promise { const urlList = await dataTransfer.get(Mimes.uriList)?.asString(); if (urlList) { return UriList.from(urlList); } // Find file entries const uris: vscode.Uri[] = []; for (const [_, entry] of dataTransfer) { const file = entry.asFile(); if (file?.uri) { uris.push(file.uri); } } return new UriList(uris.map(uri => ({ uri, str: uri.toString(true) }))); } private async createUriListSnippet(docUri: vscode.Uri, uriList: UriList): Promise<{ readonly snippet: vscode.SnippetString; readonly label: string } | undefined> { if (!uriList.entries.length) { return; } const snippet = new vscode.SnippetString(); for (let i = 0; i < uriList.entries.length; i++) { const uri = uriList.entries[i]; const relativePath = getRelativePath(getDocumentDir(docUri), uri.uri); const urlText = relativePath ?? uri.str; snippet.appendText(`url(${urlText})`); if (i !== uriList.entries.length - 1) { snippet.appendText(' '); } } return { snippet, label: uriList.entries.length > 1 ? vscode.l10n.t('Insert url() Functions') : vscode.l10n.t('Insert url() Function') }; } private pasteAsCssUrlByDefault(document: vscode.TextDocument, position: vscode.Position): boolean { const regex = /url\(.+?\)/gi; for (const match of Array.from(document.lineAt(position.line).text.matchAll(regex))) { if (position.character > match.index && position.character < match.index + match[0].length) { return false; } } return true; } } function getRelativePath(fromFile: vscode.Uri | undefined, toFile: vscode.Uri): string | undefined { if (fromFile && fromFile.scheme === toFile.scheme && fromFile.authority === toFile.authority) { if (toFile.scheme === Schemes.file) { // On windows, we must use the native `path.relative` to generate the relative path // so that drive-letters are resolved cast insensitively. However we then want to // convert back to a posix path to insert in to the document const relativePath = path.relative(fromFile.fsPath, toFile.fsPath); return path.posix.normalize(relativePath.split(path.sep).join(path.posix.sep)); } return path.posix.relative(fromFile.path, toFile.path); } return undefined; } export function registerDropOrPasteResourceSupport(selector: vscode.DocumentSelector): vscode.Disposable { const provider = new DropOrPasteResourceProvider(); return vscode.Disposable.from( vscode.languages.registerDocumentDropEditProvider(selector, provider, { providedDropEditKinds: [provider.kind], dropMimeTypes: [ Mimes.uriList, 'files' ] }), vscode.languages.registerDocumentPasteEditProvider(selector, provider, { providedPasteEditKinds: [provider.kind], pasteMimeTypes: [ Mimes.uriList, 'files' ] }) ); } ================================================ FILE: extensions/css-language-features/client/src/dropOrPaste/shared.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { Utils } from 'vscode-uri'; export const Schemes = Object.freeze({ file: 'file', notebookCell: 'vscode-notebook-cell', untitled: 'untitled', }); export const Mimes = Object.freeze({ plain: 'text/plain', uriList: 'text/uri-list', }); export function getDocumentDir(uri: vscode.Uri): vscode.Uri | undefined { const docUri = getParentDocumentUri(uri); if (docUri.scheme === Schemes.untitled) { return vscode.workspace.workspaceFolders?.[0]?.uri; } return Utils.dirname(docUri); } function getParentDocumentUri(uri: vscode.Uri): vscode.Uri { if (uri.scheme === Schemes.notebookCell) { // is notebook documents necessary? for (const notebook of vscode.workspace.notebookDocuments) { for (const cell of notebook.getCells()) { if (cell.document.uri.toString() === uri.toString()) { return notebook.uri; } } } } return uri; } ================================================ FILE: extensions/css-language-features/client/src/dropOrPaste/uriList.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; function splitUriList(str: string): string[] { return str.split('\r\n'); } function parseUriList(str: string): string[] { return splitUriList(str) .filter(value => !value.startsWith('#')) // Remove comments .map(value => value.trim()); } export class UriList { static from(str: string): UriList { return new UriList(coalesce(parseUriList(str).map(line => { try { return { uri: vscode.Uri.parse(line), str: line }; } catch { // Uri parse failure return undefined; } }))); } constructor( public readonly entries: ReadonlyArray<{ readonly uri: vscode.Uri; readonly str: string }> ) { } } function coalesce(array: ReadonlyArray): T[] { return array.filter(e => !!e); } ================================================ FILE: extensions/css-language-features/client/src/node/cssClientMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TextDecoder } from 'util'; import { ExtensionContext, extensions, l10n } from 'vscode'; import { BaseLanguageClient, LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node'; import { LanguageClientConstructor, startClient } from '../cssClient'; import { getNodeFSRequestService } from './nodeFs'; import { registerDropOrPasteResourceSupport } from '../dropOrPaste/dropOrPasteResource'; let client: BaseLanguageClient | undefined; // this method is called when vs code is activated export async function activate(context: ExtensionContext) { const clientMain = extensions.getExtension('vscode.css-language-features')?.packageJSON?.main || ''; const serverMain = `./server/${clientMain.indexOf('/dist/') !== -1 ? 'dist' : 'out'}/node/cssServerMain`; const serverModule = context.asAbsolutePath(serverMain); // The debug options for the server const debugOptions = { execArgv: ['--nolazy', '--inspect=' + (7000 + Math.round(Math.random() * 999))] }; // If the extension is launch in debug mode the debug server options are use // Otherwise the run options are used const serverOptions: ServerOptions = { run: { module: serverModule, transport: TransportKind.ipc }, debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } }; const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => { return new LanguageClient(id, name, serverOptions, clientOptions); }; // pass the location of the localization bundle to the server process.env['VSCODE_L10N_BUNDLE_LOCATION'] = l10n.uri?.toString() ?? ''; client = await startClient(context, newLanguageClient, { fs: getNodeFSRequestService(), TextDecoder }); context.subscriptions.push(registerDropOrPasteResourceSupport({ language: 'css', scheme: '*' })); } export async function deactivate(): Promise { if (client) { await client.stop(); client = undefined; } } ================================================ FILE: extensions/css-language-features/client/src/node/nodeFs.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; import { Uri } from 'vscode'; import { RequestService, FileType } from '../requests'; export function getNodeFSRequestService(): RequestService { function ensureFileUri(location: string) { if (!location.startsWith('file://')) { throw new Error('fileRequestService can only handle file URLs'); } } return { getContent(location: string, encoding?: BufferEncoding) { ensureFileUri(location); return new Promise((c, e) => { const uri = Uri.parse(location); fs.readFile(uri.fsPath, encoding, (err, buf) => { if (err) { return e(err); } c(buf.toString()); }); }); }, stat(location: string) { ensureFileUri(location); return new Promise((c, e) => { const uri = Uri.parse(location); fs.stat(uri.fsPath, (err, stats) => { if (err) { if (err.code === 'ENOENT') { return c({ type: FileType.Unknown, ctime: -1, mtime: -1, size: -1 }); } else { return e(err); } } let type = FileType.Unknown; if (stats.isFile()) { type = FileType.File; } else if (stats.isDirectory()) { type = FileType.Directory; } else if (stats.isSymbolicLink()) { type = FileType.SymbolicLink; } c({ type, ctime: stats.ctime.getTime(), mtime: stats.mtime.getTime(), size: stats.size }); }); }); }, readDirectory(location: string) { ensureFileUri(location); return new Promise((c, e) => { const path = Uri.parse(location).fsPath; fs.readdir(path, { withFileTypes: true }, (err, children) => { if (err) { return e(err); } c(children.map(stat => { if (stat.isSymbolicLink()) { return [stat.name, FileType.SymbolicLink]; } else if (stat.isDirectory()) { return [stat.name, FileType.Directory]; } else if (stat.isFile()) { return [stat.name, FileType.File]; } else { return [stat.name, FileType.Unknown]; } })); }); }); } }; } ================================================ FILE: extensions/css-language-features/client/src/requests.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Uri, workspace } from 'vscode'; import { RequestType, BaseLanguageClient } from 'vscode-languageclient'; import { Runtime } from './cssClient'; export namespace FsContentRequest { export const type: RequestType<{ uri: string; encoding?: string }, string, any> = new RequestType('fs/content'); } export namespace FsStatRequest { export const type: RequestType = new RequestType('fs/stat'); } export namespace FsReadDirRequest { export const type: RequestType = new RequestType('fs/readDir'); } export function serveFileSystemRequests(client: BaseLanguageClient, runtime: Runtime) { client.onRequest(FsContentRequest.type, (param: { uri: string; encoding?: string }) => { const uri = Uri.parse(param.uri); if (uri.scheme === 'file' && runtime.fs) { return runtime.fs.getContent(param.uri); } return workspace.fs.readFile(uri).then(buffer => { return new runtime.TextDecoder(param.encoding).decode(buffer); }); }); client.onRequest(FsReadDirRequest.type, (uriString: string) => { const uri = Uri.parse(uriString); if (uri.scheme === 'file' && runtime.fs) { return runtime.fs.readDirectory(uriString); } return workspace.fs.readDirectory(uri); }); client.onRequest(FsStatRequest.type, (uriString: string) => { const uri = Uri.parse(uriString); if (uri.scheme === 'file' && runtime.fs) { return runtime.fs.stat(uriString); } return workspace.fs.stat(uri); }); } export enum FileType { /** * The file type is unknown. */ Unknown = 0, /** * A regular file. */ File = 1, /** * A directory. */ Directory = 2, /** * A symbolic link to a file. */ SymbolicLink = 64 } export interface FileStat { /** * The type of the file, e.g. is a regular file, a directory, or symbolic link * to a file. */ type: FileType; /** * The creation timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. */ ctime: number; /** * The modification timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. */ mtime: number; /** * The size in bytes. */ size: number; } export interface RequestService { getContent(uri: string, encoding?: string): Promise; stat(uri: string): Promise; readDirectory(uri: string): Promise<[string, FileType][]>; } ================================================ FILE: extensions/css-language-features/client/tsconfig.json ================================================ { "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./out", "lib": [ "webworker" ], "module": "Node16", }, "include": [ "src/**/*", "../../../src/vscode-dts/vscode.d.ts" ] } ================================================ FILE: extensions/css-language-features/extension-browser.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withBrowserDefaults = require('../shared.webpack.config').browser; const path = require('path'); module.exports = withBrowserDefaults({ context: path.join(__dirname, 'client'), entry: { extension: './src/browser/cssClientMain.ts' }, output: { filename: 'cssClientMain.js', path: path.join(__dirname, 'client', 'dist', 'browser') } }); ================================================ FILE: extensions/css-language-features/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withDefaults = require('../shared.webpack.config'); const path = require('path'); module.exports = withDefaults({ context: path.join(__dirname, 'client'), entry: { extension: './src/node/cssClientMain.ts', }, output: { filename: 'cssClientMain.js', path: path.join(__dirname, 'client', 'dist', 'node') } }); ================================================ FILE: extensions/css-language-features/package.json ================================================ { "name": "css-language-features", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.77.0" }, "icon": "icons/css.png", "activationEvents": [ "onLanguage:css", "onLanguage:less", "onLanguage:scss", "onCommand:_css.applyCodeAction" ], "main": "./client/out/node/cssClientMain", "browser": "./client/dist/browser/cssClientMain", "capabilities": { "virtualWorkspaces": true, "untrustedWorkspaces": { "supported": true } }, "scripts": { "compile": "npx gulp compile-extension:css-language-features-client compile-extension:css-language-features-server", "watch": "npx gulp watch-extension:css-language-features-client watch-extension:css-language-features-server", "test": "node ../../node_modules/mocha/bin/mocha", "install-client-next": "npm install vscode-languageclient@next" }, "categories": [ "Programming Languages" ], "contributes": { "configuration": [ { "order": 22, "id": "css", "title": "%css.title%", "properties": { "css.customData": { "type": "array", "markdownDescription": "%css.customData.desc%", "default": [], "items": { "type": "string" }, "scope": "resource" }, "css.completion.triggerPropertyValueCompletion": { "type": "boolean", "scope": "resource", "default": true, "description": "%css.completion.triggerPropertyValueCompletion.desc%" }, "css.completion.completePropertyWithSemicolon": { "type": "boolean", "scope": "resource", "default": true, "description": "%css.completion.completePropertyWithSemicolon.desc%" }, "css.validate": { "type": "boolean", "scope": "resource", "default": true, "description": "%css.validate.desc%" }, "css.hover.documentation": { "type": "boolean", "scope": "resource", "default": true, "description": "%css.hover.documentation%" }, "css.hover.references": { "type": "boolean", "scope": "resource", "default": true, "description": "%css.hover.references%" }, "css.lint.compatibleVendorPrefixes": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.compatibleVendorPrefixes.desc%" }, "css.lint.vendorPrefix": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%css.lint.vendorPrefix.desc%" }, "css.lint.duplicateProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.duplicateProperties.desc%" }, "css.lint.emptyRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%css.lint.emptyRules.desc%" }, "css.lint.importStatement": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.importStatement.desc%" }, "css.lint.boxModel": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%css.lint.boxModel.desc%" }, "css.lint.universalSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%css.lint.universalSelector.desc%" }, "css.lint.zeroUnits": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.zeroUnits.desc%" }, "css.lint.fontFaceProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%css.lint.fontFaceProperties.desc%" }, "css.lint.hexColorLength": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%css.lint.hexColorLength.desc%" }, "css.lint.argumentsInColorFunction": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%css.lint.argumentsInColorFunction.desc%" }, "css.lint.unknownProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%css.lint.unknownProperties.desc%" }, "css.lint.validProperties": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "scope": "resource", "default": [], "description": "%css.lint.validProperties.desc%" }, "css.lint.ieHack": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.ieHack.desc%" }, "css.lint.unknownVendorSpecificProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.unknownVendorSpecificProperties.desc%" }, "css.lint.propertyIgnoredDueToDisplay": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%css.lint.propertyIgnoredDueToDisplay.desc%" }, "css.lint.important": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%css.lint.important.desc%" }, "css.lint.float": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%css.lint.float.desc%" }, "css.lint.idSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%css.lint.idSelector.desc%" }, "css.lint.unknownAtRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%css.lint.unknownAtRules.desc%" }, "css.trace.server": { "type": "string", "scope": "window", "enum": [ "off", "messages", "verbose" ], "default": "off", "description": "%css.trace.server.desc%" }, "css.format.enable": { "type": "boolean", "scope": "window", "default": true, "description": "%css.format.enable.desc%" }, "css.format.newlineBetweenSelectors": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%css.format.newlineBetweenSelectors.desc%" }, "css.format.newlineBetweenRules": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%css.format.newlineBetweenRules.desc%" }, "css.format.spaceAroundSelectorSeparator": { "type": "boolean", "scope": "resource", "default": false, "markdownDescription": "%css.format.spaceAroundSelectorSeparator.desc%" }, "css.format.braceStyle": { "type": "string", "scope": "resource", "default": "collapse", "enum": [ "collapse", "expand" ], "markdownDescription": "%css.format.braceStyle.desc%" }, "css.format.preserveNewLines": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%css.format.preserveNewLines.desc%" }, "css.format.maxPreserveNewLines": { "type": [ "number", "null" ], "scope": "resource", "default": null, "markdownDescription": "%css.format.maxPreserveNewLines.desc%" } } }, { "id": "scss", "order": 24, "title": "%scss.title%", "properties": { "scss.completion.triggerPropertyValueCompletion": { "type": "boolean", "scope": "resource", "default": true, "description": "%scss.completion.triggerPropertyValueCompletion.desc%" }, "scss.completion.completePropertyWithSemicolon": { "type": "boolean", "scope": "resource", "default": true, "description": "%scss.completion.completePropertyWithSemicolon.desc%" }, "scss.validate": { "type": "boolean", "scope": "resource", "default": true, "description": "%scss.validate.desc%" }, "scss.hover.documentation": { "type": "boolean", "scope": "resource", "default": true, "description": "%scss.hover.documentation%" }, "scss.hover.references": { "type": "boolean", "scope": "resource", "default": true, "description": "%scss.hover.references%" }, "scss.lint.compatibleVendorPrefixes": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.compatibleVendorPrefixes.desc%" }, "scss.lint.vendorPrefix": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%scss.lint.vendorPrefix.desc%" }, "scss.lint.duplicateProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.duplicateProperties.desc%" }, "scss.lint.emptyRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%scss.lint.emptyRules.desc%" }, "scss.lint.importStatement": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.importStatement.desc%" }, "scss.lint.boxModel": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%scss.lint.boxModel.desc%" }, "scss.lint.universalSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%scss.lint.universalSelector.desc%" }, "scss.lint.zeroUnits": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.zeroUnits.desc%" }, "scss.lint.fontFaceProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%scss.lint.fontFaceProperties.desc%" }, "scss.lint.hexColorLength": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%scss.lint.hexColorLength.desc%" }, "scss.lint.argumentsInColorFunction": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%scss.lint.argumentsInColorFunction.desc%" }, "scss.lint.unknownProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%scss.lint.unknownProperties.desc%" }, "scss.lint.validProperties": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "scope": "resource", "default": [], "description": "%scss.lint.validProperties.desc%" }, "scss.lint.ieHack": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.ieHack.desc%" }, "scss.lint.unknownVendorSpecificProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.unknownVendorSpecificProperties.desc%" }, "scss.lint.propertyIgnoredDueToDisplay": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%scss.lint.propertyIgnoredDueToDisplay.desc%" }, "scss.lint.important": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%scss.lint.important.desc%" }, "scss.lint.float": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%scss.lint.float.desc%" }, "scss.lint.idSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%scss.lint.idSelector.desc%" }, "scss.lint.unknownAtRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%scss.lint.unknownAtRules.desc%" }, "scss.format.enable": { "type": "boolean", "scope": "window", "default": true, "description": "%scss.format.enable.desc%" }, "scss.format.newlineBetweenSelectors": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%scss.format.newlineBetweenSelectors.desc%" }, "scss.format.newlineBetweenRules": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%scss.format.newlineBetweenRules.desc%" }, "scss.format.spaceAroundSelectorSeparator": { "type": "boolean", "scope": "resource", "default": false, "markdownDescription": "%scss.format.spaceAroundSelectorSeparator.desc%" }, "scss.format.braceStyle": { "type": "string", "scope": "resource", "default": "collapse", "enum": [ "collapse", "expand" ], "markdownDescription": "%scss.format.braceStyle.desc%" }, "scss.format.preserveNewLines": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%scss.format.preserveNewLines.desc%" }, "scss.format.maxPreserveNewLines": { "type": [ "number", "null" ], "scope": "resource", "default": null, "markdownDescription": "%scss.format.maxPreserveNewLines.desc%" } } }, { "id": "less", "order": 23, "type": "object", "title": "%less.title%", "properties": { "less.completion.triggerPropertyValueCompletion": { "type": "boolean", "scope": "resource", "default": true, "description": "%less.completion.triggerPropertyValueCompletion.desc%" }, "less.completion.completePropertyWithSemicolon": { "type": "boolean", "scope": "resource", "default": true, "description": "%less.completion.completePropertyWithSemicolon.desc%" }, "less.validate": { "type": "boolean", "scope": "resource", "default": true, "description": "%less.validate.desc%" }, "less.hover.documentation": { "type": "boolean", "scope": "resource", "default": true, "description": "%less.hover.documentation%" }, "less.hover.references": { "type": "boolean", "scope": "resource", "default": true, "description": "%less.hover.references%" }, "less.lint.compatibleVendorPrefixes": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.compatibleVendorPrefixes.desc%" }, "less.lint.vendorPrefix": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%less.lint.vendorPrefix.desc%" }, "less.lint.duplicateProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.duplicateProperties.desc%" }, "less.lint.emptyRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%less.lint.emptyRules.desc%" }, "less.lint.importStatement": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.importStatement.desc%" }, "less.lint.boxModel": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%less.lint.boxModel.desc%" }, "less.lint.universalSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%less.lint.universalSelector.desc%" }, "less.lint.zeroUnits": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.zeroUnits.desc%" }, "less.lint.fontFaceProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%less.lint.fontFaceProperties.desc%" }, "less.lint.hexColorLength": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%less.lint.hexColorLength.desc%" }, "less.lint.argumentsInColorFunction": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "error", "description": "%less.lint.argumentsInColorFunction.desc%" }, "less.lint.unknownProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%less.lint.unknownProperties.desc%" }, "less.lint.validProperties": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "scope": "resource", "default": [], "description": "%less.lint.validProperties.desc%" }, "less.lint.ieHack": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.ieHack.desc%" }, "less.lint.unknownVendorSpecificProperties": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.unknownVendorSpecificProperties.desc%" }, "less.lint.propertyIgnoredDueToDisplay": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "markdownDescription": "%less.lint.propertyIgnoredDueToDisplay.desc%" }, "less.lint.important": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%less.lint.important.desc%" }, "less.lint.float": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "markdownDescription": "%less.lint.float.desc%" }, "less.lint.idSelector": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "ignore", "description": "%less.lint.idSelector.desc%" }, "less.lint.unknownAtRules": { "type": "string", "scope": "resource", "enum": [ "ignore", "warning", "error" ], "default": "warning", "description": "%less.lint.unknownAtRules.desc%" }, "less.format.enable": { "type": "boolean", "scope": "window", "default": true, "description": "%less.format.enable.desc%" }, "less.format.newlineBetweenSelectors": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%less.format.newlineBetweenSelectors.desc%" }, "less.format.newlineBetweenRules": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%less.format.newlineBetweenRules.desc%" }, "less.format.spaceAroundSelectorSeparator": { "type": "boolean", "scope": "resource", "default": false, "markdownDescription": "%less.format.spaceAroundSelectorSeparator.desc%" }, "less.format.braceStyle": { "type": "string", "scope": "resource", "default": "collapse", "enum": [ "collapse", "expand" ], "markdownDescription": "%less.format.braceStyle.desc%" }, "less.format.preserveNewLines": { "type": "boolean", "scope": "resource", "default": true, "markdownDescription": "%less.format.preserveNewLines.desc%" }, "less.format.maxPreserveNewLines": { "type": [ "number", "null" ], "scope": "resource", "default": null, "markdownDescription": "%less.format.maxPreserveNewLines.desc%" } } } ], "configurationDefaults": { "[css]": { "editor.suggest.insertMode": "replace" }, "[scss]": { "editor.suggest.insertMode": "replace" }, "[less]": { "editor.suggest.insertMode": "replace" } }, "jsonValidation": [ { "fileMatch": "*.css-data.json", "url": "https://raw.githubusercontent.com/microsoft/vscode-css-languageservice/master/docs/customData.schema.json" }, { "fileMatch": "package.json", "url": "./schemas/package.schema.json" } ] }, "dependencies": { "vscode-languageclient": "^10.0.0-next.14", "vscode-uri": "^3.0.8" }, "devDependencies": { "@types/node": "20.x" }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/css-language-features/package.nls.json ================================================ { "displayName": "CSS Language Features", "description": "Provides rich language support for CSS, LESS and SCSS files.", "css.title": "CSS", "css.customData.desc": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/microsoft/vscode-css-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its CSS support for CSS custom properties (variables), at-rules, pseudo-classes, and pseudo-elements you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.", "css.completion.triggerPropertyValueCompletion.desc": "By default, VS Code triggers property value completion after selecting a CSS property. Use this setting to disable this behavior.", "css.completion.completePropertyWithSemicolon.desc": "Insert semicolon at end of line when completing CSS properties.", "css.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", "css.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", "css.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", "css.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", "css.lint.emptyRules.desc": "Do not use empty rulesets.", "css.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", "css.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", "css.lint.hexColorLength.desc": "Hex colors must consist of 3, 4, 6 or 8 hex numbers.", "css.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "css.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "css.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", "css.lint.importStatement.desc": "Import statements do not load in parallel.", "css.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", "css.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "css.lint.unknownAtRules.desc": "Unknown at-rule.", "css.lint.unknownProperties.desc": "Unknown property.", "css.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.", "css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", "css.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "css.lint.zeroUnits.desc": "No unit for zero needed.", "css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.", "css.validate.title": "Controls CSS validation and problem severities.", "css.validate.desc": "Enables or disables all validations.", "css.hover.documentation": "Show property and value documentation in CSS hovers.", "css.hover.references": "Show references to MDN in CSS hovers.", "css.format.enable.desc": "Enable/disable default CSS formatter.", "css.format.newlineBetweenSelectors.desc": "Separate selectors with a new line.", "css.format.newlineBetweenRules.desc": "Separate rulesets by a blank line.", "css.format.spaceAroundSelectorSeparator.desc": "Ensure a space character around selector separators '>', '+', '~' (e.g. `a > b`).", "css.format.braceStyle.desc": "Put braces on the same line as rules (`collapse`) or put braces on own line (`expand`).", "css.format.preserveNewLines.desc": "Whether existing line breaks before rules and declarations should be preserved.", "css.format.maxPreserveNewLines.desc": "Maximum number of line breaks to be preserved in one chunk, when `#css.format.preserveNewLines#` is enabled.", "less.title": "LESS", "less.completion.triggerPropertyValueCompletion.desc": "By default, VS Code triggers property value completion after selecting a CSS property. Use this setting to disable this behavior.", "less.completion.completePropertyWithSemicolon.desc": "Insert semicolon at end of line when completing CSS properties.", "less.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", "less.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", "less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", "less.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", "less.lint.emptyRules.desc": "Do not use empty rulesets.", "less.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", "less.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", "less.lint.hexColorLength.desc": "Hex colors must consist of 3, 4, 6 or 8 hex numbers.", "less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "less.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "less.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", "less.lint.importStatement.desc": "Import statements do not load in parallel.", "less.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", "less.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "less.lint.unknownAtRules.desc": "Unknown at-rule.", "less.lint.unknownProperties.desc": "Unknown property.", "less.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.", "less.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", "less.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "less.lint.zeroUnits.desc": "No unit for zero needed.", "less.validate.title": "Controls LESS validation and problem severities.", "less.validate.desc": "Enables or disables all validations.", "less.hover.documentation": "Show property and value documentation in LESS hovers.", "less.hover.references": "Show references to MDN in LESS hovers.", "less.format.enable.desc": "Enable/disable default LESS formatter.", "less.format.newlineBetweenSelectors.desc": "Separate selectors with a new line.", "less.format.newlineBetweenRules.desc": "Separate rulesets by a blank line.", "less.format.spaceAroundSelectorSeparator.desc": "Ensure a space character around selector separators '>', '+', '~' (e.g. `a > b`).", "less.format.braceStyle.desc": "Put braces on the same line as rules (`collapse`) or put braces on own line (`expand`).", "less.format.preserveNewLines.desc": "Whether existing line breaks before rules and declarations should be preserved.", "less.format.maxPreserveNewLines.desc": "Maximum number of line breaks to be preserved in one chunk, when `#less.format.preserveNewLines#` is enabled.", "scss.title": "SCSS (Sass)", "scss.completion.triggerPropertyValueCompletion.desc": "By default, VS Code triggers property value completion after selecting a CSS property. Use this setting to disable this behavior.", "scss.completion.completePropertyWithSemicolon.desc": "Insert semicolon at end of line when completing CSS properties.", "scss.lint.argumentsInColorFunction.desc": "Invalid number of parameters.", "scss.lint.boxModel.desc": "Do not use `width` or `height` when using `padding` or `border`.", "scss.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties.", "scss.lint.duplicateProperties.desc": "Do not use duplicate style definitions.", "scss.lint.emptyRules.desc": "Do not use empty rulesets.", "scss.lint.float.desc": "Avoid using `float`. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.", "scss.lint.fontFaceProperties.desc": "`@font-face` rule must define `src` and `font-family` properties.", "scss.lint.hexColorLength.desc": "Hex colors must consist of 3, 4, 6 or 8 hex numbers.", "scss.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.", "scss.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.", "scss.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.", "scss.lint.importStatement.desc": "Import statements do not load in parallel.", "scss.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.", "scss.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.", "scss.lint.unknownAtRules.desc": "Unknown at-rule.", "scss.lint.unknownProperties.desc": "Unknown property.", "scss.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.", "scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.", "scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.", "scss.lint.zeroUnits.desc": "No unit for zero needed.", "scss.validate.title": "Controls SCSS validation and problem severities.", "scss.validate.desc": "Enables or disables all validations.", "scss.hover.documentation": "Show property and value documentation in SCSS hovers.", "scss.hover.references": "Show references to MDN in SCSS hovers.", "scss.format.enable.desc": "Enable/disable default SCSS formatter.", "scss.format.newlineBetweenSelectors.desc": "Separate selectors with a new line.", "scss.format.newlineBetweenRules.desc": "Separate rulesets by a blank line.", "scss.format.spaceAroundSelectorSeparator.desc": "Ensure a space character around selector separators '>', '+', '~' (e.g. `a > b`).", "scss.format.braceStyle.desc": "Put braces on the same line as rules (`collapse`) or put braces on own line (`expand`).", "scss.format.preserveNewLines.desc": "Whether existing line breaks before rules and declarations should be preserved.", "scss.format.maxPreserveNewLines.desc": "Maximum number of line breaks to be preserved in one chunk, when `#scss.format.preserveNewLines#` is enabled.", "css.colorDecorators.enable.deprecationMessage": "The setting `css.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.", "scss.colorDecorators.enable.deprecationMessage": "The setting `scss.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.", "less.colorDecorators.enable.deprecationMessage": "The setting `less.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`." } ================================================ FILE: extensions/css-language-features/schemas/package.schema.json ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "contributes": { "type": "object", "properties": { "css.customData": { "type": "array", "markdownDescription": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/microsoft/vscode-css-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its CSS support for the custom CSS properties, at directives, pseudo classes and pseudo elements you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.", "items": { "type": "string", "description": "Relative path to a CSS custom data file" } } } } } } ================================================ FILE: extensions/css-language-features/server/.npmrc ================================================ legacy-peer-deps="true" timeout=180000 ================================================ FILE: extensions/css-language-features/server/.vscode/launch.json ================================================ { "version": "0.1.0", // List of configurations. Add new configurations or edit existing ones. "configurations": [ { "name": "Attach", "type": "node", "request": "attach", "port": 6044, "protocol": "inspector", "sourceMaps": true, "outFiles": ["${workspaceFolder}/out/**/*.js"] }, { "name": "Unit Tests", "type": "node", "request": "launch", "program": "${workspaceFolder}/../../../node_modules/mocha/bin/_mocha", "stopOnEntry": false, "args": [ "--timeout", "999999", "--colors" ], "cwd": "${workspaceFolder}", "runtimeExecutable": null, "runtimeArgs": [], "env": {}, "sourceMaps": true, "outFiles": ["${workspaceFolder}/out/**/*.js"] } ] } ================================================ FILE: extensions/css-language-features/server/.vscode/tasks.json ================================================ { "version": "0.1.0", "command": "npm", "isShellCommand": true, "showOutput": "silent", "args": ["run", "watch"], "isWatching": true, "problemMatcher": "$tsc-watch" } ================================================ FILE: extensions/css-language-features/server/extension-browser.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withBrowserDefaults = require('../../shared.webpack.config').browser; const path = require('path'); module.exports = withBrowserDefaults({ context: __dirname, entry: { extension: './src/browser/cssServerWorkerMain.ts', }, output: { filename: 'cssServerMain.js', path: path.join(__dirname, 'dist', 'browser'), libraryTarget: 'var', library: 'serverExportVar' } }); ================================================ FILE: extensions/css-language-features/server/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withDefaults = require('../../shared.webpack.config'); const path = require('path'); module.exports = withDefaults({ context: path.join(__dirname), entry: { extension: './src/node/cssServerNodeMain.ts', }, output: { filename: 'cssServerMain.js', path: path.join(__dirname, 'dist', 'node'), } }); ================================================ FILE: extensions/css-language-features/server/package.json ================================================ { "name": "vscode-css-languageserver", "description": "CSS/LESS/SCSS language server", "version": "1.0.0", "author": "Microsoft Corporation", "license": "MIT", "engines": { "node": "*" }, "main": "./out/node/cssServerMain", "browser": "./dist/browser/cssServerMain", "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-css-languageservice": "^6.3.3", "vscode-languageserver": "^10.0.0-next.11", "vscode-uri": "^3.0.8" }, "devDependencies": { "@types/mocha": "^9.1.1", "@types/node": "20.x" }, "scripts": { "compile": "gulp compile-extension:css-language-features-server", "watch": "gulp watch-extension:css-language-features-server", "install-service-next": "npm install vscode-css-languageservice", "install-service-local": "npm link vscode-css-languageservice", "install-server-next": "npm install vscode-languageserver@next", "install-server-local": "npm install vscode-languageserver", "test": "node ./test/index.js" } } ================================================ FILE: extensions/css-language-features/server/src/browser/cssServerMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { createConnection, BrowserMessageReader, BrowserMessageWriter, Disposable } from 'vscode-languageserver/browser'; import { RuntimeEnvironment, startServer } from '../cssServer'; const messageReader = new BrowserMessageReader(self); const messageWriter = new BrowserMessageWriter(self); const connection = createConnection(messageReader, messageWriter); console.log = connection.console.log.bind(connection.console); console.error = connection.console.error.bind(connection.console); const runtime: RuntimeEnvironment = { timer: { setImmediate(callback: (...args: any[]) => void, ...args: any[]): Disposable { const handle = setTimeout(callback, 0, ...args); return { dispose: () => clearTimeout(handle) }; }, setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): Disposable { const handle = setTimeout(callback, ms, ...args); return { dispose: () => clearTimeout(handle) }; } } }; startServer(connection, runtime); ================================================ FILE: extensions/css-language-features/server/src/browser/cssServerWorkerMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as l10n from '@vscode/l10n'; let initialized = false; const pendingMessages: any[] = []; const messageHandler = async (e: any) => { if (!initialized) { const l10nLog: string[] = []; initialized = true; const i10lLocation = e.data.i10lLocation; if (i10lLocation) { try { await l10n.config({ uri: i10lLocation }); l10nLog.push(`l10n: Configured to ${i10lLocation.toString()}.`); } catch (e) { l10nLog.push(`l10n: Problems loading ${i10lLocation.toString()} : ${e}.`); } } else { l10nLog.push(`l10n: No bundle configured.`); } await import('./cssServerMain.js'); if (self.onmessage !== messageHandler) { pendingMessages.forEach(msg => self.onmessage?.(msg)); pendingMessages.length = 0; } l10nLog.forEach(console.log); } else { pendingMessages.push(e); } }; self.onmessage = messageHandler; ================================================ FILE: extensions/css-language-features/server/src/cssServer.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Connection, TextDocuments, InitializeParams, InitializeResult, ServerCapabilities, ConfigurationRequest, WorkspaceFolder, TextDocumentSyncKind, NotificationType, Disposable, TextDocumentIdentifier, Range, FormattingOptions, TextEdit, Diagnostic } from 'vscode-languageserver'; import { URI } from 'vscode-uri'; import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet, TextDocument, Position } from 'vscode-css-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { runSafeAsync } from './utils/runner'; import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation'; import { getDocumentContext } from './utils/documentContext'; import { fetchDataProviders } from './customData'; import { RequestService, getRequestService } from './requests'; namespace CustomDataChangedNotification { export const type: NotificationType = new NotificationType('css/customDataChanged'); } export interface Settings { css: LanguageSettings; less: LanguageSettings; scss: LanguageSettings; } export interface RuntimeEnvironment { readonly file?: RequestService; readonly http?: RequestService; readonly timer: { setImmediate(callback: (...args: any[]) => void, ...args: any[]): Disposable; setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): Disposable; }; } export function startServer(connection: Connection, runtime: RuntimeEnvironment) { // Create a text document manager. const documents = new TextDocuments(TextDocument); // Make the text document manager listen on the connection // for open, change and close text document events documents.listen(connection); const stylesheets = getLanguageModelCache(10, 60, document => getLanguageService(document).parseStylesheet(document)); documents.onDidClose(e => { stylesheets.onDocumentRemoved(e.document); }); connection.onShutdown(() => { stylesheets.dispose(); }); let scopedSettingsSupport = false; let foldingRangeLimit = Number.MAX_VALUE; let workspaceFolders: WorkspaceFolder[]; let formatterMaxNumberOfEdits = Number.MAX_VALUE; let dataProvidersReady: Promise = Promise.resolve(); let diagnosticsSupport: DiagnosticsSupport | undefined; const languageServices: { [id: string]: LanguageService } = {}; const notReady = () => Promise.reject('Not Ready'); let requestService: RequestService = { getContent: notReady, stat: notReady, readDirectory: notReady }; // After the server has started the client sends an initialize request. The server receives // in the passed params the rootPath of the workspace plus the client capabilities. connection.onInitialize((params: InitializeParams): InitializeResult => { const initializationOptions = params.initializationOptions as any || {}; workspaceFolders = (params).workspaceFolders; if (!Array.isArray(workspaceFolders)) { workspaceFolders = []; if (params.rootPath) { workspaceFolders.push({ name: '', uri: URI.file(params.rootPath).toString(true) }); } } requestService = getRequestService(initializationOptions?.handledSchemas || ['file'], connection, runtime); function getClientCapability(name: string, def: T) { const keys = name.split('.'); let c: any = params.capabilities; for (let i = 0; c && i < keys.length; i++) { if (!c.hasOwnProperty(keys[i])) { return def; } c = c[keys[i]]; } return c; } const snippetSupport = !!getClientCapability('textDocument.completion.completionItem.snippetSupport', false); scopedSettingsSupport = !!getClientCapability('workspace.configuration', false); foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); formatterMaxNumberOfEdits = initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE; languageServices.css = getCSSLanguageService({ fileSystemProvider: requestService, clientCapabilities: params.capabilities }); languageServices.scss = getSCSSLanguageService({ fileSystemProvider: requestService, clientCapabilities: params.capabilities }); languageServices.less = getLESSLanguageService({ fileSystemProvider: requestService, clientCapabilities: params.capabilities }); const supportsDiagnosticPull = getClientCapability('textDocument.diagnostic', undefined); if (supportsDiagnosticPull === undefined) { diagnosticsSupport = registerDiagnosticsPushSupport(documents, connection, runtime, validateTextDocument); } else { diagnosticsSupport = registerDiagnosticsPullSupport(documents, connection, runtime, validateTextDocument); } const capabilities: ServerCapabilities = { textDocumentSync: TextDocumentSyncKind.Incremental, completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/', '-', ':'] } : undefined, hoverProvider: true, documentSymbolProvider: true, referencesProvider: true, definitionProvider: true, documentHighlightProvider: true, documentLinkProvider: { resolveProvider: false }, codeActionProvider: true, renameProvider: true, colorProvider: {}, foldingRangeProvider: true, selectionRangeProvider: true, diagnosticProvider: { documentSelector: null, interFileDependencies: false, workspaceDiagnostics: false }, documentRangeFormattingProvider: initializationOptions?.provideFormatter === true, documentFormattingProvider: initializationOptions?.provideFormatter === true, }; return { capabilities }; }); function getLanguageService(document: TextDocument) { let service = languageServices[document.languageId]; if (!service) { connection.console.log('Document type is ' + document.languageId + ', using css instead.'); service = languageServices['css']; } return service; } let documentSettings: { [key: string]: Thenable } = {}; // remove document settings on close documents.onDidClose(e => { delete documentSettings[e.document.uri]; }); function getDocumentSettings(textDocument: TextDocument): Thenable { if (scopedSettingsSupport) { let promise = documentSettings[textDocument.uri]; if (!promise) { const configRequestParam = { items: [{ scopeUri: textDocument.uri, section: textDocument.languageId }] }; promise = connection.sendRequest(ConfigurationRequest.type, configRequestParam).then(s => s[0] as LanguageSettings | undefined); documentSettings[textDocument.uri] = promise; } return promise; } return Promise.resolve(undefined); } // The settings have changed. Is send on server activation as well. connection.onDidChangeConfiguration(change => { updateConfiguration(change.settings as any); }); function updateConfiguration(settings: any) { for (const languageId in languageServices) { languageServices[languageId].configure(settings[languageId]); } // reset all document settings documentSettings = {}; diagnosticsSupport?.requestRefresh(); } async function validateTextDocument(textDocument: TextDocument): Promise { const settingsPromise = getDocumentSettings(textDocument); const [settings] = await Promise.all([settingsPromise, dataProvidersReady]); const stylesheet = stylesheets.get(textDocument); return getLanguageService(textDocument).doValidation(textDocument, stylesheet, settings); } function updateDataProviders(dataPaths: string[]) { dataProvidersReady = fetchDataProviders(dataPaths, requestService).then(customDataProviders => { for (const lang in languageServices) { languageServices[lang].setDataProviders(true, customDataProviders); } }); } connection.onCompletion((textDocumentPosition, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(textDocumentPosition.textDocument.uri); if (document) { const [settings,] = await Promise.all([getDocumentSettings(document), dataProvidersReady]); const styleSheet = stylesheets.get(document); const documentContext = getDocumentContext(document.uri, workspaceFolders); return getLanguageService(document).doComplete2(document, textDocumentPosition.position, styleSheet, documentContext, settings?.completion); } return null; }, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token); }); connection.onHover((textDocumentPosition, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(textDocumentPosition.textDocument.uri); if (document) { const [settings,] = await Promise.all([getDocumentSettings(document), dataProvidersReady]); const styleSheet = stylesheets.get(document); return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet, settings?.hover); } return null; }, null, `Error while computing hover for ${textDocumentPosition.textDocument.uri}`, token); }); connection.onDocumentSymbol((documentSymbolParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(documentSymbolParams.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).findDocumentSymbols2(document, stylesheet); } return []; }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); }); connection.onDefinition((documentDefinitionParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(documentDefinitionParams.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).findDefinition(document, documentDefinitionParams.position, stylesheet); } return null; }, null, `Error while computing definitions for ${documentDefinitionParams.textDocument.uri}`, token); }); connection.onDocumentHighlight((documentHighlightParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(documentHighlightParams.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).findDocumentHighlights(document, documentHighlightParams.position, stylesheet); } return []; }, [], `Error while computing document highlights for ${documentHighlightParams.textDocument.uri}`, token); }); connection.onDocumentLinks(async (documentLinkParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(documentLinkParams.textDocument.uri); if (document) { await dataProvidersReady; const documentContext = getDocumentContext(document.uri, workspaceFolders); const stylesheet = stylesheets.get(document); return getLanguageService(document).findDocumentLinks2(document, stylesheet, documentContext); } return []; }, [], `Error while computing document links for ${documentLinkParams.textDocument.uri}`, token); }); connection.onReferences((referenceParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(referenceParams.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).findReferences(document, referenceParams.position, stylesheet); } return []; }, [], `Error while computing references for ${referenceParams.textDocument.uri}`, token); }); connection.onCodeAction((codeActionParams, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(codeActionParams.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).doCodeActions(document, codeActionParams.range, codeActionParams.context, stylesheet); } return []; }, [], `Error while computing code actions for ${codeActionParams.textDocument.uri}`, token); }); connection.onDocumentColor((params, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).findDocumentColors(document, stylesheet); } return []; }, [], `Error while computing document colors for ${params.textDocument.uri}`, token); }); connection.onColorPresentation((params, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).getColorPresentations(document, stylesheet, params.color, params.range); } return []; }, [], `Error while computing color presentations for ${params.textDocument.uri}`, token); }); connection.onRenameRequest((renameParameters, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(renameParameters.textDocument.uri); if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).doRename(document, renameParameters.position, renameParameters.newName, stylesheet); } return null; }, null, `Error while computing renames for ${renameParameters.textDocument.uri}`, token); }); connection.onFoldingRanges((params, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); if (document) { await dataProvidersReady; return getLanguageService(document).getFoldingRanges(document, { rangeLimit: foldingRangeLimit }); } return null; }, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token); }); connection.onSelectionRanges((params, token) => { return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); const positions: Position[] = params.positions; if (document) { await dataProvidersReady; const stylesheet = stylesheets.get(document); return getLanguageService(document).getSelectionRanges(document, positions, stylesheet); } return []; }, [], `Error while computing selection ranges for ${params.textDocument.uri}`, token); }); async function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): Promise { const document = documents.get(textDocument.uri); if (document) { const edits = getLanguageService(document).format(document, range ?? getFullRange(document), options); if (edits.length > formatterMaxNumberOfEdits) { const newText = TextDocument.applyEdits(document, edits); return [TextEdit.replace(getFullRange(document), newText)]; } return edits; } return []; } connection.onDocumentRangeFormatting((formatParams, token) => { return runSafeAsync(runtime, () => onFormat(formatParams.textDocument, formatParams.range, formatParams.options), [], `Error while formatting range for ${formatParams.textDocument.uri}`, token); }); connection.onDocumentFormatting((formatParams, token) => { return runSafeAsync(runtime, () => onFormat(formatParams.textDocument, undefined, formatParams.options), [], `Error while formatting ${formatParams.textDocument.uri}`, token); }); connection.onNotification(CustomDataChangedNotification.type, updateDataProviders); // Listen on the connection connection.listen(); } function getFullRange(document: TextDocument): Range { return Range.create(Position.create(0, 0), document.positionAt(document.getText().length)); } ================================================ FILE: extensions/css-language-features/server/src/customData.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ICSSDataProvider, newCSSDataProvider } from 'vscode-css-languageservice'; import { RequestService } from './requests'; export function fetchDataProviders(dataPaths: string[], requestService: RequestService): Promise { const providers = dataPaths.map(async p => { try { const content = await requestService.getContent(p); return parseCSSData(content); } catch (e) { return newCSSDataProvider({ version: 1 }); } }); return Promise.all(providers); } function parseCSSData(source: string): ICSSDataProvider { let rawData: any; try { rawData = JSON.parse(source); } catch (err) { return newCSSDataProvider({ version: 1 }); } return newCSSDataProvider({ version: rawData.version || 1, properties: rawData.properties || [], atDirectives: rawData.atDirectives || [], pseudoClasses: rawData.pseudoClasses || [], pseudoElements: rawData.pseudoElements || [] }); } ================================================ FILE: extensions/css-language-features/server/src/languageModelCache.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { TextDocument } from 'vscode-css-languageservice'; export interface LanguageModelCache { get(document: TextDocument): T; onDocumentRemoved(document: TextDocument): void; dispose(): void; } export function getLanguageModelCache(maxEntries: number, cleanupIntervalTimeInSec: number, parse: (document: TextDocument) => T): LanguageModelCache { let languageModels: { [uri: string]: { version: number; languageId: string; cTime: number; languageModel: T } } = {}; let nModels = 0; let cleanupInterval: NodeJS.Timeout | undefined = undefined; if (cleanupIntervalTimeInSec > 0) { cleanupInterval = setInterval(() => { const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; const uris = Object.keys(languageModels); for (const uri of uris) { const languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < cutoffTime) { delete languageModels[uri]; nModels--; } } }, cleanupIntervalTimeInSec * 1000); } return { get(document: TextDocument): T { const version = document.version; const languageId = document.languageId; const languageModelInfo = languageModels[document.uri]; if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) { languageModelInfo.cTime = Date.now(); return languageModelInfo.languageModel; } const languageModel = parse(document); languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() }; if (!languageModelInfo) { nModels++; } if (nModels === maxEntries) { let oldestTime = Number.MAX_VALUE; let oldestUri = null; for (const uri in languageModels) { const languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < oldestTime) { oldestUri = uri; oldestTime = languageModelInfo.cTime; } } if (oldestUri) { delete languageModels[oldestUri]; nModels--; } } return languageModel; }, onDocumentRemoved(document: TextDocument) { const uri = document.uri; if (languageModels[uri]) { delete languageModels[uri]; nModels--; } }, dispose() { if (typeof cleanupInterval !== 'undefined') { clearInterval(cleanupInterval); cleanupInterval = undefined; languageModels = {}; nModels = 0; } } }; } ================================================ FILE: extensions/css-language-features/server/src/node/cssServerMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { createConnection, Connection, Disposable } from 'vscode-languageserver/node'; import { formatError } from '../utils/runner'; import { RuntimeEnvironment, startServer } from '../cssServer'; import { getNodeFSRequestService } from './nodeFs'; // Create a connection for the server. const connection: Connection = createConnection(); console.log = connection.console.log.bind(connection.console); console.error = connection.console.error.bind(connection.console); process.on('unhandledRejection', (e: any) => { connection.console.error(formatError(`Unhandled exception`, e)); }); const runtime: RuntimeEnvironment = { timer: { setImmediate(callback: (...args: any[]) => void, ...args: any[]): Disposable { const handle = setImmediate(callback, ...args); return { dispose: () => clearImmediate(handle) }; }, setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): Disposable { const handle = setTimeout(callback, ms, ...args); return { dispose: () => clearTimeout(handle) }; } }, file: getNodeFSRequestService() }; startServer(connection, runtime); ================================================ FILE: extensions/css-language-features/server/src/node/cssServerNodeMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as l10n from '@vscode/l10n'; async function setupMain() { const l10nLog: string[] = []; const i10lLocation = process.env['VSCODE_L10N_BUNDLE_LOCATION']; if (i10lLocation) { try { await l10n.config({ uri: i10lLocation }); l10nLog.push(`l10n: Configured to ${i10lLocation.toString()}`); } catch (e) { l10nLog.push(`l10n: Problems loading ${i10lLocation.toString()} : ${e}`); } } await import('./cssServerMain.js'); l10nLog.forEach(console.log); } setupMain(); ================================================ FILE: extensions/css-language-features/server/src/node/nodeFs.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { RequestService } from '../requests'; import { URI as Uri } from 'vscode-uri'; import * as fs from 'fs'; import { FileType } from 'vscode-css-languageservice'; export function getNodeFSRequestService(): RequestService { function ensureFileUri(location: string) { if (!location.startsWith('file://')) { throw new Error('fileRequestService can only handle file URLs'); } } return { getContent(location: string, encoding?: BufferEncoding) { ensureFileUri(location); return new Promise((c, e) => { const uri = Uri.parse(location); fs.readFile(uri.fsPath, encoding, (err, buf) => { if (err) { return e(err); } c(buf.toString()); }); }); }, stat(location: string) { ensureFileUri(location); return new Promise((c, e) => { const uri = Uri.parse(location); fs.stat(uri.fsPath, (err, stats) => { if (err) { if (err.code === 'ENOENT') { return c({ type: FileType.Unknown, ctime: -1, mtime: -1, size: -1 }); } else { return e(err); } } let type = FileType.Unknown; if (stats.isFile()) { type = FileType.File; } else if (stats.isDirectory()) { type = FileType.Directory; } else if (stats.isSymbolicLink()) { type = FileType.SymbolicLink; } c({ type, ctime: stats.ctime.getTime(), mtime: stats.mtime.getTime(), size: stats.size }); }); }); }, readDirectory(location: string) { ensureFileUri(location); return new Promise((c, e) => { const path = Uri.parse(location).fsPath; fs.readdir(path, { withFileTypes: true }, (err, children) => { if (err) { return e(err); } c(children.map(stat => { if (stat.isSymbolicLink()) { return [stat.name, FileType.SymbolicLink]; } else if (stat.isDirectory()) { return [stat.name, FileType.Directory]; } else if (stat.isFile()) { return [stat.name, FileType.File]; } else { return [stat.name, FileType.Unknown]; } })); }); }); } }; } ================================================ FILE: extensions/css-language-features/server/src/requests.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { RequestType, Connection } from 'vscode-languageserver'; import { RuntimeEnvironment } from './cssServer'; export namespace FsContentRequest { export const type: RequestType<{ uri: string; encoding?: string }, string, any> = new RequestType('fs/content'); } export namespace FsStatRequest { export const type: RequestType = new RequestType('fs/stat'); } export namespace FsReadDirRequest { export const type: RequestType = new RequestType('fs/readDir'); } export enum FileType { /** * The file type is unknown. */ Unknown = 0, /** * A regular file. */ File = 1, /** * A directory. */ Directory = 2, /** * A symbolic link to a file. */ SymbolicLink = 64 } export interface FileStat { /** * The type of the file, e.g. is a regular file, a directory, or symbolic link * to a file. */ type: FileType; /** * The creation timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. */ ctime: number; /** * The modification timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. */ mtime: number; /** * The size in bytes. */ size: number; } export interface RequestService { getContent(uri: string, encoding?: string): Promise; stat(uri: string): Promise; readDirectory(uri: string): Promise<[string, FileType][]>; } export function getRequestService(handledSchemas: string[], connection: Connection, runtime: RuntimeEnvironment): RequestService { const builtInHandlers: { [protocol: string]: RequestService | undefined } = {}; for (const protocol of handledSchemas) { if (protocol === 'file') { builtInHandlers[protocol] = runtime.file; } else if (protocol === 'http' || protocol === 'https') { builtInHandlers[protocol] = runtime.http; } } return { async stat(uri: string): Promise { const handler = builtInHandlers[getScheme(uri)]; if (handler) { return handler.stat(uri); } const res = await connection.sendRequest(FsStatRequest.type, uri.toString()); return res; }, readDirectory(uri: string): Promise<[string, FileType][]> { const handler = builtInHandlers[getScheme(uri)]; if (handler) { return handler.readDirectory(uri); } return connection.sendRequest(FsReadDirRequest.type, uri.toString()); }, getContent(uri: string, encoding?: string): Promise { const handler = builtInHandlers[getScheme(uri)]; if (handler) { return handler.getContent(uri, encoding); } return connection.sendRequest(FsContentRequest.type, { uri: uri.toString(), encoding }); } }; } function getScheme(uri: string) { return uri.substr(0, uri.indexOf(':')); } ================================================ FILE: extensions/css-language-features/server/src/test/completion.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'mocha'; import * as assert from 'assert'; import * as path from 'path'; import { URI } from 'vscode-uri'; import { TextDocument, CompletionList, TextEdit } from 'vscode-languageserver-types'; import { WorkspaceFolder } from 'vscode-languageserver-protocol'; import { getCSSLanguageService, LanguageServiceOptions, getSCSSLanguageService } from 'vscode-css-languageservice'; import { getNodeFSRequestService } from '../node/nodeFs'; import { getDocumentContext } from '../utils/documentContext'; export interface ItemDescription { label: string; resultText?: string; } suite('Completions', () => { const assertCompletion = function (completions: CompletionList, expected: ItemDescription, document: TextDocument, _offset: number) { const matches = completions.items.filter(completion => { return completion.label === expected.label; }); assert.strictEqual(matches.length, 1, `${expected.label} should only existing once: Actual: ${completions.items.map(c => c.label).join(', ')}`); const match = matches[0]; if (expected.resultText && TextEdit.is(match.textEdit)) { assert.strictEqual(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText); } }; async function assertCompletions(value: string, expected: { count?: number; items?: ItemDescription[] }, testUri: string, workspaceFolders?: WorkspaceFolder[], lang: string = 'css'): Promise { const offset = value.indexOf('|'); value = value.substr(0, offset) + value.substr(offset + 1); const document = TextDocument.create(testUri, lang, 0, value); const position = document.positionAt(offset); if (!workspaceFolders) { workspaceFolders = [{ name: 'x', uri: testUri.substr(0, testUri.lastIndexOf('/')) }]; } const lsOptions: LanguageServiceOptions = { fileSystemProvider: getNodeFSRequestService() }; const cssLanguageService = lang === 'scss' ? getSCSSLanguageService(lsOptions) : getCSSLanguageService(lsOptions); const context = getDocumentContext(testUri, workspaceFolders); const stylesheet = cssLanguageService.parseStylesheet(document); const list = await cssLanguageService.doComplete2(document, position, stylesheet, context); if (expected.count) { assert.strictEqual(list.items.length, expected.count); } if (expected.items) { for (const item of expected.items) { assertCompletion(list, item, document, offset); } } } test('CSS url() Path completion', async function () { const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(true); const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString(true) }]; await assertCompletions('html { background-image: url("./|")', { items: [ { label: 'about.html', resultText: 'html { background-image: url("./about.html")' } ] }, testUri, folders); await assertCompletions(`html { background-image: url('../|')`, { items: [ { label: 'about/', resultText: `html { background-image: url('../about/')` }, { label: 'index.html', resultText: `html { background-image: url('../index.html')` }, { label: 'src/', resultText: `html { background-image: url('../src/')` } ] }, testUri, folders); await assertCompletions(`html { background-image: url('../src/a|')`, { items: [ { label: 'feature.js', resultText: `html { background-image: url('../src/feature.js')` }, { label: 'data/', resultText: `html { background-image: url('../src/data/')` }, { label: 'test.js', resultText: `html { background-image: url('../src/test.js')` } ] }, testUri, folders); await assertCompletions(`html { background-image: url('../src/data/f|.asar')`, { items: [ { label: 'foo.asar', resultText: `html { background-image: url('../src/data/foo.asar')` } ] }, testUri, folders); await assertCompletions(`html { background-image: url('|')`, { items: [ { label: 'about.html', resultText: `html { background-image: url('about.html')` }, ] }, testUri, folders); await assertCompletions(`html { background-image: url('/|')`, { items: [ { label: 'pathCompletionFixtures/', resultText: `html { background-image: url('/pathCompletionFixtures/')` } ] }, testUri, folders); await assertCompletions(`html { background-image: url('/pathCompletionFixtures/|')`, { items: [ { label: 'about/', resultText: `html { background-image: url('/pathCompletionFixtures/about/')` }, { label: 'index.html', resultText: `html { background-image: url('/pathCompletionFixtures/index.html')` }, { label: 'src/', resultText: `html { background-image: url('/pathCompletionFixtures/src/')` } ] }, testUri, folders); await assertCompletions(`html { background-image: url("/|")`, { items: [ { label: 'pathCompletionFixtures/', resultText: `html { background-image: url("/pathCompletionFixtures/")` } ] }, testUri, folders); }); test('CSS url() Path Completion - Unquoted url', async function () { const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(true); const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString(true) }]; await assertCompletions('html { background-image: url(./|)', { items: [ { label: 'about.html', resultText: 'html { background-image: url(./about.html)' } ] }, testUri, folders); await assertCompletions('html { background-image: url(./a|)', { items: [ { label: 'about.html', resultText: 'html { background-image: url(./about.html)' } ] }, testUri, folders); await assertCompletions('html { background-image: url(../|src/)', { items: [ { label: 'about/', resultText: 'html { background-image: url(../about/)' } ] }, testUri, folders); await assertCompletions('html { background-image: url(../s|rc/)', { items: [ { label: 'about/', resultText: 'html { background-image: url(../about/)' } ] }, testUri, folders); }); test('CSS @import Path completion', async function () { const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(true); const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString(true) }]; await assertCompletions(`@import './|'`, { items: [ { label: 'about.html', resultText: `@import './about.html'` }, ] }, testUri, folders); await assertCompletions(`@import '../|'`, { items: [ { label: 'about/', resultText: `@import '../about/'` }, { label: 'scss/', resultText: `@import '../scss/'` }, { label: 'index.html', resultText: `@import '../index.html'` }, { label: 'src/', resultText: `@import '../src/'` } ] }, testUri, folders); }); /** * For SCSS, `@import 'foo';` can be used for importing partial file `_foo.scss` */ test('SCSS @import Path completion', async function () { const testCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(true); const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString(true) }]; /** * We are in a CSS file, so no special treatment for SCSS partial files */ await assertCompletions(`@import '../scss/|'`, { items: [ { label: 'main.scss', resultText: `@import '../scss/main.scss'` }, { label: '_foo.scss', resultText: `@import '../scss/_foo.scss'` } ] }, testCSSUri, folders); const testSCSSUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/scss/main.scss')).toString(true); await assertCompletions(`@import './|'`, { items: [ { label: '_foo.scss', resultText: `@import './foo'` } ] }, testSCSSUri, folders, 'scss'); }); test('Completion should ignore files/folders starting with dot', async function () { const testUri = URI.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/about/about.css')).toString(true); const folders = [{ name: 'x', uri: URI.file(path.resolve(__dirname, '../../test')).toString(true) }]; await assertCompletions('html { background-image: url("../|")', { count: 4 }, testUri, folders); }); }); ================================================ FILE: extensions/css-language-features/server/src/test/links.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'mocha'; import * as assert from 'assert'; import { URI } from 'vscode-uri'; import { resolve } from 'path'; import { TextDocument, DocumentLink } from 'vscode-languageserver-types'; import { WorkspaceFolder } from 'vscode-languageserver-protocol'; import { getCSSLanguageService } from 'vscode-css-languageservice'; import { getDocumentContext } from '../utils/documentContext'; import { getNodeFSRequestService } from '../node/nodeFs'; export interface ItemDescription { offset: number; value: string; target: string; } suite('Links', () => { const cssLanguageService = getCSSLanguageService({ fileSystemProvider: getNodeFSRequestService() }); const assertLink = function (links: DocumentLink[], expected: ItemDescription, document: TextDocument) { const matches = links.filter(link => { return document.offsetAt(link.range.start) === expected.offset; }); assert.strictEqual(matches.length, 1, `${expected.offset} should only existing once: Actual: ${links.map(l => document.offsetAt(l.range.start)).join(', ')}`); const match = matches[0]; assert.strictEqual(document.getText(match.range), expected.value); assert.strictEqual(match.target, expected.target); }; async function assertLinks(value: string, expected: ItemDescription[], testUri: string, workspaceFolders?: WorkspaceFolder[], lang: string = 'css'): Promise { const offset = value.indexOf('|'); value = value.substr(0, offset) + value.substr(offset + 1); const document = TextDocument.create(testUri, lang, 0, value); if (!workspaceFolders) { workspaceFolders = [{ name: 'x', uri: testUri.substr(0, testUri.lastIndexOf('/')) }]; } const context = getDocumentContext(testUri, workspaceFolders); const stylesheet = cssLanguageService.parseStylesheet(document); const links = await cssLanguageService.findDocumentLinks2(document, stylesheet, context)!; assert.strictEqual(links.length, expected.length); for (const item of expected) { assertLink(links, item, document); } } function getTestResource(path: string) { return URI.file(resolve(__dirname, '../../test/linksTestFixtures', path)).toString(true); } test('url links', async function () { const testUri = getTestResource('about.css'); const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("hello.html|")', [{ offset: 29, value: '"hello.html"', target: getTestResource('hello.html') }], testUri, folders ); }); test('url links - untitled', async function () { const testUri = 'untitled:untitled-1'; const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('@import url("base.css|");")', [{ offset: 12, value: '"base.css"', target: 'untitled:base.css' }], testUri, folders ); }); test('node module resolving', async function () { const testUri = getTestResource('about.css'); const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("~foo/hello.html|")', [{ offset: 29, value: '"~foo/hello.html"', target: getTestResource('node_modules/foo/hello.html') }], testUri, folders ); }); test('node module subfolder resolving', async function () { const testUri = getTestResource('subdir/about.css'); const folders = [{ name: 'x', uri: getTestResource('') }]; await assertLinks('html { background-image: url("~foo/hello.html|")', [{ offset: 29, value: '"~foo/hello.html"', target: getTestResource('node_modules/foo/hello.html') }], testUri, folders ); }); }); ================================================ FILE: extensions/css-language-features/server/src/utils/documentContext.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { DocumentContext } from 'vscode-css-languageservice'; import { endsWith, startsWith } from '../utils/strings'; import { WorkspaceFolder } from 'vscode-languageserver'; import { Utils, URI } from 'vscode-uri'; export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext { function getRootFolder(): string | undefined { for (const folder of workspaceFolders) { let folderURI = folder.uri; if (!endsWith(folderURI, '/')) { folderURI = folderURI + '/'; } if (startsWith(documentUri, folderURI)) { return folderURI; } } return undefined; } return { resolveReference: (ref: string, base = documentUri) => { if (ref[0] === '/') { // resolve absolute path against the current workspace folder const folderUri = getRootFolder(); if (folderUri) { return folderUri + ref.substring(1); } } const baseUri = URI.parse(base); const baseUriDir = baseUri.path.endsWith('/') ? baseUri : Utils.dirname(baseUri); return Utils.resolvePath(baseUriDir, ref).toString(true); }, }; } ================================================ FILE: extensions/css-language-features/server/src/utils/runner.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ResponseError, CancellationToken, LSPErrorCodes } from 'vscode-languageserver'; import { RuntimeEnvironment } from '../cssServer'; export function formatError(message: string, err: any): string { if (err instanceof Error) { const error = err; return `${message}: ${error.message}\n${error.stack}`; } else if (typeof err === 'string') { return `${message}: ${err}`; } else if (err) { return `${message}: ${err.toString()}`; } return message; } export function runSafeAsync(runtime: RuntimeEnvironment, func: () => Thenable, errorVal: T, errorMessage: string, token: CancellationToken): Thenable> { return new Promise>((resolve) => { runtime.timer.setImmediate(() => { if (token.isCancellationRequested) { resolve(cancelValue()); return; } return func().then(result => { if (token.isCancellationRequested) { resolve(cancelValue()); return; } else { resolve(result); } }, e => { console.error(formatError(errorMessage, e)); resolve(errorVal); }); }); }); } function cancelValue() { return new ResponseError(LSPErrorCodes.RequestCancelled, 'Request cancelled'); } ================================================ FILE: extensions/css-language-features/server/src/utils/strings.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export function startsWith(haystack: string, needle: string): boolean { if (haystack.length < needle.length) { return false; } for (let i = 0; i < needle.length; i++) { if (haystack[i] !== needle[i]) { return false; } } return true; } /** * Determines if haystack ends with needle. */ export function endsWith(haystack: string, needle: string): boolean { const diff = haystack.length - needle.length; if (diff > 0) { return haystack.lastIndexOf(needle) === diff; } else if (diff === 0) { return haystack === needle; } else { return false; } } ================================================ FILE: extensions/css-language-features/server/src/utils/validation.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { CancellationToken, Connection, Diagnostic, Disposable, DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, TextDocuments } from 'vscode-languageserver'; import { TextDocument } from 'vscode-css-languageservice'; import { formatError, runSafeAsync } from './runner'; import { RuntimeEnvironment } from '../cssServer'; export type Validator = (textDocument: TextDocument) => Promise; export type DiagnosticsSupport = { dispose(): void; requestRefresh(): void; }; export function registerDiagnosticsPushSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { const pendingValidationRequests: { [uri: string]: Disposable } = {}; const validationDelayMs = 500; const disposables: Disposable[] = []; // The content of a text document has changed. This event is emitted // when the text document first opened or when its content has changed. documents.onDidChangeContent(change => { triggerValidation(change.document); }, undefined, disposables); // a document has closed: clear all diagnostics documents.onDidClose(event => { cleanPendingValidation(event.document); connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] }); }, undefined, disposables); function cleanPendingValidation(textDocument: TextDocument): void { const request = pendingValidationRequests[textDocument.uri]; if (request) { request.dispose(); delete pendingValidationRequests[textDocument.uri]; } } function triggerValidation(textDocument: TextDocument): void { cleanPendingValidation(textDocument); const request = pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(async () => { if (request === pendingValidationRequests[textDocument.uri]) { try { const diagnostics = await validate(textDocument); if (request === pendingValidationRequests[textDocument.uri]) { connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); } delete pendingValidationRequests[textDocument.uri]; } catch (e) { connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e)); } } }, validationDelayMs); } return { requestRefresh: () => { documents.all().forEach(triggerValidation); }, dispose: () => { disposables.forEach(d => d.dispose()); disposables.length = 0; const keys = Object.keys(pendingValidationRequests); for (const key of keys) { pendingValidationRequests[key].dispose(); delete pendingValidationRequests[key]; } } }; } export function registerDiagnosticsPullSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { function newDocumentDiagnosticReport(diagnostics: Diagnostic[]): DocumentDiagnosticReport { return { kind: DocumentDiagnosticReportKind.Full, items: diagnostics }; } const registration = connection.languages.diagnostics.on(async (params: DocumentDiagnosticParams, token: CancellationToken) => { return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); if (document) { return newDocumentDiagnosticReport(await validate(document)); } return newDocumentDiagnosticReport([]); }, newDocumentDiagnosticReport([]), `Error while computing diagnostics for ${params.textDocument.uri}`, token); }); function requestRefresh(): void { connection.languages.diagnostics.refresh(); } return { requestRefresh, dispose: () => { registration.dispose(); } }; } ================================================ FILE: extensions/css-language-features/server/test/index.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const path = require('path'); const Mocha = require('mocha'); const glob = require('glob'); const suite = 'Integration CSS Extension Tests'; const options = { ui: 'tdd', color: true, timeout: 60000 }; if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { options.reporter = 'mocha-multi-reporters'; options.reporterOptions = { reporterEnabled: 'spec, mocha-junit-reporter', mochaJunitReporterReporterOptions: { testsuitesTitle: `${suite} ${process.platform}`, mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) } }; } const mocha = new Mocha(options); glob.sync(__dirname + '/../out/test/**/*.test.js') .forEach(file => mocha.addFile(file)); mocha.run(failures => process.exit(failures ? -1 : 0)); ================================================ FILE: extensions/css-language-features/server/test/linksTestFixtures/.gitignore ================================================ !/node_modules ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/.foo.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/about/about.css ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/about/about.html ================================================ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/index.html ================================================ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/src/feature.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/test/pathCompletionFixtures/src/test.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ ================================================ FILE: extensions/css-language-features/server/tsconfig.json ================================================ { "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./out", "lib": [ "ES2020", "WebWorker" ], "module": "Node16", }, "include": [ "src/**/*" ] } ================================================ FILE: extensions/css-language-features/test/mocha.opts ================================================ --ui tdd --useColors true server/out/test/**.test.js ================================================ FILE: extensions/dart/.vscodeignore ================================================ build/** cgmanifest.json ================================================ FILE: extensions/dart/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "dart-lang/dart-syntax-highlight", "repositoryUrl": "https://github.com/dart-lang/dart-syntax-highlight", "commitHash": "e1ac5c446c2531343393adbe8fff9d45d8a7c412" } }, "licenseDetail": [ "Copyright 2020, the Dart project authors.", "", "Redistribution and use in source and binary forms, with or without", "modification, are permitted provided that the following conditions are", "met:", "", " * Redistributions of source code must retain the above copyright", " notice, this list of conditions and the following disclaimer.", " * Redistributions in binary form must reproduce the above", " copyright notice, this list of conditions and the following", " disclaimer in the documentation and/or other materials provided", " with the distribution.", " * Neither the name of Google LLC nor the names of its", " contributors may be used to endorse or promote products derived", " from this software without specific prior written permission.", "", "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS", "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT", "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR", "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT", "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,", "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT", "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY", "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE", "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "license": "BSD", "version": "0.0.0" } ], "version": 1 } ================================================ FILE: extensions/dart/language-configuration.json ================================================ { "comments": { "lineComment": "//", "blockComment": [ "/*", "*/" ] }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ { "open": "{", "close": "}" }, { "open": "[", "close": "]" }, { "open": "(", "close": ")" }, { "open": "'", "close": "'", "notIn": ["string", "comment"] }, { "open": "\"", "close": "\"", "notIn": ["string"] }, { "open": "`", "close": "`", "notIn": ["string", "comment"] }, { "open": "/**", "close": " */", "notIn": ["string"] } ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["<", ">"], ["'", "'"], ["\"", "\""], ["`", "`"] ] } ================================================ FILE: extensions/dart/package.json ================================================ { "name": "dart", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "0.10.x" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin dart-lang/dart-syntax-highlight grammars/dart.json ./syntaxes/dart.tmLanguage.json" }, "categories": [ "Programming Languages" ], "contributes": { "languages": [ { "id": "dart", "extensions": [ ".dart" ], "aliases": [ "Dart" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "dart", "scopeName": "source.dart", "path": "./syntaxes/dart.tmLanguage.json" } ] } } ================================================ FILE: extensions/dart/package.nls.json ================================================ { "displayName": "Dart Language Basics", "description": "Provides syntax highlighting & bracket matching in Dart files." } ================================================ FILE: extensions/dart/syntaxes/dart.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/dart-lang/dart-syntax-highlight/blob/master/grammars/dart.json", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/dart-lang/dart-syntax-highlight/commit/e1ac5c446c2531343393adbe8fff9d45d8a7c412", "name": "Dart", "scopeName": "source.dart", "patterns": [ { "name": "meta.preprocessor.script.dart", "match": "^(#!.*)$" }, { "name": "meta.declaration.dart", "begin": "^\\w*\\b(augment\\s+library|library|import\\s+augment|import|part\\s+of|part|export)\\b", "beginCaptures": { "0": { "name": "keyword.other.import.dart" } }, "end": ";", "endCaptures": { "0": { "name": "punctuation.terminator.dart" } }, "patterns": [ { "include": "#strings" }, { "include": "#comments" }, { "name": "keyword.other.import.dart", "match": "\\b(as|show|hide)\\b" }, { "name": "keyword.control.dart", "match": "\\b(if)\\b" } ] }, { "include": "#comments" }, { "include": "#punctuation" }, { "include": "#annotations" }, { "include": "#keywords" }, { "include": "#constants-and-special-vars" }, { "include": "#operators" }, { "include": "#strings" } ], "repository": { "dartdoc-codeblock-triple": { "begin": "^\\s*///\\s*(?!\\s*```)", "end": "\n", "contentName": "variable.other.source.dart" }, "dartdoc-codeblock-block": { "begin": "^\\s*\\*\\s*(?!(\\s*```|/))", "end": "\n", "contentName": "variable.other.source.dart" }, "dartdoc": { "patterns": [ { "match": "(\\[.*?\\])", "captures": { "0": { "name": "variable.name.source.dart" } } }, { "begin": "^\\s*///\\s*(```)", "end": "^\\s*///\\s*(```)|^(?!\\s*///)", "patterns": [ { "include": "#dartdoc-codeblock-triple" } ] }, { "begin": "^\\s*\\*\\s*(```)", "end": "^\\s*\\*\\s*(```)|^(?=\\s*\\*/)", "patterns": [ { "include": "#dartdoc-codeblock-block" } ] }, { "match": "`[^`\n]+`", "name": "variable.other.source.dart" }, { "match": "(?:\\*|\\/\\/)\\s{4,}(.*?)(?=($|\\*\\/))", "captures": { "1": { "name": "variable.other.source.dart" } } } ] }, "comments": { "patterns": [ { "name": "comment.block.empty.dart", "match": "/\\*\\*/", "captures": { "0": { "name": "punctuation.definition.comment.dart" } } }, { "include": "#comments-doc-oldschool" }, { "include": "#comments-doc" }, { "include": "#comments-inline" } ] }, "comments-doc-oldschool": { "patterns": [ { "name": "comment.block.documentation.dart", "begin": "/\\*\\*", "end": "\\*/", "patterns": [ { "include": "#comments-doc-oldschool" }, { "include": "#comments-block" }, { "include": "#dartdoc" } ] } ] }, "comments-doc": { "patterns": [ { "name": "comment.block.documentation.dart", "begin": "///", "end": "^(?!\\s*///)", "patterns": [ { "include": "#dartdoc" } ] } ] }, "comments-inline": { "patterns": [ { "include": "#comments-block" }, { "match": "((//).*)$", "captures": { "1": { "name": "comment.line.double-slash.dart" } } } ] }, "comments-block": { "patterns": [ { "name": "comment.block.dart", "begin": "/\\*", "end": "\\*/", "patterns": [ { "include": "#comments-block" } ] } ] }, "annotations": { "patterns": [ { "name": "storage.type.annotation.dart", "match": "@[a-zA-Z]+" } ] }, "constants-and-special-vars": { "patterns": [ { "name": "constant.language.dart", "match": "(??]|,\\s*|\\s+extends\\s+)+>)?[!?]?\\(", "captures": { "1": { "name": "entity.name.function.dart" }, "2": { "patterns": [ { "include": "#type-args" } ] } } } ] }, "type-args": { "begin": "(<)", "end": "(>)", "beginCaptures": { "1": { "name": "other.source.dart" } }, "endCaptures": { "1": { "name": "other.source.dart" } }, "patterns": [ { "include": "#class-identifier" }, { "match": "," }, { "name": "keyword.declaration.dart", "match": "extends" }, { "include": "#comments" } ] }, "keywords": { "patterns": [ { "name": "keyword.cast.dart", "match": "(?>>?|~|\\^|\\||&)" }, { "name": "keyword.operator.assignment.bitwise.dart", "match": "((&|\\^|\\||<<|>>>?)=)" }, { "name": "keyword.operator.closure.dart", "match": "(=>)" }, { "name": "keyword.operator.comparison.dart", "match": "(==|!=|<=?|>=?)" }, { "name": "keyword.operator.assignment.arithmetic.dart", "match": "(([+*/%-]|\\~)=)" }, { "name": "keyword.operator.assignment.dart", "match": "(=)" }, { "name": "keyword.operator.increment-decrement.dart", "match": "(\\-\\-|\\+\\+)" }, { "name": "keyword.operator.arithmetic.dart", "match": "(\\-|\\+|\\*|\\/|\\~\\/|%)" }, { "name": "keyword.operator.logical.dart", "match": "(!|&&|\\|\\|)" } ] }, "expression": { "patterns": [ { "include": "#constants-and-special-vars" }, { "include": "#strings" }, { "name": "variable.parameter.dart", "match": "[a-zA-Z0-9_]+" }, { "begin": "\\{", "end": "\\}", "patterns": [ { "include": "#expression" } ] } ] }, "string-interp": { "patterns": [ { "name": "meta.embedded.expression.dart", "match": "\\$([a-zA-Z0-9_]+)", "captures": { "1": { "name": "variable.parameter.dart" } } }, { "name": "meta.embedded.expression.dart", "begin": "\\$\\{", "end": "\\}", "patterns": [ { "include": "#expression" } ] }, { "name": "constant.character.escape.dart", "match": "\\\\." } ] }, "strings": { "patterns": [ { "name": "string.interpolated.triple.double.dart", "begin": "(?/**"], "args": [ "--extensionDevelopmentPath=${workspaceFolder}", ], "outFiles": [ "${workspaceFolder}/out/**/*.js", ], } ] } ================================================ FILE: extensions/debug-auto-launch/.vscodeignore ================================================ src/** tsconfig.json out/** extension.webpack.config.js package-lock.json ================================================ FILE: extensions/debug-auto-launch/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withDefaults = require('../shared.webpack.config'); module.exports = withDefaults({ context: __dirname, entry: { extension: './src/extension.ts', }, resolve: { mainFields: ['module', 'main'] } }); ================================================ FILE: extensions/debug-auto-launch/package.json ================================================ { "name": "debug-auto-launch", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.5.0" }, "icon": "media/icon.png", "capabilities": { "virtualWorkspaces": false, "untrustedWorkspaces": { "supported": true } }, "activationEvents": [ "onStartupFinished" ], "main": "./out/extension", "scripts": { "compile": "gulp compile-extension:debug-auto-launch", "watch": "gulp watch-extension:debug-auto-launch" }, "contributes": { "commands": [ { "command": "extension.node-debug.toggleAutoAttach", "title": "%toggle.auto.attach%", "category": "Debug" } ] }, "devDependencies": { "@types/node": "20.x" }, "prettier": { "printWidth": 100, "trailingComma": "all", "singleQuote": true, "arrowParens": "avoid" }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/debug-auto-launch/package.nls.json ================================================ { "displayName": "Node Debug Auto-attach", "description": "Helper for auto-attach feature when node-debug extensions are not active.", "toggle.auto.attach": "Toggle Auto Attach" } ================================================ FILE: extensions/debug-auto-launch/src/extension.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { promises as fs } from 'fs'; import { createServer, Server } from 'net'; import { dirname } from 'path'; import * as vscode from 'vscode'; const enum State { Disabled = 'disabled', OnlyWithFlag = 'onlyWithFlag', Smart = 'smart', Always = 'always', } const TEXT_STATUSBAR_LABEL = { [State.Disabled]: vscode.l10n.t('Auto Attach: Disabled'), [State.Always]: vscode.l10n.t('Auto Attach: Always'), [State.Smart]: vscode.l10n.t('Auto Attach: Smart'), [State.OnlyWithFlag]: vscode.l10n.t('Auto Attach: With Flag'), }; const TEXT_STATE_LABEL = { [State.Disabled]: vscode.l10n.t('Disabled'), [State.Always]: vscode.l10n.t('Always'), [State.Smart]: vscode.l10n.t('Smart'), [State.OnlyWithFlag]: vscode.l10n.t('Only With Flag'), }; const TEXT_STATE_DESCRIPTION = { [State.Disabled]: vscode.l10n.t('Auto attach is disabled and not shown in status bar'), [State.Always]: vscode.l10n.t('Auto attach to every Node.js process launched in the terminal'), [State.Smart]: vscode.l10n.t("Auto attach when running scripts that aren't in a node_modules folder"), [State.OnlyWithFlag]: vscode.l10n.t('Only auto attach when the `--inspect` flag is given') }; const TEXT_TOGGLE_WORKSPACE = vscode.l10n.t('Toggle auto attach in this workspace'); const TEXT_TOGGLE_GLOBAL = vscode.l10n.t('Toggle auto attach on this machine'); const TEXT_TEMP_DISABLE = vscode.l10n.t('Temporarily disable auto attach in this session'); const TEXT_TEMP_ENABLE = vscode.l10n.t('Re-enable auto attach'); const TEXT_TEMP_DISABLE_LABEL = vscode.l10n.t('Auto Attach: Disabled'); const TOGGLE_COMMAND = 'extension.node-debug.toggleAutoAttach'; const STORAGE_IPC = 'jsDebugIpcState'; const SETTING_SECTION = 'debug.javascript'; const SETTING_STATE = 'autoAttachFilter'; /** * settings that, when changed, should cause us to refresh the state vars */ const SETTINGS_CAUSE_REFRESH = new Set( ['autoAttachSmartPattern', SETTING_STATE].map(s => `${SETTING_SECTION}.${s}`), ); let currentState: Promise<{ context: vscode.ExtensionContext; state: State | null }>; let statusItem: vscode.StatusBarItem | undefined; // and there is no status bar item let server: Promise | undefined; // auto attach server let isTemporarilyDisabled = false; // whether the auto attach server is disabled temporarily, reset whenever the state changes export function activate(context: vscode.ExtensionContext): void { currentState = Promise.resolve({ context, state: null }); context.subscriptions.push( vscode.commands.registerCommand(TOGGLE_COMMAND, toggleAutoAttachSetting.bind(null, context)), ); context.subscriptions.push( vscode.workspace.onDidChangeConfiguration(e => { // Whenever a setting is changed, disable auto attach, and re-enable // it (if necessary) to refresh variables. if ( e.affectsConfiguration(`${SETTING_SECTION}.${SETTING_STATE}`) || [...SETTINGS_CAUSE_REFRESH].some(setting => e.affectsConfiguration(setting)) ) { refreshAutoAttachVars(); } }), ); updateAutoAttach(readCurrentState()); } export async function deactivate(): Promise { await destroyAttachServer(); } function refreshAutoAttachVars() { updateAutoAttach(State.Disabled); updateAutoAttach(readCurrentState()); } function getDefaultScope(info: ReturnType) { if (!info) { return vscode.ConfigurationTarget.Global; } else if (info.workspaceFolderValue) { return vscode.ConfigurationTarget.WorkspaceFolder; } else if (info.workspaceValue) { return vscode.ConfigurationTarget.Workspace; } else if (info.globalValue) { return vscode.ConfigurationTarget.Global; } return vscode.ConfigurationTarget.Global; } type PickResult = { state: State } | { setTempDisabled: boolean } | { scope: vscode.ConfigurationTarget } | undefined; type PickItem = vscode.QuickPickItem & ({ state: State } | { setTempDisabled: boolean }); async function toggleAutoAttachSetting(context: vscode.ExtensionContext, scope?: vscode.ConfigurationTarget): Promise { const section = vscode.workspace.getConfiguration(SETTING_SECTION); scope = scope || getDefaultScope(section.inspect(SETTING_STATE)); const isGlobalScope = scope === vscode.ConfigurationTarget.Global; const quickPick = vscode.window.createQuickPick(); const current = readCurrentState(); const items: PickItem[] = [State.Always, State.Smart, State.OnlyWithFlag, State.Disabled].map(state => ({ state, label: TEXT_STATE_LABEL[state], description: TEXT_STATE_DESCRIPTION[state], alwaysShow: true, })); if (current !== State.Disabled) { items.unshift({ setTempDisabled: !isTemporarilyDisabled, label: isTemporarilyDisabled ? TEXT_TEMP_ENABLE : TEXT_TEMP_DISABLE, alwaysShow: true, }); } quickPick.items = items; quickPick.activeItems = isTemporarilyDisabled ? [items[0]] : quickPick.items.filter(i => 'state' in i && i.state === current); quickPick.title = isGlobalScope ? TEXT_TOGGLE_GLOBAL : TEXT_TOGGLE_WORKSPACE; quickPick.buttons = [ { iconPath: new vscode.ThemeIcon(isGlobalScope ? 'folder' : 'globe'), tooltip: isGlobalScope ? TEXT_TOGGLE_WORKSPACE : TEXT_TOGGLE_GLOBAL, }, ]; quickPick.show(); let result = await new Promise(resolve => { quickPick.onDidAccept(() => resolve(quickPick.selectedItems[0])); quickPick.onDidHide(() => resolve(undefined)); quickPick.onDidTriggerButton(() => { resolve({ scope: isGlobalScope ? vscode.ConfigurationTarget.Workspace : vscode.ConfigurationTarget.Global, }); }); }); quickPick.dispose(); if (!result) { return; } if ('scope' in result) { return await toggleAutoAttachSetting(context, result.scope); } if ('state' in result) { if (result.state !== current) { section.update(SETTING_STATE, result.state, scope); } else if (isTemporarilyDisabled) { result = { setTempDisabled: false }; } } if ('setTempDisabled' in result) { updateStatusBar(context, current, true); isTemporarilyDisabled = result.setTempDisabled; if (result.setTempDisabled) { await destroyAttachServer(); } else { await createAttachServer(context); // unsets temp disabled var internally } updateStatusBar(context, current, false); } } function readCurrentState(): State { const section = vscode.workspace.getConfiguration(SETTING_SECTION); return section.get(SETTING_STATE) ?? State.Disabled; } async function clearJsDebugAttachState(context: vscode.ExtensionContext) { if (server || await context.workspaceState.get(STORAGE_IPC)) { await context.workspaceState.update(STORAGE_IPC, undefined); await vscode.commands.executeCommand('extension.js-debug.clearAutoAttachVariables'); await destroyAttachServer(); } } /** * Turns auto attach on, and returns the server auto attach is listening on * if it's successful. */ async function createAttachServer(context: vscode.ExtensionContext) { const ipcAddress = await getIpcAddress(context); if (!ipcAddress) { return undefined; } server = createServerInner(ipcAddress).catch(async err => { console.error('[debug-auto-launch] Error creating auto attach server: ', err); if (process.platform !== 'win32') { // On macOS, and perhaps some Linux distros, the temporary directory can // sometimes change. If it looks like that's the cause of a listener // error, automatically refresh the auto attach vars. try { await fs.access(dirname(ipcAddress)); } catch { console.error('[debug-auto-launch] Refreshing variables from error'); refreshAutoAttachVars(); return undefined; } } return undefined; }); return await server; } const createServerInner = async (ipcAddress: string) => { try { return await createServerInstance(ipcAddress); } catch (e) { // On unix/linux, the file can 'leak' if the process exits unexpectedly. // If we see this, try to delete the file and then listen again. await fs.unlink(ipcAddress).catch(() => undefined); return await createServerInstance(ipcAddress); } }; const createServerInstance = (ipcAddress: string) => new Promise((resolve, reject) => { const s = createServer(socket => { const data: Buffer[] = []; socket.on('data', async chunk => { if (chunk[chunk.length - 1] !== 0) { // terminated with NUL byte data.push(chunk); return; } data.push(chunk.slice(0, -1)); try { await vscode.commands.executeCommand( 'extension.js-debug.autoAttachToProcess', JSON.parse(Buffer.concat(data).toString()), ); socket.write(Buffer.from([0])); } catch (err) { socket.write(Buffer.from([1])); console.error(err); } }); }) .on('error', reject) .listen(ipcAddress, () => resolve(s)); }); /** * Destroys the auto-attach server, if it's running. */ async function destroyAttachServer() { const instance = await server; if (instance) { await new Promise(r => instance.close(r)); } } interface CachedIpcState { ipcAddress: string; jsDebugPath: string | undefined; settingsValue: string; } /** * Map of logic that happens when auto attach states are entered and exited. * All state transitions are queued and run in order; promises are awaited. */ const transitions: { [S in State]: (context: vscode.ExtensionContext) => Promise } = { async [State.Disabled](context) { await clearJsDebugAttachState(context); }, async [State.OnlyWithFlag](context) { await createAttachServer(context); }, async [State.Smart](context) { await createAttachServer(context); }, async [State.Always](context) { await createAttachServer(context); }, }; /** * Ensures the status bar text reflects the current state. */ function updateStatusBar(context: vscode.ExtensionContext, state: State, busy = false) { if (state === State.Disabled && !busy) { statusItem?.hide(); return; } if (!statusItem) { statusItem = vscode.window.createStatusBarItem('status.debug.autoAttach', vscode.StatusBarAlignment.Left); statusItem.name = vscode.l10n.t("Debug Auto Attach"); statusItem.command = TOGGLE_COMMAND; statusItem.tooltip = vscode.l10n.t("Automatically attach to node.js processes in debug mode"); context.subscriptions.push(statusItem); } let text = busy ? '$(loading) ' : ''; text += isTemporarilyDisabled ? TEXT_TEMP_DISABLE_LABEL : TEXT_STATUSBAR_LABEL[state]; statusItem.text = text; statusItem.show(); } /** * Updates the auto attach feature based on the user or workspace setting */ function updateAutoAttach(newState: State) { currentState = currentState.then(async ({ context, state: oldState }) => { if (newState === oldState) { return { context, state: oldState }; } if (oldState !== null) { updateStatusBar(context, oldState, true); } await transitions[newState](context); isTemporarilyDisabled = false; updateStatusBar(context, newState, false); return { context, state: newState }; }); } /** * Gets the IPC address for the server to listen on for js-debug sessions. This * is cached such that we can reuse the address of previous activations. */ async function getIpcAddress(context: vscode.ExtensionContext) { // Iff the `cachedData` is present, the js-debug registered environment // variables for this workspace--cachedData is set after successfully // invoking the attachment command. const cachedIpc = context.workspaceState.get(STORAGE_IPC); // We invalidate the IPC data if the js-debug path changes, since that // indicates the extension was updated or reinstalled and the // environment variables will have been lost. // todo: make a way in the API to read environment data directly without activating js-debug? const jsDebugPath = vscode.extensions.getExtension('ms-vscode.js-debug-nightly')?.extensionPath || vscode.extensions.getExtension('ms-vscode.js-debug')?.extensionPath; const settingsValue = getJsDebugSettingKey(); if (cachedIpc?.jsDebugPath === jsDebugPath && cachedIpc?.settingsValue === settingsValue) { return cachedIpc.ipcAddress; } const result = await vscode.commands.executeCommand<{ ipcAddress: string }>( 'extension.js-debug.setAutoAttachVariables', cachedIpc?.ipcAddress, ); if (!result) { return; } const ipcAddress = result.ipcAddress; await context.workspaceState.update(STORAGE_IPC, { ipcAddress, jsDebugPath, settingsValue, } satisfies CachedIpcState); return ipcAddress; } function getJsDebugSettingKey() { const o: { [key: string]: unknown } = {}; const config = vscode.workspace.getConfiguration(SETTING_SECTION); for (const setting of SETTINGS_CAUSE_REFRESH) { o[setting] = config.get(setting); } return JSON.stringify(o); } ================================================ FILE: extensions/debug-auto-launch/tsconfig.json ================================================ { "extends": "../tsconfig.base.json", "compilerOptions": { "outDir": "./out", "downlevelIteration": true, "types": [ "node" ] }, "include": [ "src/**/*", "../../src/vscode-dts/vscode.d.ts" ] } ================================================ FILE: extensions/debug-server-ready/.npmrc ================================================ legacy-peer-deps="true" timeout=180000 ================================================ FILE: extensions/debug-server-ready/.vscode/launch.json ================================================ { "version": "0.2.0", "configurations": [ { "name": "Run Server Ready Extension", "type": "extensionHost", "request": "launch", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" ] } ] } ================================================ FILE: extensions/debug-server-ready/.vscodeignore ================================================ src/** tsconfig.json out/** extension.webpack.config.js package-lock.json .vscode ================================================ FILE: extensions/debug-server-ready/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withDefaults = require('../shared.webpack.config'); module.exports = withDefaults({ context: __dirname, entry: { extension: './src/extension.ts', }, resolve: { mainFields: ['module', 'main'] } }); ================================================ FILE: extensions/debug-server-ready/package.json ================================================ { "name": "debug-server-ready", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.32.0" }, "icon": "media/icon.png", "activationEvents": [ "onDebugResolve" ], "capabilities": { "virtualWorkspaces": false, "untrustedWorkspaces": { "supported": true } }, "enabledApiProposals": [ "terminalDataWriteEvent" ], "main": "./out/extension", "scripts": { "compile": "gulp compile-extension:debug-server-ready", "watch": "gulp watch-extension:debug-server-ready" }, "contributes": { "debuggers": [ { "type": "*", "configurationAttributes": { "launch": { "properties": { "serverReadyAction": { "oneOf": [ { "type": "object", "additionalProperties": false, "markdownDescription": "%debug.server.ready.serverReadyAction.description%", "default": { "action": "openExternally", "killOnServerStop": false }, "properties": { "action": { "type": "string", "enum": [ "openExternally" ], "enumDescriptions": [ "%debug.server.ready.action.openExternally.description%" ], "markdownDescription": "%debug.server.ready.action.description%", "default": "openExternally" }, "pattern": { "type": "string", "markdownDescription": "%debug.server.ready.pattern.description%", "default": "listening on port ([0-9]+)" }, "uriFormat": { "type": "string", "markdownDescription": "%debug.server.ready.uriFormat.description%", "default": "http://localhost:%s" }, "killOnServerStop": { "type": "boolean", "markdownDescription": "%debug.server.ready.killOnServerStop.description%", "default": false } } }, { "type": "object", "additionalProperties": false, "markdownDescription": "%debug.server.ready.serverReadyAction.description%", "default": { "action": "debugWithEdge", "pattern": "listening on port ([0-9]+)", "uriFormat": "http://localhost:%s", "webRoot": "${workspaceFolder}", "killOnServerStop": false }, "properties": { "action": { "type": "string", "enum": [ "debugWithChrome", "debugWithEdge" ], "enumDescriptions": [ "%debug.server.ready.action.debugWithChrome.description%" ], "markdownDescription": "%debug.server.ready.action.description%", "default": "debugWithEdge" }, "pattern": { "type": "string", "markdownDescription": "%debug.server.ready.pattern.description%", "default": "listening on port ([0-9]+)" }, "uriFormat": { "type": "string", "markdownDescription": "%debug.server.ready.uriFormat.description%", "default": "http://localhost:%s" }, "webRoot": { "type": "string", "markdownDescription": "%debug.server.ready.webRoot.description%", "default": "${workspaceFolder}" }, "killOnServerStop": { "type": "boolean", "markdownDescription": "%debug.server.ready.killOnServerStop.description%", "default": false } } }, { "type": "object", "additionalProperties": false, "markdownDescription": "%debug.server.ready.serverReadyAction.description%", "default": { "action": "startDebugging", "name": "", "killOnServerStop": false }, "required": [ "name" ], "properties": { "action": { "type": "string", "enum": [ "startDebugging" ], "enumDescriptions": [ "%debug.server.ready.action.startDebugging.description%" ], "markdownDescription": "%debug.server.ready.action.description%", "default": "startDebugging" }, "pattern": { "type": "string", "markdownDescription": "%debug.server.ready.pattern.description%", "default": "listening on port ([0-9]+)" }, "name": { "type": "string", "markdownDescription": "%debug.server.ready.debugConfigName.description%", "default": "Launch Browser" }, "killOnServerStop": { "type": "boolean", "markdownDescription": "%debug.server.ready.killOnServerStop.description%", "default": false } } }, { "type": "object", "additionalProperties": false, "markdownDescription": "%debug.server.ready.serverReadyAction.description%", "default": { "action": "startDebugging", "config": { "type": "node", "request": "launch" }, "killOnServerStop": false }, "required": [ "config" ], "properties": { "action": { "type": "string", "enum": [ "startDebugging" ], "enumDescriptions": [ "%debug.server.ready.action.startDebugging.description%" ], "markdownDescription": "%debug.server.ready.action.description%", "default": "startDebugging" }, "pattern": { "type": "string", "markdownDescription": "%debug.server.ready.pattern.description%", "default": "listening on port ([0-9]+)" }, "config": { "type": "object", "markdownDescription": "%debug.server.ready.debugConfig.description%", "default": {} }, "killOnServerStop": { "type": "boolean", "markdownDescription": "%debug.server.ready.killOnServerStop.description%", "default": false } } } ] } } } } } ] }, "devDependencies": { "@types/node": "20.x" }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/debug-server-ready/package.nls.json ================================================ { "displayName": "Server Ready Action", "description": "Open URI in browser if server under debugging is ready.", "debug.server.ready.serverReadyAction.description": "Act upon a URI when a server program under debugging is ready (indicated by sending output of the form 'listening on port 3000' or 'Now listening on: https://localhost:5001' to the debug console.)", "debug.server.ready.action.description": "What to do with the URI when the server is ready.", "debug.server.ready.action.openExternally.description": "Open URI externally with the default application.", "debug.server.ready.action.debugWithChrome.description": "Start debugging with the 'Debugger for Chrome'.", "debug.server.ready.action.startDebugging.description": "Run another launch configuration.", "debug.server.ready.pattern.description": "Server is ready if this pattern appears on the debug console. The first capture group must include a URI or a port number.", "debug.server.ready.debugConfig.description": "The debug configuration to run.", "debug.server.ready.uriFormat.description": "A format string used when constructing the URI from a port number. The first '%s' is substituted with the port number.", "debug.server.ready.webRoot.description": "Value passed to the debug configuration for the 'Debugger for Chrome'.", "debug.server.ready.killOnServerStop.description": "Stop the child session when the parent session stopped.", "debug.server.ready.debugConfigName.description": "Name of the launch configuration to run." } ================================================ FILE: extensions/debug-server-ready/src/extension.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import * as util from 'util'; import { randomUUID } from 'crypto'; const PATTERN = 'listening on.* (https?://\\S+|[0-9]+)'; // matches "listening on port 3000" or "Now listening on: https://localhost:5001" const URI_PORT_FORMAT = 'http://localhost:%s'; const URI_FORMAT = '%s'; const WEB_ROOT = '${workspaceFolder}'; interface ServerReadyAction { pattern: string; action?: 'openExternally' | 'debugWithChrome' | 'debugWithEdge' | 'startDebugging'; uriFormat?: string; webRoot?: string; name?: string; config?: vscode.DebugConfiguration; killOnServerStop?: boolean; } // From src/vs/base/common/strings.ts const CSI_SEQUENCE = /(?:\x1b\[|\x9b)[=?>!]?[\d;:]*["$#'* ]?[a-zA-Z@^`{}|~]/; const OSC_SEQUENCE = /(?:\x1b\]|\x9d).*?(?:\x1b\\|\x07|\x9c)/; const ESC_SEQUENCE = /\x1b(?:[ #%\(\)\*\+\-\.\/]?[a-zA-Z0-9\|}~@])/; const CONTROL_SEQUENCES = new RegExp('(?:' + [ CSI_SEQUENCE.source, OSC_SEQUENCE.source, ESC_SEQUENCE.source, ].join('|') + ')', 'g'); /** * Froms vs/base/common/strings.ts in core * @see https://github.com/microsoft/vscode/blob/22a2a0e833175c32a2005b977d7fbd355582e416/src/vs/base/common/strings.ts#L736 */ function removeAnsiEscapeCodes(str: string): string { if (str) { str = str.replace(CONTROL_SEQUENCES, ''); } return str; } class Trigger { private _fired = false; public get hasFired() { return this._fired; } public fire() { this._fired = true; } } class ServerReadyDetector extends vscode.Disposable { private static detectors = new Map(); private static terminalDataListener: vscode.Disposable | undefined; private readonly stoppedEmitter = new vscode.EventEmitter(); private readonly onDidSessionStop = this.stoppedEmitter.event; private readonly disposables = new Set([]); private trigger: Trigger; private shellPid?: number; private regexp: RegExp; static start(session: vscode.DebugSession): ServerReadyDetector | undefined { if (session.configuration.serverReadyAction) { let detector = ServerReadyDetector.detectors.get(session); if (!detector) { detector = new ServerReadyDetector(session); ServerReadyDetector.detectors.set(session, detector); } return detector; } return undefined; } static stop(session: vscode.DebugSession): void { const detector = ServerReadyDetector.detectors.get(session); if (detector) { ServerReadyDetector.detectors.delete(session); detector.sessionStopped(); detector.dispose(); } } static rememberShellPid(session: vscode.DebugSession, pid: number) { const detector = ServerReadyDetector.detectors.get(session); if (detector) { detector.shellPid = pid; } } static async startListeningTerminalData() { if (!this.terminalDataListener) { this.terminalDataListener = vscode.window.onDidWriteTerminalData(async e => { // first find the detector with a matching pid const pid = await e.terminal.processId; const str = removeAnsiEscapeCodes(e.data); for (const [, detector] of this.detectors) { if (detector.shellPid === pid) { detector.detectPattern(str); return; } } // if none found, try all detectors until one matches for (const [, detector] of this.detectors) { if (detector.detectPattern(str)) { return; } } }); } } private constructor(private session: vscode.DebugSession) { super(() => this.internalDispose()); // Re-used the triggered of the parent session, if one exists if (session.parentSession) { this.trigger = ServerReadyDetector.start(session.parentSession)?.trigger ?? new Trigger(); } else { this.trigger = new Trigger(); } this.regexp = new RegExp(session.configuration.serverReadyAction.pattern || PATTERN, 'i'); } private internalDispose() { this.disposables.forEach(d => d.dispose()); this.disposables.clear(); } public sessionStopped() { this.stoppedEmitter.fire(); } detectPattern(s: string): boolean { if (!this.trigger.hasFired) { const matches = this.regexp.exec(s); if (matches && matches.length >= 1) { this.openExternalWithString(this.session, matches.length > 1 ? matches[1] : ''); this.trigger.fire(); return true; } } return false; } private openExternalWithString(session: vscode.DebugSession, captureString: string) { const args: ServerReadyAction = session.configuration.serverReadyAction; let uri; if (captureString === '') { // nothing captured by reg exp -> use the uriFormat as the target uri without substitution // verify that format does not contain '%s' const format = args.uriFormat || ''; if (format.indexOf('%s') >= 0) { const errMsg = vscode.l10n.t("Format uri ('{0}') uses a substitution placeholder but pattern did not capture anything.", format); vscode.window.showErrorMessage(errMsg, { modal: true }).then(_ => undefined); return; } uri = format; } else { // if no uriFormat is specified guess the appropriate format based on the captureString const format = args.uriFormat || (/^[0-9]+$/.test(captureString) ? URI_PORT_FORMAT : URI_FORMAT); // verify that format only contains a single '%s' const s = format.split('%s'); if (s.length !== 2) { const errMsg = vscode.l10n.t("Format uri ('{0}') must contain exactly one substitution placeholder.", format); vscode.window.showErrorMessage(errMsg, { modal: true }).then(_ => undefined); return; } uri = util.format(format, captureString); } this.openExternalWithUri(session, uri); } private async openExternalWithUri(session: vscode.DebugSession, uri: string) { const args: ServerReadyAction = session.configuration.serverReadyAction; switch (args.action || 'openExternally') { case 'openExternally': await vscode.env.openExternal(vscode.Uri.parse(uri)); break; case 'debugWithChrome': await this.debugWithBrowser('pwa-chrome', session, uri); break; case 'debugWithEdge': await this.debugWithBrowser('pwa-msedge', session, uri); break; case 'startDebugging': if (args.config) { await this.startDebugSession(session, args.config.name, args.config); } else { await this.startDebugSession(session, args.name || 'unspecified'); } break; default: // not supported break; } } private async debugWithBrowser(type: string, session: vscode.DebugSession, uri: string) { const args = session.configuration.serverReadyAction as ServerReadyAction; if (!args.killOnServerStop) { await this.startBrowserDebugSession(type, session, uri); return; } const trackerId = randomUUID(); const cts = new vscode.CancellationTokenSource(); const newSessionPromise = this.catchStartedDebugSession(session => session.configuration._debugServerReadySessionId === trackerId, cts.token); if (!await this.startBrowserDebugSession(type, session, uri, trackerId)) { cts.cancel(); cts.dispose(); return; } const createdSession = await newSessionPromise; cts.dispose(); if (!createdSession) { return; } const stopListener = this.onDidSessionStop(async () => { stopListener.dispose(); this.disposables.delete(stopListener); await vscode.debug.stopDebugging(createdSession); }); this.disposables.add(stopListener); } private startBrowserDebugSession(type: string, session: vscode.DebugSession, uri: string, trackerId?: string) { return vscode.debug.startDebugging(session.workspaceFolder, { type, name: 'Browser Debug', request: 'launch', url: uri, webRoot: session.configuration.serverReadyAction.webRoot || WEB_ROOT, _debugServerReadySessionId: trackerId, }); } /** * Starts a debug session given a debug configuration name (saved in launch.json) or a debug configuration object. * * @param session The parent debugSession * @param name The name of the configuration to launch. If config it set, it assumes it is the same as config.name. * @param config [Optional] Instead of starting a debug session by debug configuration name, use a debug configuration object instead. */ private async startDebugSession(session: vscode.DebugSession, name: string, config?: vscode.DebugConfiguration) { const args = session.configuration.serverReadyAction as ServerReadyAction; if (!args.killOnServerStop) { await vscode.debug.startDebugging(session.workspaceFolder, config ?? name); return; } const cts = new vscode.CancellationTokenSource(); const newSessionPromise = this.catchStartedDebugSession(x => x.name === name, cts.token); if (!await vscode.debug.startDebugging(session.workspaceFolder, config ?? name)) { cts.cancel(); cts.dispose(); return; } const createdSession = await newSessionPromise; cts.dispose(); if (!createdSession) { return; } const stopListener = this.onDidSessionStop(async () => { stopListener.dispose(); this.disposables.delete(stopListener); await vscode.debug.stopDebugging(createdSession); }); this.disposables.add(stopListener); } private catchStartedDebugSession(predicate: (session: vscode.DebugSession) => boolean, cancellationToken: vscode.CancellationToken): Promise { return new Promise(_resolve => { const done = (value?: vscode.DebugSession) => { listener.dispose(); cancellationListener.dispose(); this.disposables.delete(listener); this.disposables.delete(cancellationListener); _resolve(value); }; const cancellationListener = cancellationToken.onCancellationRequested(done); const listener = vscode.debug.onDidStartDebugSession(session => { if (predicate(session)) { done(session); } }); // In case the debug session of interest was never caught anyhow. this.disposables.add(listener); this.disposables.add(cancellationListener); }); } } export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.debug.onDidStartDebugSession(session => { if (session.configuration.serverReadyAction) { const detector = ServerReadyDetector.start(session); if (detector) { ServerReadyDetector.startListeningTerminalData(); } } })); context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(session => { ServerReadyDetector.stop(session); })); const trackers = new Set(); context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('*', { resolveDebugConfigurationWithSubstitutedVariables(_folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration) { if (debugConfiguration.type && debugConfiguration.serverReadyAction) { if (!trackers.has(debugConfiguration.type)) { trackers.add(debugConfiguration.type); startTrackerForType(context, debugConfiguration.type); } } return debugConfiguration; } })); } function startTrackerForType(context: vscode.ExtensionContext, type: string) { // scan debug console output for a PORT message context.subscriptions.push(vscode.debug.registerDebugAdapterTrackerFactory(type, { createDebugAdapterTracker(session: vscode.DebugSession) { const detector = ServerReadyDetector.start(session); if (detector) { let runInTerminalRequestSeq: number | undefined; return { onDidSendMessage: m => { if (m.type === 'event' && m.event === 'output' && m.body) { switch (m.body.category) { case 'console': case 'stderr': case 'stdout': if (m.body.output) { detector.detectPattern(m.body.output); } break; default: break; } } if (m.type === 'request' && m.command === 'runInTerminal' && m.arguments) { if (m.arguments.kind === 'integrated') { runInTerminalRequestSeq = m.seq; // remember this to find matching response } } }, onWillReceiveMessage: m => { if (runInTerminalRequestSeq && m.type === 'response' && m.command === 'runInTerminal' && m.body && runInTerminalRequestSeq === m.request_seq) { runInTerminalRequestSeq = undefined; ServerReadyDetector.rememberShellPid(session, m.body.shellProcessId); } } }; } return undefined; } })); } ================================================ FILE: extensions/debug-server-ready/tsconfig.json ================================================ { "extends": "../tsconfig.base.json", "compilerOptions": { "outDir": "./out", "downlevelIteration": true, "types": [ "node" ] }, "include": [ "src/**/*", "../../src/vscode-dts/vscode.d.ts", "../../src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts", ] } ================================================ FILE: extensions/diff/.vscodeignore ================================================ build/** cgmanifest.json ================================================ FILE: extensions/diff/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "textmate/diff.tmbundle", "repositoryUrl": "https://github.com/textmate/diff.tmbundle", "commitHash": "0593bb775eab1824af97ef2172fd38822abd97d7" } }, "licenseDetail": [ "Copyright (c) textmate-diff.tmbundle project authors", "", "If not otherwise specified (see below), files in this repository fall under the following license:", "", "Permission to copy, use, modify, sell and distribute this", "software is granted. This software is provided \"as is\" without", "express or implied warranty, and with no claim as to its", "suitability for any purpose.", "", "An exception is made for files in readable text which contain their own license information,", "or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added", "to the base-name name of the original file, and an extension of txt, html, or similar. For example", "\"tidy\" is accompanied by \"tidy-license.txt\"." ], "license": "TextMate Bundle License", "version": "0.0.0" } ], "version": 1 } ================================================ FILE: extensions/diff/language-configuration.json ================================================ { "comments": { "lineComment": "#", "blockComment": [ "#", " " ] }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ] } ================================================ FILE: extensions/diff/package.json ================================================ { "name": "diff", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "0.10.x" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/diff.tmbundle Syntaxes/Diff.plist ./syntaxes/diff.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "diff", "aliases": [ "Diff", "diff" ], "extensions": [ ".diff", ".patch", ".rej" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "diff", "scopeName": "source.diff", "path": "./syntaxes/diff.tmLanguage.json" } ] } } ================================================ FILE: extensions/diff/package.nls.json ================================================ { "displayName": "Diff Language Basics", "description": "Provides syntax highlighting & bracket matching in Diff files." } ================================================ FILE: extensions/diff/syntaxes/diff.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/textmate/diff.tmbundle/blob/master/Syntaxes/Diff.plist", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/textmate/diff.tmbundle/commit/0593bb775eab1824af97ef2172fd38822abd97d7", "name": "Diff", "scopeName": "source.diff", "patterns": [ { "captures": { "1": { "name": "punctuation.definition.separator.diff" } }, "match": "^((\\*{15})|(={67})|(-{3}))$\\n?", "name": "meta.separator.diff" }, { "match": "^\\d+(,\\d+)*(a|d|c)\\d+(,\\d+)*$\\n?", "name": "meta.diff.range.normal" }, { "captures": { "1": { "name": "punctuation.definition.range.diff" }, "2": { "name": "meta.toc-list.line-number.diff" }, "3": { "name": "punctuation.definition.range.diff" } }, "match": "^(@@)\\s*(.+?)\\s*(@@)($\\n?)?", "name": "meta.diff.range.unified" }, { "captures": { "3": { "name": "punctuation.definition.range.diff" }, "4": { "name": "punctuation.definition.range.diff" }, "6": { "name": "punctuation.definition.range.diff" }, "7": { "name": "punctuation.definition.range.diff" } }, "match": "^(((\\-{3}) .+ (\\-{4}))|((\\*{3}) .+ (\\*{4})))$\\n?", "name": "meta.diff.range.context" }, { "match": "^diff --git a/.*$\\n?", "name": "meta.diff.header.git" }, { "match": "^diff (-|\\S+\\s+\\S+).*$\\n?", "name": "meta.diff.header.command" }, { "captures": { "4": { "name": "punctuation.definition.from-file.diff" }, "6": { "name": "punctuation.definition.from-file.diff" }, "7": { "name": "punctuation.definition.from-file.diff" } }, "match": "(^(((-{3}) .+)|((\\*{3}) .+))$\\n?|^(={4}) .+(?= - ))", "name": "meta.diff.header.from-file" }, { "captures": { "2": { "name": "punctuation.definition.to-file.diff" }, "3": { "name": "punctuation.definition.to-file.diff" }, "4": { "name": "punctuation.definition.to-file.diff" } }, "match": "(^(\\+{3}) .+$\\n?| (-) .* (={4})$\\n?)", "name": "meta.diff.header.to-file" }, { "captures": { "3": { "name": "punctuation.definition.inserted.diff" }, "6": { "name": "punctuation.definition.inserted.diff" } }, "match": "^(((>)( .*)?)|((\\+).*))$\\n?", "name": "markup.inserted.diff" }, { "captures": { "1": { "name": "punctuation.definition.changed.diff" } }, "match": "^(!).*$\\n?", "name": "markup.changed.diff" }, { "captures": { "3": { "name": "punctuation.definition.deleted.diff" }, "6": { "name": "punctuation.definition.deleted.diff" } }, "match": "^(((<)( .*)?)|((-).*))$\\n?", "name": "markup.deleted.diff" }, { "begin": "^(#)", "captures": { "1": { "name": "punctuation.definition.comment.diff" } }, "comment": "Git produces unified diffs with embedded comments\"", "end": "\\n", "name": "comment.line.number-sign.diff" }, { "match": "^index [0-9a-f]{7,40}\\.\\.[0-9a-f]{7,40}.*$\\n?", "name": "meta.diff.index.git" }, { "captures": { "1": { "name": "punctuation.separator.key-value.diff" }, "2": { "name": "meta.toc-list.file-name.diff" } }, "match": "^Index(:) (.+)$\\n?", "name": "meta.diff.index" }, { "match": "^Only in .*: .*$\\n?", "name": "meta.diff.only-in" } ] } ================================================ FILE: extensions/docker/.vscodeignore ================================================ test/** cgmanifest.json ================================================ FILE: extensions/docker/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "language-docker", "repositoryUrl": "https://github.com/moby/moby", "commitHash": "c2029cb2574647e4bc28ed58486b8e85883eedb9" } }, "license": "Apache-2.0", "description": "The file syntaxes/docker.tmLanguage was included from https://github.com/moby/moby/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage.", "version": "0.0.0" } ], "version": 1 } ================================================ FILE: extensions/docker/language-configuration.json ================================================ { "comments": { "lineComment": "#" }, "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], "autoClosingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["\"", "\""], ["'", "'"] ], "surroundingPairs": [ ["{", "}"], ["[", "]"], ["(", ")"], ["\"", "\""], ["'", "'"] ], "indentationRules": { "increaseIndentPattern": "^\\s*.*(:|-) ?(&\\w+)?(\\{[^}\"']*|\\([^)\"']*)?$", "decreaseIndentPattern": "^\\s+\\}$" } } ================================================ FILE: extensions/docker/package.json ================================================ { "name": "docker", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "*" }, "scripts": { "update-grammar": "node ../node_modules/vscode-grammar-updater/bin moby/moby contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage ./syntaxes/docker.tmLanguage.json" }, "categories": ["Programming Languages"], "contributes": { "languages": [ { "id": "dockerfile", "extensions": [ ".dockerfile", ".containerfile" ], "filenames": [ "Dockerfile", "Containerfile" ], "filenamePatterns": [ "Dockerfile.*", "Containerfile.*" ], "aliases": [ "Docker", "Dockerfile", "Containerfile" ], "configuration": "./language-configuration.json" } ], "grammars": [ { "language": "dockerfile", "scopeName": "source.dockerfile", "path": "./syntaxes/docker.tmLanguage.json" } ], "configurationDefaults": { "[dockerfile]": { "editor.quickSuggestions": { "strings": true } } } }, "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" } } ================================================ FILE: extensions/docker/package.nls.json ================================================ { "displayName": "Docker Language Basics", "description": "Provides syntax highlighting and bracket matching in Docker files." } ================================================ FILE: extensions/docker/syntaxes/docker.tmLanguage.json ================================================ { "information_for_contributors": [ "This file has been converted from https://github.com/moby/moby/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], "version": "https://github.com/moby/moby/commit/c2029cb2574647e4bc28ed58486b8e85883eedb9", "name": "Dockerfile", "scopeName": "source.dockerfile", "patterns": [ { "captures": { "1": { "name": "keyword.other.special-method.dockerfile" }, "2": { "name": "keyword.other.special-method.dockerfile" } }, "match": "^\\s*\\b(?i:(FROM))\\b.*?\\b(?i:(AS))\\b" }, { "captures": { "1": { "name": "keyword.control.dockerfile" }, "2": { "name": "keyword.other.special-method.dockerfile" } }, "match": "^\\s*(?i:(ONBUILD)\\s+)?(?i:(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR))\\s" }, { "captures": { "1": { "name": "keyword.operator.dockerfile" }, "2": { "name": "keyword.other.special-method.dockerfile" } }, "match": "^\\s*(?i:(ONBUILD)\\s+)?(?i:(CMD|ENTRYPOINT))\\s" }, { "include": "#string-character-escape" }, { "begin": "\"", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.dockerfile" } }, "end": "\"", "endCaptures": { "1": { "name": "punctuation.definition.string.end.dockerfile" } }, "name": "string.quoted.double.dockerfile", "patterns": [ { "include": "#string-character-escape" } ] }, { "begin": "'", "beginCaptures": { "1": { "name": "punctuation.definition.string.begin.dockerfile" } }, "end": "'", "endCaptures": { "1": { "name": "punctuation.definition.string.end.dockerfile" } }, "name": "string.quoted.single.dockerfile", "patterns": [ { "include": "#string-character-escape" } ] }, { "captures": { "1": { "name": "punctuation.whitespace.comment.leading.dockerfile" }, "2": { "name": "comment.line.number-sign.dockerfile" }, "3": { "name": "punctuation.definition.comment.dockerfile" } }, "comment": "comment.line", "match": "^(\\s*)((#).*$\\n?)" } ], "repository": { "string-character-escape": { "name": "constant.character.escaped.dockerfile", "match": "\\\\." } } } ================================================ FILE: extensions/emmet/.npmrc ================================================ legacy-peer-deps="true" timeout=180000 ================================================ FILE: extensions/emmet/.vscode/launch.json ================================================ { // Use IntelliSense to learn about possible Node.js debug attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "extensionHost", "request": "launch", "name": "Launch Extension", "runtimeExecutable": "${execPath}", "args": ["--extensionDevelopmentPath=${workspaceFolder}"], "sourceMaps": true, "outFiles": ["${workspaceFolder}/out/**/*.js"] }, { "type": "extensionHost", "request": "launch", "name": "Launch Tests", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test", "--disable-extensions" ], "sourceMaps": true, "outFiles": ["${workspaceFolder}/out/**/*.js"] } ] } ================================================ FILE: extensions/emmet/.vscode/settings.json ================================================ { "emmet.excludeLanguages": [] } ================================================ FILE: extensions/emmet/.vscodeignore ================================================ test/** test-workspace/** src/** out/** tsconfig.json extension.webpack.config.js extension-browser.webpack.config.js CONTRIBUTING.md cgmanifest.json package-lock.json .vscode ================================================ FILE: extensions/emmet/CONTRIBUTING.md ================================================ ## How to build and run from source? Read the basics about extension authoring from [Extending Visual Studio Code](https://code.visualstudio.com/docs/extensions/overview) - Read [Build and Run VS Code from Source](https://github.com/microsoft/vscode/wiki/How-to-Contribute#build-and-run-from-source) to get a local dev set up running for VS Code - Open the `extensions/emmet` folder in the vscode repo in VS Code - Press F5 to start debugging ## Running tests Tests for Emmet extension are run as integration tests as part of VS Code. - Read [Build and Run VS Code from Source](https://github.com/microsoft/vscode/wiki/How-to-Contribute#build-and-run-from-source) to get a local dev set up running for VS Code - Run `./scripts/test-integration.sh` to run all the integrations tests that include the Emmet tests. ================================================ FILE: extensions/emmet/README.md ================================================ # Emmet integration in Visual Studio Code **Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled. ## Features See [Emmet in Visual Studio Code](https://code.visualstudio.com/docs/editor/emmet) to learn about the features of this extension. Please read the [CONTRIBUTING.md](https://github.com/microsoft/vscode/blob/master/extensions/emmet/CONTRIBUTING.md) file to learn how to contribute to this extension. ================================================ FILE: extensions/emmet/cgmanifest.json ================================================ { "registrations": [ { "component": { "type": "git", "git": { "name": "expand-abbreviation", "repositoryUrl": "https://github.com/emmetio/expand-abbreviation", "commitHash": "ef943f2056572fe43ce9eebf72929d3c825f3995" } }, "license": "MIT", "version": "0.5.8" } ], "version": 1 } ================================================ FILE: extensions/emmet/extension-browser.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const withBrowserDefaults = require('../shared.webpack.config').browser; module.exports = withBrowserDefaults({ context: __dirname, entry: { extension: './src/browser/emmetBrowserMain.ts' }, output: { filename: 'emmetBrowserMain.js' } }); ================================================ FILE: extensions/emmet/extension.webpack.config.js ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ //@ts-check 'use strict'; const path = require('path'); const withDefaults = require('../shared.webpack.config'); module.exports = withDefaults({ context: __dirname, entry: { extension: './src/node/emmetNodeMain.ts', }, output: { path: path.join(__dirname, 'dist', 'node'), filename: 'emmetNodeMain.js' } }); ================================================ FILE: extensions/emmet/package.json ================================================ { "name": "emmet", "displayName": "Emmet", "description": "%description%", "version": "1.0.0", "publisher": "vscode", "license": "MIT", "engines": { "vscode": "^1.13.0" }, "icon": "images/icon.png", "categories": [ "Other" ], "repository": { "type": "git", "url": "https://github.com/microsoft/vscode.git" }, "activationEvents": [ "onCommand:emmet.expandAbbreviation", "onLanguage" ], "main": "./out/node/emmetNodeMain", "browser": "./dist/browser/emmetBrowserMain", "contributes": { "configuration": { "type": "object", "title": "Emmet", "properties": { "emmet.showExpandedAbbreviation": { "type": [ "string" ], "enum": [ "never", "always", "inMarkupAndStylesheetFilesOnly" ], "default": "always", "markdownDescription": "%emmetShowExpandedAbbreviation%" }, "emmet.showAbbreviationSuggestions": { "type": "boolean", "default": true, "scope": "language-overridable", "markdownDescription": "%emmetShowAbbreviationSuggestions%" }, "emmet.includeLanguages": { "type": "object", "additionalProperties": { "type": "string" }, "default": {}, "markdownDescription": "%emmetIncludeLanguages%" }, "emmet.variables": { "type": "object", "properties": { "lang": { "type": "string", "default": "en" }, "charset": { "type": "string", "default": "UTF-8" } }, "additionalProperties": { "type": "string" }, "default": {}, "markdownDescription": "%emmetVariables%" }, "emmet.syntaxProfiles": { "type": "object", "default": {}, "markdownDescription": "%emmetSyntaxProfiles%" }, "emmet.excludeLanguages": { "type": "array", "items": { "type": "string" }, "default": [ "markdown" ], "markdownDescription": "%emmetExclude%" }, "emmet.extensionsPath": { "type": "array", "items": { "type": "string", "markdownDescription": "%emmetExtensionsPathItem%" }, "default": [], "scope": "machine-overridable", "markdownDescription": "%emmetExtensionsPath%" }, "emmet.triggerExpansionOnTab": { "type": "boolean", "default": false, "scope": "language-overridable", "markdownDescription": "%emmetTriggerExpansionOnTab%" }, "emmet.useInlineCompletions": { "type": "boolean", "default": false, "markdownDescription": "%emmetUseInlineCompletions%" }, "emmet.preferences": { "type": "object", "default": {}, "markdownDescription": "%emmetPreferences%", "properties": { "css.intUnit": { "type": "string", "default": "px", "markdownDescription": "%emmetPreferencesIntUnit%" }, "css.floatUnit": { "type": "string", "default": "em", "markdownDescription": "%emmetPreferencesFloatUnit%" }, "css.propertyEnd": { "type": "string", "default": ";", "markdownDescription": "%emmetPreferencesCssAfter%" }, "sass.propertyEnd": { "type": "string", "default": "", "markdownDescription": "%emmetPreferencesSassAfter%" }, "stylus.propertyEnd": { "type": "string", "default": "", "markdownDescription": "%emmetPreferencesStylusAfter%" }, "css.valueSeparator": { "type": "string", "default": ": ", "markdownDescription": "%emmetPreferencesCssBetween%" }, "sass.valueSeparator": { "type": "string", "default": ": ", "markdownDescription": "%emmetPreferencesSassBetween%" }, "stylus.valueSeparator": { "type": "string", "default": " ", "markdownDescription": "%emmetPreferencesStylusBetween%" }, "bem.elementSeparator": { "type": "string", "default": "__", "markdownDescription": "%emmetPreferencesBemElementSeparator%" }, "bem.modifierSeparator": { "type": "string", "default": "_", "markdownDescription": "%emmetPreferencesBemModifierSeparator%" }, "filter.commentBefore": { "type": "string", "default": "", "markdownDescription": "%emmetPreferencesFilterCommentBefore%" }, "filter.commentAfter": { "type": "string", "default": "\n", "markdownDescription": "%emmetPreferencesFilterCommentAfter%" }, "filter.commentTrigger": { "type": "array", "default": [ "id", "class" ], "markdownDescription": "%emmetPreferencesFilterCommentTrigger%" }, "format.noIndentTags": { "type": "array", "default": [ "html" ], "markdownDescription": "%emmetPreferencesFormatNoIndentTags%" }, "format.forceIndentationForTags": { "type": "array", "default": [ "body" ], "markdownDescription": "%emmetPreferencesFormatForceIndentTags%" }, "profile.allowCompactBoolean": { "type": "boolean", "default": false, "markdownDescription": "%emmetPreferencesAllowCompactBoolean%" }, "css.webkitProperties": { "type": "string", "default": null, "markdownDescription": "%emmetPreferencesCssWebkitProperties%" }, "css.mozProperties": { "type": "string", "default": null, "markdownDescription": "%emmetPreferencesCssMozProperties%" }, "css.oProperties": { "type": "string", "default": null, "markdownDescription": "%emmetPreferencesCssOProperties%" }, "css.msProperties": { "type": "string", "default": null, "markdownDescription": "%emmetPreferencesCssMsProperties%" }, "css.fuzzySearchMinScore": { "type": "number", "default": 0.3, "markdownDescription": "%emmetPreferencesCssFuzzySearchMinScore%" }, "output.inlineBreak": { "type": "number", "default": 0, "markdownDescription": "%emmetPreferencesOutputInlineBreak%" }, "output.reverseAttributes": { "type": "boolean", "default": false, "markdownDescription": "%emmetPreferencesOutputReverseAttributes%" }, "output.selfClosingStyle": { "type": "string", "enum": [ "html", "xhtml", "xml" ], "default": "html", "markdownDescription": "%emmetPreferencesOutputSelfClosingStyle%" }, "css.color.short": { "type": "boolean", "default": true, "markdownDescription": "%emmetPreferencesCssColorShort%" } } }, "emmet.showSuggestionsAsSnippets": { "type": "boolean", "default": false, "markdownDescription": "%emmetShowSuggestionsAsSnippets%" }, "emmet.optimizeStylesheetParsing": { "type": "boolean", "default": true, "markdownDescription": "%emmetOptimizeStylesheetParsing%" } } }, "commands": [ { "command": "editor.emmet.action.wrapWithAbbreviation", "title": "%command.wrapWithAbbreviation%", "category": "Emmet" }, { "command": "editor.emmet.action.removeTag", "title": "%command.removeTag%", "category": "Emmet" }, { "command": "editor.emmet.action.updateTag", "title": "%command.updateTag%", "category": "Emmet" }, { "command": "editor.emmet.action.matchTag", "title": "%command.matchTag%", "category": "Emmet" }, { "command": "editor.emmet.action.balanceIn", "title": "%command.balanceIn%", "category": "Emmet" }, { "command": "editor.emmet.action.balanceOut", "title": "%command.balanceOut%", "category": "Emmet" }, { "command": "editor.emmet.action.prevEditPoint", "title": "%command.prevEditPoint%", "category": "Emmet" }, { "command": "editor.emmet.action.nextEditPoint", "title": "%command.nextEditPoint%", "category": "Emmet" }, { "command": "editor.emmet.action.mergeLines", "title": "%command.mergeLines%", "category": "Emmet" }, { "command": "editor.emmet.action.selectPrevItem", "title": "%command.selectPrevItem%", "category": "Emmet" }, { "command": "editor.emmet.action.selectNextItem", "title": "%command.selectNextItem%", "category": "Emmet" }, { "command": "editor.emmet.action.splitJoinTag", "title": "%command.splitJoinTag%", "category": "Emmet" }, { "command": "editor.emmet.action.toggleComment", "title": "%command.toggleComment%", "category": "Emmet" }, { "command": "editor.emmet.action.evaluateMathExpression", "title": "%command.evaluateMathExpression%", "category": "Emmet" }, { "command": "editor.emmet.action.updateImageSize", "title": "%command.updateImageSize%", "category": "Emmet" }, { "command": "editor.emmet.action.incrementNumberByOneTenth", "title": "%command.incrementNumberByOneTenth%", "category": "Emmet" }, { "command": "editor.emmet.action.incrementNumberByOne", "title": "%command.incrementNumberByOne%", "category": "Emmet" }, { "command": "editor.emmet.action.incrementNumberByTen", "title": "%command.incrementNumberByTen%", "category": "Emmet" }, { "command": "editor.emmet.action.decrementNumberByOneTenth", "title": "%command.decrementNumberByOneTenth%", "category": "Emmet" }, { "command": "editor.emmet.action.decrementNumberByOne", "title": "%command.decrementNumberByOne%", "category": "Emmet" }, { "command": "editor.emmet.action.decrementNumberByTen", "title": "%command.decrementNumberByTen%", "category": "Emmet" }, { "command": "editor.emmet.action.reflectCSSValue", "title": "%command.reflectCSSValue%", "category": "Emmet" }, { "command": "workbench.action.showEmmetCommands", "title": "%command.showEmmetCommands%", "category": "" } ], "menus": { "commandPalette": [ { "command": "editor.emmet.action.wrapWithAbbreviation", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.removeTag", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.updateTag", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.matchTag", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.balanceIn", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.balanceOut", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.prevEditPoint", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.nextEditPoint", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.mergeLines", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.selectPrevItem", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.selectNextItem", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.splitJoinTag", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.toggleComment", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.evaluateMathExpression", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.updateImageSize", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.incrementNumberByOneTenth", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.incrementNumberByOne", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.incrementNumberByTen", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.decrementNumberByOneTenth", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.decrementNumberByOne", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.decrementNumberByTen", "when": "!activeEditorIsReadonly" }, { "command": "editor.emmet.action.reflectCSSValue", "when": "!activeEditorIsReadonly" } ] } }, "scripts": { "watch": "gulp watch-extension:emmet", "compile": "gulp compile-extension:emmet", "deps": "npm install @vscode/emmet-helper" }, "devDependencies": { "@types/node": "20.x" }, "dependencies": { "@emmetio/css-parser": "ramya-rao-a/css-parser#vscode", "@emmetio/html-matcher": "^0.3.3", "@emmetio/math-expression": "^1.0.5", "@vscode/emmet-helper": "^2.8.8", "image-size": "~1.0.0", "vscode-languageserver-textdocument": "^1.0.1" }, "capabilities": { "virtualWorkspaces": true, "untrustedWorkspaces": { "supported": true } } } ================================================ FILE: extensions/emmet/package.nls.json ================================================ { "description": "Emmet support for VS Code", "command.wrapWithAbbreviation": "Wrap with Abbreviation", "command.removeTag": "Remove Tag", "command.updateTag": "Update Tag", "command.matchTag": "Go to Matching Pair", "command.balanceIn": "Balance (inward)", "command.balanceOut": "Balance (outward)", "command.prevEditPoint": "Go to Previous Edit Point", "command.nextEditPoint": "Go to Next Edit Point", "command.mergeLines": "Merge Lines", "command.selectPrevItem": "Select Previous Item", "command.selectNextItem": "Select Next Item", "command.splitJoinTag": "Split/Join Tag", "command.toggleComment": "Toggle Comment", "command.evaluateMathExpression": "Evaluate Math Expression", "command.updateImageSize": "Update Image Size", "command.reflectCSSValue": "Reflect CSS Value", "command.incrementNumberByOne": "Increment by 1", "command.decrementNumberByOne": "Decrement by 1", "command.incrementNumberByOneTenth": "Increment by 0.1", "command.decrementNumberByOneTenth": "Decrement by 0.1", "command.incrementNumberByTen": "Increment by 10", "command.decrementNumberByTen": "Decrement by 10", "command.showEmmetCommands": "Show Emmet Commands", "emmetSyntaxProfiles": "Define profile for specified syntax or use your own profile with specific rules.", "emmetExclude": "An array of languages where Emmet abbreviations should not be expanded.", "emmetExtensionsPath": "An array of paths, where each path can contain Emmet syntaxProfiles and/or snippet files.\nIn case of conflicts, the profiles/snippets of later paths will override those of earlier paths.\nSee https://code.visualstudio.com/docs/editor/emmet for more information and an example snippet file.", "emmetExtensionsPathItem": "A path containing Emmet syntaxProfiles and/or snippets.", "emmetShowExpandedAbbreviation": "Shows expanded Emmet abbreviations as suggestions.\nThe option `\"inMarkupAndStylesheetFilesOnly\"` applies to html, haml, jade, slim, xml, xsl, css, scss, sass, less and stylus.\nThe option `\"always\"` applies to all parts of the file regardless of markup/css.", "emmetShowAbbreviationSuggestions": "Shows possible Emmet abbreviations as suggestions. Not applicable in stylesheets or when emmet.showExpandedAbbreviation is set to `\"never\"`.", "emmetIncludeLanguages": "Enable Emmet abbreviations in languages that are not supported by default. Add a mapping here between the language and Emmet supported language.\n For example: `{\"vue-html\": \"html\", \"javascript\": \"javascriptreact\"}`", "emmetVariables": "Variables to be used in Emmet snippets.", "emmetTriggerExpansionOnTab": "When enabled, Emmet abbreviations are expanded when pressing TAB, even when completions do not show up. When disabled, completions that show up can still be accepted by pressing TAB.", "emmetPreferences": "Preferences used to modify behavior of some actions and resolvers of Emmet.", "emmetPreferencesIntUnit": "Default unit for integer values.", "emmetPreferencesFloatUnit": "Default unit for float values.", "emmetPreferencesCssAfter": "Symbol to be placed at the end of CSS property when expanding CSS abbreviations.", "emmetPreferencesSassAfter": "Symbol to be placed at the end of CSS property when expanding CSS abbreviations in Sass files.", "emmetPreferencesStylusAfter": "Symbol to be placed at the end of CSS property when expanding CSS abbreviations in Stylus files.", "emmetPreferencesCssBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations.", "emmetPreferencesSassBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations in Sass files.", "emmetPreferencesStylusBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations in Stylus files.", "emmetShowSuggestionsAsSnippets": "If `true`, then Emmet suggestions will show up as snippets allowing you to order them as per `#editor.snippetSuggestions#` setting.", "emmetPreferencesBemElementSeparator": "Element separator used for classes when using the BEM filter.", "emmetPreferencesBemModifierSeparator": "Modifier separator used for classes when using the BEM filter.", "emmetPreferencesFilterCommentBefore": "A definition of comment that should be placed before matched element when comment filter is applied.", "emmetPreferencesFilterCommentAfter": "A definition of comment that should be placed after matched element when comment filter is applied.", "emmetPreferencesFilterCommentTrigger": "A comma-separated list of attribute names that should exist in the abbreviation for the comment filter to be applied.", "emmetPreferencesFormatNoIndentTags": "An array of tag names that should never get inner indentation.", "emmetPreferencesFormatForceIndentTags": "An array of tag names that should always get inner indentation.", "emmetPreferencesAllowCompactBoolean": "If `true`, compact notation of boolean attributes are produced.", "emmetPreferencesCssWebkitProperties": "Comma separated CSS properties that get the 'webkit' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'webkit' prefix.", "emmetPreferencesCssMozProperties": "Comma separated CSS properties that get the 'moz' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'moz' prefix.", "emmetPreferencesCssOProperties": "Comma separated CSS properties that get the 'o' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'o' prefix.", "emmetPreferencesCssMsProperties": "Comma separated CSS properties that get the 'ms' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'ms' prefix.", "emmetPreferencesCssFuzzySearchMinScore": "The minimum score (from 0 to 1) that fuzzy-matched abbreviation should achieve. Lower values may produce many false-positive matches, higher values may reduce possible matches.", "emmetOptimizeStylesheetParsing": "When set to `false`, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to `true`, only the content around the current position in CSS/SCSS/Less files is parsed.", "emmetPreferencesOutputInlineBreak": "The number of sibling inline elements needed for line breaks to be placed between those elements. If `0`, inline elements are always expanded onto a single line.", "emmetPreferencesOutputReverseAttributes": "If `true`, reverses attribute merging directions when resolving snippets.", "emmetPreferencesOutputSelfClosingStyle": "Style of self-closing tags: html (`
`), xml (`
`) or xhtml (`
`).", "emmetPreferencesCssColorShort": "If `true`, color values like `#f` will be expanded to `#fff` instead of `#ffffff`.", "emmetUseInlineCompletions": "If `true`, Emmet will use inline completions to suggest expansions. To prevent the non-inline completion item provider from showing up as often while this setting is `true`, turn `#editor.quickSuggestions#` to `inline` or `off` for the `other` item." } ================================================ FILE: extensions/emmet/src/abbreviationActions.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { Node, HtmlNode, Rule, Property, Stylesheet } from 'EmmetFlatNode'; import { getEmmetHelper, getFlatNode, getHtmlFlatNode, getMappingForIncludedLanguages, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode, parsePartialStylesheet, isStyleAttribute, getEmbeddedCssNodeIfAny, allowedMimeTypesInScriptTag, toLSTextDocument, isOffsetInsideOpenOrCloseTag } from './util'; import { getRootNode as parseDocument } from './parseDocument'; const trimRegex = /[\u00a0]*[\d#\-\*\u2022]+\.?/; const hexColorRegex = /^#[\da-fA-F]{0,6}$/; interface ExpandAbbreviationInput { syntax: string; abbreviation: string; rangeToReplace: vscode.Range; textToWrap?: string[]; filter?: string; indent?: string; baseIndent?: string; } interface PreviewRangesWithContent { previewRange: vscode.Range; originalRange: vscode.Range; originalContent: string; textToWrapInPreview: string[]; baseIndent: string; } export async function wrapWithAbbreviation(args: any): Promise { if (!validate(false)) { return false; } const editor = vscode.window.activeTextEditor!; const document = editor.document; args = args || {}; if (!args['language']) { args['language'] = document.languageId; } // we know it's not stylesheet due to the validate(false) call above const syntax = getSyntaxFromArgs(args) || 'html'; const rootNode = parseDocument(document, true); const helper = getEmmetHelper(); const operationRanges = Array.from(editor.selections).sort((a, b) => a.start.compareTo(b.start)).map(selection => { let rangeToReplace: vscode.Range = selection; // wrap around the node if the selection falls inside its open or close tag { let { start, end } = rangeToReplace; const startOffset = document.offsetAt(start); const documentText = document.getText(); const startNode = getHtmlFlatNode(documentText, rootNode, startOffset, true); if (startNode && isOffsetInsideOpenOrCloseTag(startNode, startOffset)) { start = document.positionAt(startNode.start); const nodeEndPosition = document.positionAt(startNode.end); end = nodeEndPosition.isAfter(end) ? nodeEndPosition : end; } const endOffset = document.offsetAt(end); const endNode = getHtmlFlatNode(documentText, rootNode, endOffset, true); if (endNode && isOffsetInsideOpenOrCloseTag(endNode, endOffset)) { const nodeStartPosition = document.positionAt(endNode.start); start = nodeStartPosition.isBefore(start) ? nodeStartPosition : start; const nodeEndPosition = document.positionAt(endNode.end); end = nodeEndPosition.isAfter(end) ? nodeEndPosition : end; } rangeToReplace = new vscode.Range(start, end); } // in case of multi-line, exclude last empty line from rangeToReplace if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) { const previousLine = rangeToReplace.end.line - 1; rangeToReplace = new vscode.Range(rangeToReplace.start, document.lineAt(previousLine).range.end); } // wrap line the cursor is on if (rangeToReplace.isEmpty) { rangeToReplace = document.lineAt(rangeToReplace.start).range; } // ignore whitespace on the first line const firstLineOfRange = document.lineAt(rangeToReplace.start); if (!firstLineOfRange.isEmptyOrWhitespace && firstLineOfRange.firstNonWhitespaceCharacterIndex > rangeToReplace.start.character) { rangeToReplace = rangeToReplace.with(new vscode.Position(rangeToReplace.start.line, firstLineOfRange.firstNonWhitespaceCharacterIndex)); } return rangeToReplace; }).reduce((mergedRanges, range) => { // Merge overlapping ranges if (mergedRanges.length > 0 && range.intersection(mergedRanges[mergedRanges.length - 1])) { mergedRanges.push(range.union(mergedRanges.pop()!)); } else { mergedRanges.push(range); } return mergedRanges; }, [] as vscode.Range[]); // Backup orginal selections and update selections // Also helps with https://github.com/microsoft/vscode/issues/113930 by avoiding `editor.linkedEditing` // execution if selection is inside an open or close tag const oldSelections = editor.selections; editor.selections = operationRanges.map(range => new vscode.Selection(range.start, range.end)); // Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents const rangesToReplace: PreviewRangesWithContent[] = operationRanges.map(rangeToReplace => { let textToWrapInPreview: string[]; const textToReplace = document.getText(rangeToReplace); // the following assumes all the lines are indented the same way as the first // this assumption helps with applyPreview later const wholeFirstLine = document.lineAt(rangeToReplace.start).text; const otherMatches = wholeFirstLine.match(/^(\s*)/); const baseIndent = otherMatches ? otherMatches[1] : ''; textToWrapInPreview = rangeToReplace.isSingleLine ? [textToReplace] : textToReplace.split('\n' + baseIndent).map(x => x.trimEnd()); // escape $ characters, fixes #52640 textToWrapInPreview = textToWrapInPreview.map(e => e.replace(/(\$\d)/g, '\\$1')); return { previewRange: rangeToReplace, originalRange: rangeToReplace, originalContent: textToReplace, textToWrapInPreview, baseIndent }; }); const { tabSize, insertSpaces } = editor.options; const indent = insertSpaces ? ' '.repeat(tabSize as number) : '\t'; function revertPreview(): Thenable { return editor.edit(builder => { for (const rangeToReplace of rangesToReplace) { builder.replace(rangeToReplace.previewRange, rangeToReplace.originalContent); rangeToReplace.previewRange = rangeToReplace.originalRange; } }, { undoStopBefore: false, undoStopAfter: false }); } function applyPreview(expandAbbrList: ExpandAbbreviationInput[]): Thenable { let lastOldPreviewRange = new vscode.Range(0, 0, 0, 0); let lastNewPreviewRange = new vscode.Range(0, 0, 0, 0); let totalNewLinesInserted = 0; return editor.edit(builder => { // the edits are applied in order top-down for (let i = 0; i < rangesToReplace.length; i++) { const expandedText = expandAbbr(expandAbbrList[i]) || ''; if (!expandedText) { // Failed to expand text. We already showed an error inside expandAbbr. break; } // get the current preview range, format the new wrapped text, and then replace // the text in the preview range with that new text const oldPreviewRange = rangesToReplace[i].previewRange; const newText = expandedText .replace(/\$\{[\d]*\}/g, '|') // Removing Tabstops .replace(/\$\{[\d]*:([^}]*)\}/g, (_, placeholder) => placeholder) // Replacing Placeholders .replace(/\\\$/g, '$'); // Remove backslashes before $ builder.replace(oldPreviewRange, newText); // calculate the new preview range to use for future previews // we also have to take into account that the previous expansions could: // - cause new lines to appear // - be on the same line as other expansions const expandedTextLines = newText.split('\n'); const oldPreviewLines = oldPreviewRange.end.line - oldPreviewRange.start.line + 1; const newLinesInserted = expandedTextLines.length - oldPreviewLines; const newPreviewLineStart = oldPreviewRange.start.line + totalNewLinesInserted; let newPreviewStart = oldPreviewRange.start.character; const newPreviewLineEnd = oldPreviewRange.end.line + totalNewLinesInserted + newLinesInserted; let newPreviewEnd = expandedTextLines[expandedTextLines.length - 1].length; if (i > 0 && newPreviewLineEnd === lastNewPreviewRange.end.line) { // If newPreviewLineEnd is equal to the previous expandedText lineEnd, // set newPreviewStart to the length of the previous expandedText in that line // plus the number of characters between both selections. newPreviewStart = lastNewPreviewRange.end.character + (oldPreviewRange.start.character - lastOldPreviewRange.end.character); newPreviewEnd += newPreviewStart; } else if (i > 0 && newPreviewLineStart === lastNewPreviewRange.end.line) { // Same as above but expandedTextLines.length > 1 so newPreviewEnd keeps its value. newPreviewStart = lastNewPreviewRange.end.character + (oldPreviewRange.start.character - lastOldPreviewRange.end.character); } else if (expandedTextLines.length === 1) { // If the expandedText is single line, add the length of preceeding text as it will not be included in line length. newPreviewEnd += oldPreviewRange.start.character; } lastOldPreviewRange = rangesToReplace[i].previewRange; lastNewPreviewRange = new vscode.Range(newPreviewLineStart, newPreviewStart, newPreviewLineEnd, newPreviewEnd); rangesToReplace[i].previewRange = lastNewPreviewRange; totalNewLinesInserted += newLinesInserted; } }, { undoStopBefore: false, undoStopAfter: false }); } let inPreviewMode = false; async function makeChanges(inputAbbreviation: string | undefined, previewChanges: boolean): Promise { const isAbbreviationValid = !!inputAbbreviation && !!inputAbbreviation.trim() && helper.isAbbreviationValid(syntax, inputAbbreviation); const extractedResults = isAbbreviationValid ? helper.extractAbbreviationFromText(inputAbbreviation!, syntax) : undefined; if (!extractedResults) { if (inPreviewMode) { inPreviewMode = false; await revertPreview(); } return false; } const { abbreviation, filter } = extractedResults; if (abbreviation !== inputAbbreviation) { // Not clear what should we do in this case. Warn the user? How? } if (previewChanges) { const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => ({ syntax, abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter, indent, baseIndent: rangesAndContent.baseIndent }) ); inPreviewMode = true; return applyPreview(expandAbbrList); } const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => ({ syntax, abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter, indent }) ); if (inPreviewMode) { inPreviewMode = false; await revertPreview(); } return expandAbbreviationInRange(editor, expandAbbrList, false); } let currentValue = ''; async function inputChanged(value: string): Promise { if (value !== currentValue) { currentValue = value; await makeChanges(value, true); } return ''; } const prompt = vscode.l10n.t("Enter Abbreviation"); const inputAbbreviation = (args && args['abbreviation']) ? (args['abbreviation'] as string) : await vscode.window.showInputBox({ prompt, validateInput: inputChanged }); const changesWereMade = await makeChanges(inputAbbreviation, false); if (!changesWereMade) { editor.selections = oldSelections; } return changesWereMade; } export function expandEmmetAbbreviation(args: any): Thenable { if (!validate() || !vscode.window.activeTextEditor) { return fallbackTab(); } /** * Short circuit the parsing. If previous character is space, do not expand. */ if (vscode.window.activeTextEditor.selections.length === 1 && vscode.window.activeTextEditor.selection.isEmpty ) { const anchor = vscode.window.activeTextEditor.selection.anchor; if (anchor.character === 0) { return fallbackTab(); } const prevPositionAnchor = anchor.translate(0, -1); const prevText = vscode.window.activeTextEditor.document.getText(new vscode.Range(prevPositionAnchor, anchor)); if (prevText === ' ' || prevText === '\t') { return fallbackTab(); } } args = args || {}; if (!args['language']) { args['language'] = vscode.window.activeTextEditor.document.languageId; } else { const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ? vscode.workspace.getConfiguration('emmet')['excludeLanguages'] : []; if (excludedLanguages.includes(vscode.window.activeTextEditor.document.languageId)) { return fallbackTab(); } } const syntax = getSyntaxFromArgs(args); if (!syntax) { return fallbackTab(); } const editor = vscode.window.activeTextEditor; // When tabbed on a non empty selection, do not treat it as an emmet abbreviation, and fallback to tab instead if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) { return fallbackTab(); } const abbreviationList: ExpandAbbreviationInput[] = []; let firstAbbreviation: string; let allAbbreviationsSame: boolean = true; const helper = getEmmetHelper(); const getAbbreviation = (document: vscode.TextDocument, selection: vscode.Selection, position: vscode.Position, syntax: string): [vscode.Range | null, string, string | undefined] => { position = document.validatePosition(position); let rangeToReplace: vscode.Range = selection; let abbr = document.getText(rangeToReplace); if (!rangeToReplace.isEmpty) { const extractedResults = helper.extractAbbreviationFromText(abbr, syntax); if (extractedResults) { return [rangeToReplace, extractedResults.abbreviation, extractedResults.filter]; } return [null, '', '']; } const currentLine = editor.document.lineAt(position.line).text; const textTillPosition = currentLine.substr(0, position.character); // Expand cases like

explicitly // else we will end up with <
if (syntax === 'html') { const matches = textTillPosition.match(/<(\w+)$/); if (matches) { abbr = matches[1]; rangeToReplace = new vscode.Range(position.translate(0, -(abbr.length + 1)), position); return [rangeToReplace, abbr, '']; } } const extractedResults = helper.extractAbbreviation(toLSTextDocument(editor.document), position, { lookAhead: false }); if (!extractedResults) { return [null, '', '']; } const { abbreviationRange, abbreviation, filter } = extractedResults; return [new vscode.Range(abbreviationRange.start.line, abbreviationRange.start.character, abbreviationRange.end.line, abbreviationRange.end.character), abbreviation, filter]; }; const selectionsInReverseOrder = editor.selections.slice(0); selectionsInReverseOrder.sort((a, b) => { const posA = a.isReversed ? a.anchor : a.active; const posB = b.isReversed ? b.anchor : b.active; return posA.compareTo(posB) * -1; }); let rootNode: Node | undefined; function getRootNode() { if (rootNode) { return rootNode; } const usePartialParsing = vscode.workspace.getConfiguration('emmet')['optimizeStylesheetParsing'] === true; if (editor.selections.length === 1 && isStyleSheet(editor.document.languageId) && usePartialParsing && editor.document.lineCount > 1000) { rootNode = parsePartialStylesheet(editor.document, editor.selection.isReversed ? editor.selection.anchor : editor.selection.active); } else { rootNode = parseDocument(editor.document, true); } return rootNode; } selectionsInReverseOrder.forEach(selection => { const position = selection.isReversed ? selection.anchor : selection.active; const [rangeToReplace, abbreviation, filter] = getAbbreviation(editor.document, selection, position, syntax); if (!rangeToReplace) { return; } if (!helper.isAbbreviationValid(syntax, abbreviation)) { return; } if (isStyleSheet(syntax) && abbreviation.endsWith(':')) { // Fix for https://github.com/Microsoft/vscode/issues/1623 return; } const offset = editor.document.offsetAt(position); let currentNode = getFlatNode(getRootNode(), offset, true); let validateLocation = true; let syntaxToUse = syntax; if (editor.document.languageId === 'html') { if (isStyleAttribute(currentNode, offset)) { syntaxToUse = 'css'; validateLocation = false; } else { const embeddedCssNode = getEmbeddedCssNodeIfAny(editor.document, currentNode, position); if (embeddedCssNode) { currentNode = getFlatNode(embeddedCssNode, offset, true); syntaxToUse = 'css'; } } } if (validateLocation && !isValidLocationForEmmetAbbreviation(editor.document, getRootNode(), currentNode, syntaxToUse, offset, rangeToReplace)) { return; } if (!firstAbbreviation) { firstAbbreviation = abbreviation; } else if (allAbbreviationsSame && firstAbbreviation !== abbreviation) { allAbbreviationsSame = false; } abbreviationList.push({ syntax: syntaxToUse, abbreviation, rangeToReplace, filter }); }); return expandAbbreviationInRange(editor, abbreviationList, allAbbreviationsSame).then(success => { return success ? Promise.resolve(undefined) : fallbackTab(); }); } function fallbackTab(): Thenable { if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true) { return vscode.commands.executeCommand('tab'); } return Promise.resolve(true); } /** * Checks if given position is a valid location to expand emmet abbreviation. * Works only on html and css/less/scss syntax * @param document current Text Document * @param rootNode parsed document * @param currentNode current node in the parsed document * @param syntax syntax of the abbreviation * @param position position to validate * @param abbreviationRange The range of the abbreviation for which given position is being validated */ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocument, rootNode: Node | undefined, currentNode: Node | undefined, syntax: string, offset: number, abbreviationRange: vscode.Range): boolean { if (isStyleSheet(syntax)) { const stylesheet = rootNode; if (stylesheet && (stylesheet.comments || []).some(x => offset >= x.start && offset <= x.end)) { return false; } // Continue validation only if the file was parse-able and the currentNode has been found if (!currentNode) { return true; } // Get the abbreviation right now // Fixes https://github.com/microsoft/vscode/issues/74505 // Stylesheet abbreviations starting with @ should bring up suggestions // even at outer-most level const abbreviation = document.getText(new vscode.Range(abbreviationRange.start.line, abbreviationRange.start.character, abbreviationRange.end.line, abbreviationRange.end.character)); if (abbreviation.startsWith('@')) { return true; } // Fix for https://github.com/microsoft/vscode/issues/34162 // Other than sass, stylus, we can make use of the terminator tokens to validate position if (syntax !== 'sass' && syntax !== 'stylus' && currentNode.type === 'property') { // Fix for upstream issue https://github.com/emmetio/css-parser/issues/3 if (currentNode.parent && currentNode.parent.type !== 'rule' && currentNode.parent.type !== 'at-rule') { return false; } const propertyNode = currentNode; if (propertyNode.terminatorToken && propertyNode.separator && offset >= propertyNode.separatorToken.end && offset <= propertyNode.terminatorToken.start && !abbreviation.includes(':')) { return hexColorRegex.test(abbreviation) || abbreviation === '!'; } if (!propertyNode.terminatorToken && propertyNode.separator && offset >= propertyNode.separatorToken.end && !abbreviation.includes(':')) { return hexColorRegex.test(abbreviation) || abbreviation === '!'; } if (hexColorRegex.test(abbreviation) || abbreviation === '!') { return false; } } // If current node is a rule or at-rule, then perform additional checks to ensure // emmet suggestions are not provided in the rule selector if (currentNode.type !== 'rule' && currentNode.type !== 'at-rule') { return true; } const currentCssNode = currentNode; // Position is valid if it occurs after the `{` that marks beginning of rule contents if (offset > currentCssNode.contentStartToken.end) { return true; } // Workaround for https://github.com/microsoft/vscode/30188 // The line above the rule selector is considered as part of the selector by the css-parser // But we should assume it is a valid location for css properties under the parent rule if (currentCssNode.parent && (currentCssNode.parent.type === 'rule' || currentCssNode.parent.type === 'at-rule') && currentCssNode.selectorToken) { const position = document.positionAt(offset); const tokenStartPos = document.positionAt(currentCssNode.selectorToken.start); const tokenEndPos = document.positionAt(currentCssNode.selectorToken.end); if (position.line !== tokenEndPos.line && tokenStartPos.character === abbreviationRange.start.character && tokenStartPos.line === abbreviationRange.start.line ) { return true; } } return false; } const startAngle = '<'; const endAngle = '>'; const escape = '\\'; const question = '?'; const currentHtmlNode = currentNode; let start = 0; if (currentHtmlNode) { if (currentHtmlNode.name === 'script') { const typeAttribute = (currentHtmlNode.attributes || []).filter(x => x.name.toString() === 'type')[0]; const typeValue = typeAttribute ? typeAttribute.value.toString() : ''; if (allowedMimeTypesInScriptTag.includes(typeValue)) { return true; } const isScriptJavascriptType = !typeValue || typeValue === 'application/javascript' || typeValue === 'text/javascript'; if (isScriptJavascriptType) { return !!getSyntaxFromArgs({ language: 'javascript' }); } return false; } // Fix for https://github.com/microsoft/vscode/issues/28829 if (!currentHtmlNode.open || !currentHtmlNode.close || !(currentHtmlNode.open.end <= offset && offset <= currentHtmlNode.close.start)) { return false; } // Fix for https://github.com/microsoft/vscode/issues/35128 // Find the position up till where we will backtrack looking for unescaped < or > // to decide if current position is valid for emmet expansion start = currentHtmlNode.open.end; let lastChildBeforePosition = currentHtmlNode.firstChild; while (lastChildBeforePosition) { if (lastChildBeforePosition.end > offset) { break; } start = lastChildBeforePosition.end; lastChildBeforePosition = lastChildBeforePosition.nextSibling; } } const startPos = document.positionAt(start); let textToBackTrack = document.getText(new vscode.Range(startPos.line, startPos.character, abbreviationRange.start.line, abbreviationRange.start.character)); // Worse case scenario is when cursor is inside a big chunk of text which needs to backtracked // Backtrack only 500 offsets to ensure we dont waste time doing this if (textToBackTrack.length > 500) { textToBackTrack = textToBackTrack.substr(textToBackTrack.length - 500); } if (!textToBackTrack.trim()) { return true; } let valid = true; let foundSpace = false; // If < is found before finding whitespace, then its valid abbreviation. E.g.: = 0) { const char = textToBackTrack[i]; i--; if (!foundSpace && /\s/.test(char)) { foundSpace = true; continue; } if (char === question && textToBackTrack[i] === startAngle) { i--; continue; } // Fix for https://github.com/microsoft/vscode/issues/55411 // A space is not a valid character right after < in a tag name. if (/\s/.test(char) && textToBackTrack[i] === startAngle) { i--; continue; } if (char !== startAngle && char !== endAngle) { continue; } if (i >= 0 && textToBackTrack[i] === escape) { i--; continue; } if (char === endAngle) { if (i >= 0 && textToBackTrack[i] === '=') { continue; // False alarm of cases like => } else { break; } } if (char === startAngle) { valid = !foundSpace; break; } } return valid; } /** * Expands abbreviations as detailed in expandAbbrList in the editor * * @returns false if no snippet can be inserted. */ async function expandAbbreviationInRange(editor: vscode.TextEditor, expandAbbrList: ExpandAbbreviationInput[], insertSameSnippet: boolean): Promise { if (!expandAbbrList || expandAbbrList.length === 0) { return false; } // Snippet to replace at multiple cursors are not the same // `editor.insertSnippet` will have to be called for each instance separately // We will not be able to maintain multiple cursors after snippet insertion let insertedSnippetsCount = 0; if (!insertSameSnippet) { expandAbbrList.sort((a: ExpandAbbreviationInput, b: ExpandAbbreviationInput) => { return b.rangeToReplace.start.compareTo(a.rangeToReplace.start); }); for (const expandAbbrInput of expandAbbrList) { const expandedText = expandAbbr(expandAbbrInput); if (expandedText) { await editor.insertSnippet(new vscode.SnippetString(expandedText), expandAbbrInput.rangeToReplace, { undoStopBefore: false, undoStopAfter: false }); insertedSnippetsCount++; } } return insertedSnippetsCount > 0; } // Snippet to replace at all cursors are the same // We can pass all ranges to `editor.insertSnippet` in a single call so that // all cursors are maintained after snippet insertion const anyExpandAbbrInput = expandAbbrList[0]; const expandedText = expandAbbr(anyExpandAbbrInput); const allRanges = expandAbbrList.map(value => value.rangeToReplace); if (expandedText) { return editor.insertSnippet(new vscode.SnippetString(expandedText), allRanges); } return false; } /** * Expands abbreviation as detailed in given input. */ function expandAbbr(input: ExpandAbbreviationInput): string | undefined { const helper = getEmmetHelper(); const expandOptions = helper.getExpandOptions(input.syntax, getEmmetConfiguration(input.syntax), input.filter); if (input.textToWrap) { // escape ${ sections, fixes #122231 input.textToWrap = input.textToWrap.map(e => e.replace(/\$\{/g, '\\\$\{')); if (input.filter && input.filter.includes('t')) { input.textToWrap = input.textToWrap.map(line => { return line.replace(trimRegex, '').trim(); }); } expandOptions['text'] = input.textToWrap; if (expandOptions.options) { // Below fixes https://github.com/microsoft/vscode/issues/29898 // With this, Emmet formats inline elements as block elements // ensuring the wrapped multi line text does not get merged to a single line if (!input.rangeToReplace.isSingleLine) { expandOptions.options['output.inlineBreak'] = 1; } if (input.indent) { expandOptions.options['output.indent'] = input.indent; } if (input.baseIndent) { expandOptions.options['output.baseIndent'] = input.baseIndent; } } } let expandedText: string | undefined; try { expandedText = helper.expandAbbreviation(input.abbreviation, expandOptions); } catch (e) { void vscode.window.showErrorMessage('Failed to expand abbreviation'); } return expandedText; } export function getSyntaxFromArgs(args: { [x: string]: string }): string | undefined { const mappedModes = getMappingForIncludedLanguages(); const language: string = args['language']; const parentMode: string = args['parentMode']; const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ? vscode.workspace.getConfiguration('emmet')['excludeLanguages'] : []; if (excludedLanguages.includes(language)) { return; } let syntax = getEmmetMode(mappedModes[language] ?? language, mappedModes, excludedLanguages); if (!syntax) { syntax = getEmmetMode(mappedModes[parentMode] ?? parentMode, mappedModes, excludedLanguages); } return syntax; } ================================================ FILE: extensions/emmet/src/balance.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { getHtmlFlatNode, offsetRangeToSelection, validate } from './util'; import { getRootNode } from './parseDocument'; import { HtmlNode as HtmlFlatNode } from 'EmmetFlatNode'; let balanceOutStack: Array = []; let lastBalancedSelections: readonly vscode.Selection[] = []; export function balanceOut() { balance(true); } export function balanceIn() { balance(false); } function balance(out: boolean) { if (!validate(false) || !vscode.window.activeTextEditor) { return; } const editor = vscode.window.activeTextEditor; const document = editor.document; const rootNode = getRootNode(document, true); if (!rootNode) { return; } const rangeFn = out ? getRangeToBalanceOut : getRangeToBalanceIn; let newSelections: readonly vscode.Selection[] = editor.selections.map(selection => { return rangeFn(document, rootNode, selection); }); // check whether we are starting a balance elsewhere if (areSameSelections(lastBalancedSelections, editor.selections)) { // we are not starting elsewhere, so use the stack as-is if (out) { // make sure we are able to expand outwards if (!areSameSelections(editor.selections, newSelections)) { balanceOutStack.push(editor.selections); } } else if (balanceOutStack.length) { newSelections = balanceOutStack.pop()!; } } else { // we are starting elsewhere, so reset the stack balanceOutStack = out ? [editor.selections] : []; } editor.selections = newSelections; lastBalancedSelections = editor.selections; } function getRangeToBalanceOut(document: vscode.TextDocument, rootNode: HtmlFlatNode, selection: vscode.Selection): vscode.Selection { const offset = document.offsetAt(selection.start); const nodeToBalance = getHtmlFlatNode(document.getText(), rootNode, offset, false); if (!nodeToBalance) { return selection; } if (!nodeToBalance.open || !nodeToBalance.close) { return offsetRangeToSelection(document, nodeToBalance.start, nodeToBalance.end); } // Set reverse direction if we were in the end tag let innerSelection: vscode.Selection; let outerSelection: vscode.Selection; if (nodeToBalance.close.start <= offset && nodeToBalance.close.end > offset) { innerSelection = offsetRangeToSelection(document, nodeToBalance.close.start, nodeToBalance.open.end); outerSelection = offsetRangeToSelection(document, nodeToBalance.close.end, nodeToBalance.open.start); } else { innerSelection = offsetRangeToSelection(document, nodeToBalance.open.end, nodeToBalance.close.start); outerSelection = offsetRangeToSelection(document, nodeToBalance.open.start, nodeToBalance.close.end); } if (innerSelection.contains(selection) && !innerSelection.isEqual(selection)) { return innerSelection; } if (outerSelection.contains(selection) && !outerSelection.isEqual(selection)) { return outerSelection; } return selection; } function getRangeToBalanceIn(document: vscode.TextDocument, rootNode: HtmlFlatNode, selection: vscode.Selection): vscode.Selection { const offset = document.offsetAt(selection.start); const nodeToBalance = getHtmlFlatNode(document.getText(), rootNode, offset, true); if (!nodeToBalance) { return selection; } const selectionStart = document.offsetAt(selection.start); const selectionEnd = document.offsetAt(selection.end); if (nodeToBalance.open && nodeToBalance.close) { const entireNodeSelected = selectionStart === nodeToBalance.start && selectionEnd === nodeToBalance.end; const startInOpenTag = selectionStart > nodeToBalance.open.start && selectionStart < nodeToBalance.open.end; const startInCloseTag = selectionStart > nodeToBalance.close.start && selectionStart < nodeToBalance.close.end; if (entireNodeSelected || startInOpenTag || startInCloseTag) { return offsetRangeToSelection(document, nodeToBalance.open.end, nodeToBalance.close.start); } } if (!nodeToBalance.firstChild) { return selection; } const firstChild = nodeToBalance.firstChild; if (selectionStart === firstChild.start && selectionEnd === firstChild.end && firstChild.open && firstChild.close) { return offsetRangeToSelection(document, firstChild.open.end, firstChild.close.start); } return offsetRangeToSelection(document, firstChild.start, firstChild.end); } function areSameSelections(a: readonly vscode.Selection[], b: readonly vscode.Selection[]): boolean { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!a[i].isEqual(b[i])) { return false; } } return true; } ================================================ FILE: extensions/emmet/src/browser/emmetBrowserMain.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { activateEmmetExtension } from '../emmetCommon'; export function activate(context: vscode.ExtensionContext) { activateEmmetExtension(context); } ================================================ FILE: extensions/emmet/src/bufferStream.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /* Based on @sergeche's work in his emmet plugin */ import { TextDocument } from 'vscode'; /** * A stream reader for VSCode's `TextDocument` * Based on @emmetio/stream-reader and @emmetio/atom-plugin */ export class DocumentStreamReader { private document: TextDocument; private start: number; private _eof: number; private _sof: number; public pos: number; constructor(document: TextDocument, pos?: number, limit?: [number, number]) { this.document = document; this.start = this.pos = pos ? pos : 0; this._sof = limit ? limit[0] : 0; this._eof = limit ? limit[1] : document.getText().length; } /** * Returns true only if the stream is at the start of the file. */ sof(): boolean { return this.pos <= this._sof; } /** * Returns true only if the stream is at the end of the file. */ eof(): boolean { return this.pos >= this._eof; } /** * Creates a new stream instance which is limited to given range for given document */ limit(start: number, end: number): DocumentStreamReader { return new DocumentStreamReader(this.document, start, [start, end]); } /** * Returns the next character code in the stream without advancing it. * Will return NaN at the end of the file. */ peek(): number { if (this.eof()) { return NaN; } return this.document.getText().charCodeAt(this.pos); } /** * Returns the next character in the stream and advances it. * Also returns NaN when no more characters are available. */ next(): number { if (this.eof()) { return NaN; } const code = this.document.getText().charCodeAt(this.pos); this.pos++; if (this.eof()) { // restrict pos to eof, if in case it got moved beyond eof this.pos = this._eof; } return code; } /** * Backs up the stream n characters. Backing it up further than the * start of the current token will cause things to break, so be careful. */ backUp(n: number): number { this.pos -= n; if (this.pos < 0) { this.pos = 0; } return this.peek(); } /** * Get the string between the start of the current token and the * current stream position. */ current(): string { return this.substring(this.start, this.pos); } /** * Returns contents for given range */ substring(from: number, to: number): string { return this.document.getText().substring(from, to); } /** * Creates error object with current stream state */ error(message: string): Error { const err = new Error(`${message} at offset ${this.pos}`); return err; } /** * `match` can be a character code or a function that takes a character code * and returns a boolean. If the next character in the stream 'matches' * the given argument, it is consumed and returned. * Otherwise, `false` is returned. */ eat(match: number | Function): boolean { const ch = this.peek(); const ok = typeof match === 'function' ? match(ch) : ch === match; if (ok) { this.next(); } return ok; } /** * Repeatedly calls eat with the given argument, until it * fails. Returns true if any characters were eaten. */ eatWhile(match: number | Function): boolean { const start = this.pos; while (!this.eof() && this.eat(match)) { } return this.pos !== start; } } ================================================ FILE: extensions/emmet/src/defaultCompletionProvider.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import { Node, Stylesheet } from 'EmmetFlatNode'; import { isValidLocationForEmmetAbbreviation, getSyntaxFromArgs } from './abbreviationActions'; import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, getFlatNode, allowedMimeTypesInScriptTag, toLSTextDocument, getHtmlFlatNode, getEmbeddedCssNodeIfAny } from './util'; import { Range as LSRange } from 'vscode-languageserver-textdocument'; import { getRootNode } from './parseDocument'; export class DefaultCompletionItemProvider implements vscode.CompletionItemProvider { private lastCompletionType: string | undefined; public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, _: vscode.CancellationToken, context: vscode.CompletionContext): Thenable | undefined { const completionResult = this.provideCompletionItemsInternal(document, position, context); if (!completionResult) { this.lastCompletionType = undefined; return; } return completionResult.then(completionList => { if (!completionList || !completionList.items.length) { this.lastCompletionType = undefined; return completionList; } const item = completionList.items[0]; const expandedText = item.documentation ? item.documentation.toString() : ''; if (expandedText.startsWith('<')) { this.lastCompletionType = 'html'; } else if (expandedText.indexOf(':') > 0 && expandedText.endsWith(';')) { this.lastCompletionType = 'css'; } else { this.lastCompletionType = undefined; } return completionList; }); } private provideCompletionItemsInternal(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext): Thenable | undefined { const emmetConfig = vscode.workspace.getConfiguration('emmet'); const excludedLanguages = emmetConfig['excludeLanguages'] ? emmetConfig['excludeLanguages'] : []; if (excludedLanguages.includes(document.languageId)) { return; } const mappedLanguages = getMappingForIncludedLanguages(); const isSyntaxMapped = mappedLanguages[document.languageId] ? true : false; const emmetMode = getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), mappedLanguages, excludedLanguages); if (!emmetMode || emmetConfig['showExpandedAbbreviation'] === 'never' || ((isSyntaxMapped || emmetMode === 'jsx') && emmetConfig['showExpandedAbbreviation'] !== 'always')) { return; } let syntax = emmetMode; let validateLocation = syntax === 'html' || syntax === 'jsx' || syntax === 'xml'; let rootNode: Node | undefined; let currentNode: Node | undefined; const lsDoc = toLSTextDocument(document); position = document.validatePosition(position); // Don't show completions if there's a comment at the beginning of the line const lineRange = new vscode.Range(position.line, 0, position.line, position.character); if (document.getText(lineRange).trimStart().startsWith('//')) { return; } const helper = getEmmetHelper(); if (syntax === 'html') { if (context.triggerKind === vscode.CompletionTriggerKind.TriggerForIncompleteCompletions) { switch (this.lastCompletionType) { case 'html': validateLocation = false; break; case 'css': validateLocation = false; syntax = 'css'; break; default: break; } } if (validateLocation) { const positionOffset = document.offsetAt(position); const emmetRootNode = getRootNode(document, true); const foundNode = getHtmlFlatNode(document.getText(), emmetRootNode, positionOffset, false); if (foundNode) { if (foundNode.name === 'script') { const typeNode = foundNode.attributes.find(attr => attr.name.toString() === 'type'); if (typeNode) { const typeAttrValue = typeNode.value.toString(); if (typeAttrValue === 'application/javascript' || typeAttrValue === 'text/javascript') { if (!getSyntaxFromArgs({ language: 'javascript' })) { return; } else { validateLocation = false; } } else if (allowedMimeTypesInScriptTag.includes(typeAttrValue)) { validateLocation = false; } } else { return; } } else if (foundNode.name === 'style') { syntax = 'css'; validateLocation = false; } else { const styleNode = foundNode.attributes.find(attr => attr.name.toString() === 'style'); if (styleNode && styleNode.value.start <= positionOffset && positionOffset <= styleNode.value.end) { syntax = 'css'; validateLocation = false; } } } } } const expandOptions = isStyleSheet(syntax) ? { lookAhead: false, syntax: 'stylesheet' } : { lookAhead: true, syntax: 'markup' }; const extractAbbreviationResults = helper.extractAbbreviation(lsDoc, position, expandOptions); if (!extractAbbreviationResults || !helper.isAbbreviationValid(syntax, extractAbbreviationResults.abbreviation)) { return; } const offset = document.offsetAt(position); if (isStyleSheet(document.languageId) && context.triggerKind !== vscode.CompletionTriggerKind.TriggerForIncompleteCompletions) { validateLocation = true; const usePartialParsing = vscode.workspace.getConfiguration('emmet')['optimizeStylesheetParsing'] === true; rootNode = usePartialParsing && document.lineCount > 1000 ? parsePartialStylesheet(document, position) : getRootNode(document, true); if (!rootNode) { return; } currentNode = getFlatNode(rootNode, offset, true); } // Fix for https://github.com/microsoft/vscode/issues/107578 // Validate location if syntax is of styleSheet type to ensure that location is valid for emmet abbreviation. // For an html document containing a (ul>li.item$)*2 (ul>li.item$)*2+span (div>dl>(dt+dd)*2) `; const invokeCompletionContext: CompletionContext = { triggerKind: CompletionTriggerKind.Invoke, triggerCharacter: undefined, }; suite('Tests for Expand Abbreviations (HTML)', () => { teardown(closeAllEditors); test('Expand snippets (HTML)', () => { return testExpandAbbreviation('html', new Selection(3, 23, 3, 23), 'img', '\"\"'); }); test('Expand snippets in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(3, 23, 3, 23), 'img', '\"\"'); }); test('Expand snippets when no parent node (HTML)', () => { return withRandomFileEditor('img', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 3, 0, 3); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), '\"\"'); return Promise.resolve(); }); }); test('Expand snippets when no parent node in completion list (HTML)', () => { return withRandomFileEditor('img', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 3, 0, 3); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { assert.strictEqual(!completionPromise, false, `Got unexpected undefined instead of a completion promise`); return Promise.resolve(); } const completionList = await completionPromise; assert.strictEqual(completionList && completionList.items && completionList.items.length > 0, true); if (completionList) { assert.strictEqual(completionList.items[0].label, 'img'); assert.strictEqual(((completionList.items[0].documentation) || '').replace(/\|/g, ''), '\"\"'); } return Promise.resolve(); }); }); test('Expand abbreviation (HTML)', () => { return testExpandAbbreviation('html', new Selection(5, 25, 5, 25), 'ul>li', '
    \n\t\t\t
  • \n\t\t
'); }); test('Expand abbreviation in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(5, 25, 5, 25), 'ul>li', '
    \n\t
  • \n
'); }); test('Expand text that is neither an abbreviation nor a snippet to tags (HTML)', () => { return testExpandAbbreviation('html', new Selection(4, 20, 4, 27), 'hithere', ''); }); test('Do not Expand text that is neither an abbreviation nor a snippet to tags in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(4, 20, 4, 27), 'hithere', '', true); }); test('Expand abbreviation with repeaters (HTML)', () => { return testExpandAbbreviation('html', new Selection(6, 27, 6, 27), 'ul>li*2', '
    \n\t\t\t
  • \n\t\t\t
  • \n\t\t
'); }); test('Expand abbreviation with repeaters in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(6, 27, 6, 27), 'ul>li*2', '
    \n\t
  • \n\t
  • \n
'); }); test('Expand abbreviation with numbered repeaters (HTML)', () => { return testExpandAbbreviation('html', new Selection(7, 33, 7, 33), 'ul>li.item$*2', '
    \n\t\t\t
  • \n\t\t\t
  • \n\t\t
'); }); test('Expand abbreviation with numbered repeaters in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(7, 33, 7, 33), 'ul>li.item$*2', '
    \n\t
  • \n\t
  • \n
'); }); test('Expand abbreviation with numbered repeaters with offset (HTML)', () => { return testExpandAbbreviation('html', new Selection(8, 36, 8, 36), 'ul>li.item$@44*2', '
    \n\t\t\t
  • \n\t\t\t
  • \n\t\t
'); }); test('Expand abbreviation with numbered repeaters with offset in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(8, 36, 8, 36), 'ul>li.item$@44*2', '
    \n\t
  • \n\t
  • \n
'); }); test('Expand abbreviation with numbered repeaters in groups (HTML)', () => { return testExpandAbbreviation('html', new Selection(17, 16, 17, 16), '(ul>li.item$)*2', '
    \n\t\t
  • \n\t
\n\t
    \n\t\t
  • \n\t
'); }); test('Expand abbreviation with numbered repeaters in groups in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(17, 16, 17, 16), '(ul>li.item$)*2', '
    \n\t
  • \n
\n
    \n\t
  • \n
'); }); test('Expand abbreviation with numbered repeaters in groups with sibling in the end (HTML)', () => { return testExpandAbbreviation('html', new Selection(18, 21, 18, 21), '(ul>li.item$)*2+span', '
    \n\t\t
  • \n\t
\n\t
    \n\t\t
  • \n\t
\n\t'); }); test('Expand abbreviation with numbered repeaters in groups with sibling in the end in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(18, 21, 18, 21), '(ul>li.item$)*2+span', '
    \n\t
  • \n
\n
    \n\t
  • \n
\n'); }); test('Expand abbreviation with nested groups (HTML)', () => { return testExpandAbbreviation('html', new Selection(19, 19, 19, 19), '(div>dl>(dt+dd)*2)', '
\n\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t
\n\t\t
\n\t
'); }); test('Expand abbreviation with nested groups in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(19, 19, 19, 19), '(div>dl>(dt+dd)*2)', '
\n\t
\n\t\t
\n\t\t
\n\t\t
\n\t\t
\n\t
\n
'); }); test('Expand tag that is opened, but not closed (HTML)', () => { return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), ''); }); test('Do not Expand tag that is opened, but not closed in completion list (HTML)', () => { return testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', true); }); test('No expanding text inside open tag (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(2, 4, 2, 4); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), htmlContents); return Promise.resolve(); }); }); test('No expanding text inside open tag in completion list (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => { editor.selection = new Selection(2, 4, 2, 4); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); return Promise.resolve(); }); }); test('No expanding text inside open tag when there is no closing tag (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(9, 8, 9, 8); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), htmlContents); return Promise.resolve(); }); }); test('No expanding text inside open tag when there is no closing tag in completion list (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => { editor.selection = new Selection(9, 8, 9, 8); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); return Promise.resolve(); }); }); test('No expanding text inside open tag when there is no closing tag when there is no parent node (HTML)', () => { const fileContents = ' { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), fileContents); return Promise.resolve(); }); }); test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (HTML)', () => { const fileContents = ' { editor.selection = new Selection(0, 6, 0, 6); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); return Promise.resolve(); }); }); test('Expand css when inside style tag (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(13, 16, 13, 19); const expandPromise = expandEmmetAbbreviation({ language: 'css' }); if (!expandPromise) { return Promise.resolve(); } await expandPromise; assert.strictEqual(editor.document.getText(), htmlContents.replace('m10', 'margin: 10px;')); return Promise.resolve(); }); }); test('Expand css when inside style tag in completion list (HTML)', () => { const abbreviation = 'm10'; const expandedText = 'margin: 10px;'; return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(13, 16, 13, 19); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { assert.strictEqual(1, 2, `Problem with expanding m10`); return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding m10`); return Promise.resolve(); } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`); return Promise.resolve(); }); }); test('No expanding text inside style tag if position is not for property name (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(13, 14, 13, 14); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), htmlContents); return Promise.resolve(); }); }); test('Expand css when inside style attribute (HTML)', () => { const styleAttributeContent = '
'; return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => { editor.selection = new Selection(0, 15, 0, 15); const expandPromise = expandEmmetAbbreviation(null); if (!expandPromise) { return Promise.resolve(); } await expandPromise; assert.strictEqual(editor.document.getText(), styleAttributeContent.replace('m10', 'margin: 10px;')); return Promise.resolve(); }); }); test('Expand css when inside style attribute in completion list (HTML)', () => { const abbreviation = 'm10'; const expandedText = 'margin: 10px;'; return withRandomFileEditor('
', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 15, 0, 15); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { assert.strictEqual(1, 2, `Problem with expanding m10`); return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding m10`); return Promise.resolve(); } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`); return Promise.resolve(); }); }); test('Expand html when inside script tag with html type (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(21, 12, 21, 12); const expandPromise = expandEmmetAbbreviation(null); if (!expandPromise) { return Promise.resolve(); } await expandPromise; assert.strictEqual(editor.document.getText(), htmlContents.replace('span.hello', '')); return Promise.resolve(); }); }); test('Expand html in completion list when inside script tag with html type (HTML)', () => { const abbreviation = 'span.hello'; const expandedText = ''; return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(21, 12, 21, 12); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { assert.strictEqual(1, 2, `Problem with expanding span.hello`); return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding span.hello`); return Promise.resolve(); } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`); assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); return Promise.resolve(); }); }); test('No expanding text inside script tag with javascript type (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(24, 12, 24, 12); await expandEmmetAbbreviation(null); assert.strictEqual(editor.document.getText(), htmlContents); return Promise.resolve(); }); }); test('No expanding text in completion list inside script tag with javascript type (HTML)', () => { return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => { editor.selection = new Selection(24, 12, 24, 12); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); return Promise.resolve(); }); }); test('Expand html when inside script tag with javascript type if js is mapped to html (HTML)', async () => { const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global); await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(24, 10, 24, 10); const expandPromise = expandEmmetAbbreviation(null); if (!expandPromise) { return Promise.resolve(); } await expandPromise; assert.strictEqual(editor.document.getText(), htmlContents.replace('span.bye', '')); }); await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global); }); test('Expand html in completion list when inside script tag with javascript type if js is mapped to html (HTML)', async () => { const abbreviation = 'span.bye'; const expandedText = ''; const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global); await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(24, 10, 24, 10); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { assert.strictEqual(1, 2, `Problem with expanding span.bye`); return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding span.bye`); return Promise.resolve(); } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item (${emmetCompletionItem.label}) doesnt match.`); assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); return Promise.resolve(); }); await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global); }); // test('No expanding when html is excluded in the settings', () => { // return workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global).then(() => { // return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), '', '', true).then(() => { // return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global); // }); // }); // }); test('No expanding when html is excluded in the settings in completion list', async () => { const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global); await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true); await workspace.getConfiguration('emmet').update('excludeLanguages', oldConfig, ConfigurationTarget.Global); }); // test('No expanding when php (mapped syntax) is excluded in the settings', () => { // return workspace.getConfiguration('emmet').update('excludeLanguages', ['php'], ConfigurationTarget.Global).then(() => { // return testExpandAbbreviation('php', new Selection(9, 6, 9, 6), '', '', true).then(() => { // return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global); // }); // }); // }); }); suite('Tests for jsx, xml and xsl', () => { const oldValueForSyntaxProfiles = workspace.getConfiguration('emmet').inspect('syntaxProfiles'); teardown(closeAllEditors); test('Expand abbreviation with className instead of class in jsx', () => { return withRandomFileEditor('ul.nav', 'javascriptreact', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'javascriptreact' }); assert.strictEqual(editor.document.getText(), '
    '); return Promise.resolve(); }); }); test('Expand abbreviation with self closing tags for jsx', () => { return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'javascriptreact' }); assert.strictEqual(editor.document.getText(), ''); return Promise.resolve(); }); }); test('Expand abbreviation with single quotes for jsx', async () => { await workspace.getConfiguration('emmet').update('syntaxProfiles', { jsx: { 'attr_quotes': 'single' } }, ConfigurationTarget.Global); return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'javascriptreact' }); assert.strictEqual(editor.document.getText(), '\'\''); return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global); }); }); test('Expand abbreviation with self closing tags for xml', () => { return withRandomFileEditor('img', 'xml', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'xml' }); assert.strictEqual(editor.document.getText(), ''); return Promise.resolve(); }); }); test('Expand abbreviation with no self closing tags for html', () => { return withRandomFileEditor('img', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'html' }); assert.strictEqual(editor.document.getText(), ''); return Promise.resolve(); }); }); test('Expand abbreviation with condition containing less than sign for jsx', () => { return withRandomFileEditor('if (foo < 10) { span.bar', 'javascriptreact', async (editor, _doc) => { editor.selection = new Selection(0, 27, 0, 27); await expandEmmetAbbreviation({ language: 'javascriptreact' }); assert.strictEqual(editor.document.getText(), 'if (foo < 10) { '); return Promise.resolve(); }); }); test('No expanding text inside open tag in completion list (jsx)', () => { return testNoCompletion('jsx', htmlContents, new Selection(2, 4, 2, 4)); }); test('No expanding tag that is opened, but not closed in completion list (jsx)', () => { return testNoCompletion('jsx', htmlContents, new Selection(9, 6, 9, 6)); }); test('No expanding text inside open tag when there is no closing tag in completion list (jsx)', () => { return testNoCompletion('jsx', htmlContents, new Selection(9, 8, 9, 8)); }); test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (jsx)', () => { return testNoCompletion('jsx', ' { return withRandomFileEditor(htmlContents, syntax, async (editor, _doc) => { editor.selection = selection; const expandPromise = expandEmmetAbbreviation(null); if (!expandPromise) { if (!shouldFail) { assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`); } return Promise.resolve(); } await expandPromise; assert.strictEqual(editor.document.getText(), htmlContents.replace(abbreviation, expandedText)); return Promise.resolve(); }); } function testHtmlCompletionProvider(selection: Selection, abbreviation: string, expandedText: string, shouldFail?: boolean): Thenable { return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = selection; const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (!completionPromise) { if (!shouldFail) { assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`); } return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { if (!shouldFail) { assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`); } return Promise.resolve(); } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`); assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); return Promise.resolve(); }); } function testNoCompletion(syntax: string, fileContents: string, selection: Selection): Thenable { return withRandomFileEditor(fileContents, syntax, (editor, _doc) => { editor.selection = selection; const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); return Promise.resolve(); }); } ================================================ FILE: extensions/emmet/src/test/completion.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import 'mocha'; import { CancellationTokenSource, CompletionTriggerKind, Selection } from 'vscode'; import { DefaultCompletionItemProvider } from '../defaultCompletionProvider'; import { closeAllEditors, withRandomFileEditor } from './testUtils'; const completionProvider = new DefaultCompletionItemProvider(); suite('Tests for completion in CSS embedded in HTML', () => { teardown(closeAllEditors); test('style attribute & attribute value in html', async () => { await testCompletionProvider('html', '
    { await testCompletionProvider('html', `
    di|
    `, [ { label: 'div', documentation: `
    |
    ` } ]); }); // https://github.com/microsoft/vscode/issues/86941 test('microsoft/vscode#86941, widows should be completed after width', async () => { await testCompletionProvider('css', `.foo { wi| }`, [ { label: 'width: ;', documentation: `width: |;` } ]); await testCompletionProvider('css', `.foo { wid| }`, [ { label: 'width: ;', documentation: `width: |;` } ]); try { await testCompletionProvider('css', `.foo { wi| }`, [ { label: 'widows: ;', documentation: `widows: |;` } ]); } catch (e) { assert.strictEqual(e.message, "Didn't find completion item with label widows: ;"); } try { await testCompletionProvider('css', `.foo { wid| }`, [ { label: 'widows: ;', documentation: `widows: |;` } ]); } catch (e) { assert.strictEqual(e.message, "Didn't find completion item with label widows: ;"); } await testCompletionProvider('css', `.foo { wido| }`, [ { label: 'widows: ;', documentation: `widows: |;` } ]); }); // https://github.com/microsoft/vscode/issues/117020 test('microsoft/vscode#117020, ! at end of abbreviation should have completion', async () => { await testCompletionProvider('css', `.foo { bdbn!| }`, [ { label: 'border-bottom: none !important;', documentation: `border-bottom: none !important;` } ]); }); // https://github.com/microsoft/vscode/issues/138461 test('microsoft/vscode#138461, JSX array noise', async () => { await testCompletionProvider('jsx', 'a[i]', undefined); await testCompletionProvider('jsx', 'Component[a b]', undefined); await testCompletionProvider('jsx', '[a, b]', undefined); await testCompletionProvider('jsx', '[a=b]', [ { label: '
    ', documentation: '
    |
    ' } ]); }); // https://github.com/microsoft/vscode-emmet-helper/pull/90 test('microsoft/vscode-emmet-helper#90', async () => { await testCompletionProvider('html', 'dialog', [ { label: '', documentation: '|' } ]); }); }); interface TestCompletionItem { label: string; documentation?: string; } function testCompletionProvider(fileExtension: string, contents: string, expectedItems: TestCompletionItem[] | undefined): Thenable { const cursorPos = contents.indexOf('|'); const slicedContents = contents.slice(0, cursorPos) + contents.slice(cursorPos + 1); return withRandomFileEditor(slicedContents, fileExtension, async (editor, _doc) => { const selection = new Selection(editor.document.positionAt(cursorPos), editor.document.positionAt(cursorPos)); editor.selection = selection; const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems( editor.document, editor.selection.active, cancelSrc.token, { triggerKind: CompletionTriggerKind.Invoke, triggerCharacter: undefined } ); if (!completionPromise) { return Promise.resolve(); } const completionList = await completionPromise; if (!completionList || !completionList.items || !completionList.items.length) { if (completionList === undefined) { assert.strictEqual(expectedItems, completionList); } return Promise.resolve(); } assert.strictEqual(expectedItems === undefined, false); expectedItems!.forEach(eItem => { const matches = completionList.items.filter(i => i.label === eItem.label); const match = matches && matches.length > 0 ? matches[0] : undefined; assert.ok(match, `Didn't find completion item with label ${eItem.label}`); if (match) { assert.strictEqual(match.detail, 'Emmet Abbreviation', `Match needs to come from Emmet`); if (eItem.documentation) { assert.strictEqual(match.documentation, eItem.documentation, `Emmet completion Documentation doesn't match`); } } }); return Promise.resolve(); }); } ================================================ FILE: extensions/emmet/src/test/cssAbbreviationAction.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'mocha'; import * as assert from 'assert'; import { Selection, CompletionList, CancellationTokenSource, Position, CompletionTriggerKind, CompletionContext } from 'vscode'; import { withRandomFileEditor, closeAllEditors } from './testUtils'; import { expandEmmetAbbreviation } from '../abbreviationActions'; import { DefaultCompletionItemProvider } from '../defaultCompletionProvider'; const completionProvider = new DefaultCompletionItemProvider(); const cssContents = ` .boo { margin: 20px 10px; pos:f background-image: url('tryme.png'); pos:f } .boo .hoo { margin: 10px; ind } `; const scssContents = ` .boo { margin: 10px; p10 .hoo { p20 } } @include b(alert) { margin: 10px; p30 @include b(alert) { p40 } } .foo { margin: 10px; margin: a .hoo { color: #000; } } `; const invokeCompletionContext: CompletionContext = { triggerKind: CompletionTriggerKind.Invoke, triggerCharacter: undefined, }; suite('Tests for Expand Abbreviations (CSS)', () => { teardown(closeAllEditors); test('Expand abbreviation (CSS)', () => { return withRandomFileEditor(cssContents, 'css', (editor, _) => { editor.selections = [new Selection(3, 1, 3, 6), new Selection(5, 1, 5, 6)]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), cssContents.replace(/pos:f/g, 'position: fixed;')); return Promise.resolve(); }); }); }); test('No emmet when cursor inside comment (CSS)', () => { const testContent = ` .foo { /*margin: 10px; m10 padding: 10px;*/ display: auto; } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(3, 4, 3, 4); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('No emmet when cursor in selector of a rule (CSS)', () => { const testContent = ` .foo { margin: 10px; } nav# `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(5, 4, 5, 4); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('Skip when typing property values when there is a property in the next line (CSS)', () => { const testContent = ` .foo { margin: a margin: 10px; } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(2, 10, 2, 10); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('Skip when typing the last property value in single line rules (CSS)', () => { const testContent = `.foo {padding: 10px; margin: a}`; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(0, 30, 0, 30); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(0, 30), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('Allow hex color or !important when typing property values when there is a property in the next line (CSS)', () => { const testContent = ` .foo { margin: #12 ! margin: 10px; } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { const cancelSrc = new CancellationTokenSource(); const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(2, 12), cancelSrc.token, invokeCompletionContext); const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(2, 14), cancelSrc.token, invokeCompletionContext); if (!completionPromise1 || !completionPromise2) { assert.strictEqual(1, 2, `Completion promise wasnt returned`); return Promise.resolve(); } const callBack = (completionList: CompletionList, expandedText: string) => { if (!completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Empty Completions`); return; } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual((emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); }; return Promise.all([completionPromise1, completionPromise2]).then(([result1, result2]) => { assert.ok(result1); assert.ok(result2); callBack(result1, '#121212'); callBack(result2, '!important'); editor.selections = [new Selection(2, 12, 2, 12), new Selection(2, 14, 2, 14)]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent.replace('#12', '#121212').replace('!', '!important')); }); }); }); }); test('Skip when typing property values when there is a property in the previous line (CSS)', () => { const testContent = ` .foo { margin: 10px; margin: a } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(3, 10, 3, 10); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(3, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('Allow hex color or !important when typing property values when there is a property in the previous line (CSS)', () => { const testContent = ` .foo { margin: 10px; margin: #12 ! } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { const cancelSrc = new CancellationTokenSource(); const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 12), cancelSrc.token, invokeCompletionContext); const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(3, 14), cancelSrc.token, invokeCompletionContext); if (!completionPromise1 || !completionPromise2) { assert.strictEqual(1, 2, `Completion promise wasnt returned`); return Promise.resolve(); } const callBack = (completionList: CompletionList, expandedText: string) => { if (!completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Empty Completions`); return; } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual((emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); }; return Promise.all([completionPromise1, completionPromise2]).then(([result1, result2]) => { assert.ok(result1); assert.ok(result2); callBack(result1, '#121212'); callBack(result2, '!important'); editor.selections = [new Selection(3, 12, 3, 12), new Selection(3, 14, 3, 14)]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent.replace('#12', '#121212').replace('!', '!important')); }); }); }); }); test('Skip when typing property values when it is the only property in the rule (CSS)', () => { const testContent = ` .foo { margin: a } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(2, 10, 2, 10); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); test('Allow hex colors or !important when typing property values when it is the only property in the rule (CSS)', () => { const testContent = ` .foo { margin: #12 ! } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { const cancelSrc = new CancellationTokenSource(); const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(2, 12), cancelSrc.token, invokeCompletionContext); const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(2, 14), cancelSrc.token, invokeCompletionContext); if (!completionPromise1 || !completionPromise2) { assert.strictEqual(1, 2, `Completion promise wasnt returned`); return Promise.resolve(); } const callBack = (completionList: CompletionList, expandedText: string) => { if (!completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Empty Completions`); return; } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual((emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); }; return Promise.all([completionPromise1, completionPromise2]).then(([result1, result2]) => { assert.ok(result1); assert.ok(result2); callBack(result1, '#121212'); callBack(result2, '!important'); editor.selections = [new Selection(2, 12, 2, 12), new Selection(2, 14, 2, 14)]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent.replace('#12', '#121212').replace('!', '!important')); }); }); }); }); test('# shouldnt expand to hex color when in selector (CSS)', () => { const testContent = ` .foo { # } `; return withRandomFileEditor(testContent, 'css', (editor, _) => { editor.selection = new Selection(2, 2, 2, 2); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), testContent); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 2), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion of hex color at property name`); } return Promise.resolve(); }); }); }); test('Expand abbreviation in completion list (CSS)', () => { const abbreviation = 'pos:f'; const expandedText = 'position: fixed;'; return withRandomFileEditor(cssContents, 'css', (editor, _) => { editor.selection = new Selection(3, 1, 3, 6); const cancelSrc = new CancellationTokenSource(); const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 6), cancelSrc.token, invokeCompletionContext); const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 6), cancelSrc.token, invokeCompletionContext); if (!completionPromise1 || !completionPromise2) { assert.strictEqual(1, 2, `Problem with expanding pos:f`); return Promise.resolve(); } const callBack = (completionList: CompletionList) => { if (!completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding pos:f`); return; } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual((emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`); }; return Promise.all([completionPromise1, completionPromise2]).then(([result1, result2]) => { assert.ok(result1); assert.ok(result2); callBack(result1); callBack(result2); return Promise.resolve(); }); }); }); test('Expand abbreviation (SCSS)', () => { return withRandomFileEditor(scssContents, 'scss', (editor, _) => { editor.selections = [ new Selection(3, 4, 3, 4), new Selection(5, 5, 5, 5), new Selection(11, 4, 11, 4), new Selection(14, 5, 14, 5) ]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), scssContents.replace(/p(\d\d)/g, 'padding: $1px;')); return Promise.resolve(); }); }); }); test('Expand abbreviation in completion list (SCSS)', () => { return withRandomFileEditor(scssContents, 'scss', (editor, _) => { editor.selection = new Selection(3, 4, 3, 4); const cancelSrc = new CancellationTokenSource(); const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 4), cancelSrc.token, invokeCompletionContext); const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 5), cancelSrc.token, invokeCompletionContext); const completionPromise3 = completionProvider.provideCompletionItems(editor.document, new Position(11, 4), cancelSrc.token, invokeCompletionContext); const completionPromise4 = completionProvider.provideCompletionItems(editor.document, new Position(14, 5), cancelSrc.token, invokeCompletionContext); if (!completionPromise1) { assert.strictEqual(1, 2, `Problem with expanding padding abbreviations at line 3 col 4`); } if (!completionPromise2) { assert.strictEqual(1, 2, `Problem with expanding padding abbreviations at line 5 col 5`); } if (!completionPromise3) { assert.strictEqual(1, 2, `Problem with expanding padding abbreviations at line 11 col 4`); } if (!completionPromise4) { assert.strictEqual(1, 2, `Problem with expanding padding abbreviations at line 14 col 5`); } if (!completionPromise1 || !completionPromise2 || !completionPromise3 || !completionPromise4) { return Promise.resolve(); } const callBack = (completionList: CompletionList, abbreviation: string, expandedText: string) => { if (!completionList.items || !completionList.items.length) { assert.strictEqual(1, 2, `Problem with expanding m10`); return; } const emmetCompletionItem = completionList.items[0]; assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`); assert.strictEqual((emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`); }; return Promise.all([completionPromise1, completionPromise2, completionPromise3, completionPromise4]).then(([result1, result2, result3, result4]) => { assert.ok(result1); assert.ok(result2); assert.ok(result3); assert.ok(result4); callBack(result1, 'p10', 'padding: 10px;'); callBack(result2, 'p20', 'padding: 20px;'); callBack(result3, 'p30', 'padding: 30px;'); callBack(result4, 'p40', 'padding: 40px;'); return Promise.resolve(); }); }); }); test('Invalid locations for abbreviations in scss', () => { const scssContentsNoExpand = ` m10 .boo { margin: 10px; .hoo { background: } } `; return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, _) => { editor.selections = [ new Selection(1, 3, 1, 3), // outside rule new Selection(5, 15, 5, 15) // in the value part of property value ]; return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), scssContentsNoExpand); return Promise.resolve(); }); }); }); test('Invalid locations for abbreviations in scss in completion list', () => { const scssContentsNoExpand = ` m10 .boo { margin: 10px; .hoo { background: } } `; return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, _) => { editor.selection = new Selection(1, 3, 1, 3); // outside rule const cancelSrc = new CancellationTokenSource(); let completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `m10 gets expanded in invalid location (outside rule)`); } editor.selection = new Selection(5, 15, 5, 15); // in the value part of property value completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext); if (completionPromise) { return completionPromise.then((completionList: CompletionList | undefined) => { if (completionList && completionList.items && completionList.items.length > 0) { assert.strictEqual(1, 2, `m10 gets expanded in invalid location (n the value part of property value)`); } return Promise.resolve(); }); } return Promise.resolve(); }); }); test('Skip when typing property values when there is a nested rule in the next line (SCSS)', () => { return withRandomFileEditor(scssContents, 'scss', (editor, _) => { editor.selection = new Selection(19, 10, 19, 10); return expandEmmetAbbreviation(null).then(() => { assert.strictEqual(editor.document.getText(), scssContents); const cancelSrc = new CancellationTokenSource(); const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(19, 10), cancelSrc.token, invokeCompletionContext); if (completionPromise) { assert.strictEqual(1, 2, `Invalid completion at property value`); } return Promise.resolve(); }); }); }); }); ================================================ FILE: extensions/emmet/src/test/editPointSelectItemBalance.test.ts ================================================ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'mocha'; import * as assert from 'assert'; import { Selection } from 'vscode'; import { withRandomFileEditor, closeAllEditors } from './testUtils'; import { fetchEditPoint } from '../editPoint'; import { fetchSelectItem } from '../selectItem'; import { balanceOut, balanceIn } from '../balance'; suite('Tests for Next/Previous Select/Edit point and Balance actions', () => { teardown(closeAllEditors); const cssContents = ` .boo { margin: 20px 10px; background-image: url('tryme.png'); } .boo .hoo { margin: 10px; } `; const scssContents = ` .boo { margin: 20px 10px; background-image: url('tryme.png'); .boo .hoo { margin: 10px; } } `; const htmlContents = `
    \t\t
    `; test('Emmet Next/Prev Edit point in html file', function (): any { return withRandomFileEditor(htmlContents, '.html', (editor, _) => { editor.selections = [new Selection(1, 5, 1, 5)]; const expectedNextEditPoints: [number, number][] = [[4, 16], [6, 8], [10, 2], [10, 2]]; expectedNextEditPoints.forEach(([line, col]) => { fetchEditPoint('next'); testSelection(editor.selection, col, line); }); const expectedPrevEditPoints = [[6, 8], [4, 16], [4, 16]]; expectedPrevEditPoints.forEach(([line, col]) => { fetchEditPoint('prev'); testSelection(editor.selection, col, line); }); return Promise.resolve(); }); }); test('Emmet Select Next/Prev Item in html file', function (): any { return withRandomFileEditor(htmlContents, '.html', (editor, _) => { editor.selections = [new Selection(2, 2, 2, 2)]; const expectedNextItemPoints: [number, number, number][] = [ [2, 1, 5], // html [2, 6, 15], // lang="en" [2, 12, 14], // en [3, 1, 5], // head [4, 2, 6], // meta [4, 7, 17], // charset="" [5, 2, 6], // meta [5, 7, 22], // name="viewport" [5, 13, 21], // viewport [5, 23, 70], // content="width=device-width, initial-scale=1.0" [5, 32, 69], // width=device-width, initial-scale=1.0 [5, 32, 51], // width=device-width, [5, 52, 69], // initial-scale=1.0 [6, 2, 7] // title ]; expectedNextItemPoints.forEach(([line, colstart, colend]) => { fetchSelectItem('next'); testSelection(editor.selection, colstart, line, colend); }); editor.selections = [new Selection(6, 15, 6, 15)]; expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => { fetchSelectItem('prev'); testSelection(editor.selection, colstart, line, colend); }); return Promise.resolve(); }); }); test('Emmet Select Next/Prev item at boundary', function (): any { return withRandomFileEditor(htmlContents, '.html', (editor, _) => { editor.selections = [new Selection(4, 1, 4, 1)]; fetchSelectItem('next'); testSelection(editor.selection, 2, 4, 6); editor.selections = [new Selection(4, 1, 4, 1)]; fetchSelectItem('prev'); testSelection(editor.selection, 1, 3, 5); return Promise.resolve(); }); }); test('Emmet Next/Prev Item in html template', function (): any { const templateContents = ` `; return withRandomFileEditor(templateContents, '.html', (editor, _) => { editor.selections = [new Selection(2, 2, 2, 2)]; const expectedNextItemPoints: [number, number, number][] = [ [2, 2, 5], // div [2, 6, 20], // class="header" [2, 13, 19], // header [3, 3, 5], // ul [3, 6, 22], // class="nav main" [3, 13, 21], // nav main [3, 13, 16], // nav [3, 17, 21], // main ]; expectedNextItemPoints.forEach(([line, colstart, colend]) => { fetchSelectItem('next'); testSelection(editor.selection, colstart, line, colend); }); editor.selections = [new Selection(4, 1, 4, 1)]; expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => { fetchSelectItem('prev'); testSelection(editor.selection, colstart, line, colend); }); return Promise.resolve(); }); }); test('Emmet Select Next/Prev Item in css file', function (): any { return withRandomFileEditor(cssContents, '.css', (editor, _) => { editor.selections = [new Selection(0, 0, 0, 0)]; const expectedNextItemPoints: [number, number, number][] = [ [1, 0, 4], // .boo [2, 1, 19], // margin: 20px 10px; [2, 9, 18], // 20px 10px [2, 9, 13], // 20px [2, 14, 18], // 10px [3, 1, 36], // background-image: url('tryme.png'); [3, 19, 35], // url('tryme.png') [6, 0, 9], // .boo .hoo [7, 1, 14], // margin: 10px; [7, 9, 13], // 10px ]; expectedNextItemPoints.forEach(([line, colstart, colend]) => { fetchSelectItem('next'); testSelection(editor.selection, colstart, line, colend); }); editor.selections = [new Selection(9, 0, 9, 0)]; expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => { fetchSelectItem('prev'); testSelection(editor.selection, colstart, line, colend); }); return Promise.resolve(); }); }); test('Emmet Select Next/Prev Item in scss file with nested rules', function (): any { return withRandomFileEditor(scssContents, '.scss', (editor, _) => { editor.selections = [new Selection(0, 0, 0, 0)]; const expectedNextItemPoints: [number, number, number][] = [ [1, 0, 4], // .boo [2, 1, 19], // margin: 20px 10px; [2, 9, 18], // 20px 10px [2, 9, 13], // 20px [2, 14, 18], // 10px [3, 1, 36], // background-image: url('tryme.png'); [3, 19, 35], // url('tryme.png') [5, 1, 10], // .boo .hoo [6, 2, 15], // margin: 10px; [6, 10, 14], // 10px ]; expectedNextItemPoints.forEach(([line, colstart, colend]) => { fetchSelectItem('next'); testSelection(editor.selection, colstart, line, colend); }); editor.selections = [new Selection(8, 0, 8, 0)]; expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => { fetchSelectItem('prev'); testSelection(editor.selection, colstart, line, colend); }); return Promise.resolve(); }); }); test('Emmet Balance Out in html file', function (): any { return withRandomFileEditor(htmlContents, 'html', (editor, _) => { editor.selections = [new Selection(14, 6, 14, 10)]; const expectedBalanceOutRanges: [number, number, number, number][] = [ [14, 3, 14, 32], //
  • Item 1
  • [13, 23, 16, 2], // inner contents of