Merge remote-tracking branch 'origin/main' into tyriar/gpu_exploration

This commit is contained in:
Daniel Imms
2024-08-16 06:11:32 -07:00
168 changed files with 5329 additions and 1251 deletions
+1 -1
View File
@@ -1 +1 @@
2024-08-08T03:47:49.879Z
2024-08-14T18:12:43.548Z
@@ -7,6 +7,9 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- script: yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install"
@@ -17,34 +20,56 @@ steps:
- ${{ 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: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn test-browser-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit)
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- script: ./scripts/test-esm.sh --tfs "Unit Tests"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- script: yarn test-node-esm
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- script: yarn test-browser-esm-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit) [ESM]
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- script: ./scripts/test.sh --tfs "Unit Tests"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- script: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn test-browser-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & 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: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit)
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- script: ./scripts/test-esm.sh --build --tfs "Unit Tests"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- script: yarn test-node-esm --build
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- script: yarn test-browser-esm-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit) [ESM]
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- script: ./scripts/test.sh --build --tfs "Unit Tests"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- script: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium & Webkit)
timeoutInMinutes: 30
- ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}:
- script: |
@@ -69,24 +94,44 @@ steps:
displayName: Build integration tests
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- script: ./scripts/test-integration.sh --tfs "Integration Tests"
displayName: Run integration tests (Electron)
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- script: ./scripts/test-integration-esm.sh --tfs "Integration Tests"
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- 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
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- 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-esm.sh --build --tfs "Integration Tests"
env:
VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- 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:
@@ -9,6 +9,9 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
@@ -174,6 +177,7 @@ steps:
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 }}
VSCODE_BUILD_ESM: ${{ parameters.VSCODE_BUILD_ESM }}
- ${{ elseif and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
- task: DownloadPipelineArtifact@2
@@ -5,6 +5,9 @@ parameters:
type: boolean
- name: VSCODE_ARCH
type: string
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- task: NodeTool@0
@@ -201,6 +204,7 @@ steps:
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: false
VSCODE_BUILD_ESM: ${{ parameters.VSCODE_BUILD_ESM }}
${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1
@@ -10,6 +10,9 @@ parameters:
- name: PUBLISH_TASK_NAME
type: string
default: PublishPipelineArtifact@0
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- script: yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install"
@@ -33,36 +36,61 @@ steps:
- ${{ 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
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- script: ./scripts/test-esm.sh --tfs "Unit Tests"
env:
DISPLAY: ":10"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- script: yarn test-node-esm
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- script: yarn test-browser-esm-no-install --browser chromium --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium) [ESM]
timeoutInMinutes: 15
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- script: ./scripts/test.sh --tfs "Unit Tests"
env:
DISPLAY: ":10"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- script: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn test-browser-no-install --browser chromium --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 15
- script: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn 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: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn 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_BUILD_ESM, true) }}:
- script: ./scripts/test-esm.sh --build --tfs "Unit Tests"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- script: yarn test-node-esm --build
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- script: yarn test-browser-esm-no-install --build --browser chromium --tfs "Browser Unit Tests"
env:
DEBUG: "*browser*"
displayName: Run unit tests (Browser, Chromium) [ESM]
timeoutInMinutes: 15
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- script: ./scripts/test.sh --build --tfs "Unit Tests"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- script: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- script: yarn 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: |
@@ -88,11 +116,18 @@ steps:
- ${{ 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
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- script: ./scripts/test-integration-esm.sh --tfs "Integration Tests"
env:
DISPLAY: ":10"
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- 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)
@@ -103,20 +138,36 @@ steps:
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
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- 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-esm.sh --build --tfs "Integration Tests"
env:
VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- 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:
@@ -11,6 +11,9 @@ parameters:
type: boolean
- name: VSCODE_ARCH
type: string
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
@@ -267,6 +270,7 @@ steps:
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 }}
VSCODE_BUILD_ESM: ${{ parameters.VSCODE_BUILD_ESM }}
${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1
+24 -3
View File
@@ -100,7 +100,7 @@ parameters:
displayName: "Skip tests"
type: boolean
default: false
- name: VSCODE_BUILD_ESM # TODO@bpasero remove me once ESM is shipped
- name: VSCODE_BUILD_ESM # TODO@bpasero TODO@esm remove me once ESM is shipped
displayName: "️❗ Build as ESM (!FOR TESTING ONLY!) ️❗"
type: boolean
default: false
@@ -175,7 +175,7 @@ resources:
ref: refs/tags/release
extends:
template: v1/1ES.Unofficial.PipelineTemplate.yml@1esPipelines
template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
parameters:
sdl:
tsa:
@@ -190,9 +190,10 @@ extends:
validateToolOutput: None
allTools: true
codeql:
runSourceLanguagesInSourceAnalysis: true
compiled:
enabled: false
runSourceLanguagesInSourceAnalysis: true
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:
@@ -361,6 +362,7 @@ extends:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_ARCH: x64
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: true
@@ -375,6 +377,7 @@ extends:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_ARCH: x64
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
@@ -389,6 +392,7 @@ extends:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_ARCH: x64
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
@@ -404,6 +408,7 @@ extends:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_ARCH: x64
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
@@ -427,6 +432,7 @@ extends:
- template: build/azure-pipelines/win32/product-build-win32.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_ARCH: arm64
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
@@ -455,6 +461,7 @@ extends:
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -470,6 +477,7 @@ extends:
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
@@ -485,6 +493,7 @@ extends:
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -502,6 +511,7 @@ extends:
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
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) }}
@@ -527,6 +537,7 @@ extends:
parameters:
VSCODE_ARCH: armhf
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -542,6 +553,7 @@ extends:
parameters:
VSCODE_ARCH: arm64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -566,6 +578,7 @@ extends:
parameters:
VSCODE_ARCH: x64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF_LEGACY_SERVER, true) }}:
@@ -578,6 +591,7 @@ extends:
parameters:
VSCODE_ARCH: armhf
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_RUN_INTEGRATION_TESTS: false
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64_LEGACY_SERVER, true) }}:
@@ -590,6 +604,7 @@ extends:
parameters:
VSCODE_ARCH: arm64
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_RUN_INTEGRATION_TESTS: false
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_ALPINE'], true)) }}:
@@ -642,6 +657,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -655,6 +671,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
@@ -668,6 +685,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -682,6 +700,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -696,6 +715,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
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) }}
@@ -727,6 +747,7 @@ extends:
- template: build/azure-pipelines/darwin/product-build-darwin.yml@self
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_ESM: ${{ variables.VSCODE_BUILD_ESM }}
VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
@@ -12,6 +12,9 @@ parameters:
- name: PUBLISH_TASK_NAME
type: string
default: PublishPipelineArtifact@0
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- powershell: yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install"
@@ -22,30 +25,48 @@ steps:
- ${{ 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: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: node test/unit/browser/index.js --sequential --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- powershell: .\scripts\test-esm.bat --tfs "Unit Tests"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- powershell: yarn test-node-esm
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- powershell: node test/unit/browser/index.esm.js --sequential --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- powershell: .\scripts\test.bat --tfs "Unit Tests"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- powershell: yarn test-node
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: node test/unit/browser/index.js --sequential --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: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: yarn test-browser-no-install --sequential --build --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- powershell: .\scripts\test-esm.bat --build --tfs "Unit Tests"
displayName: Run unit tests (Electron) [ESM]
timeoutInMinutes: 15
- script: yarn test-node-esm --build
displayName: Run unit tests (node.js) [ESM]
timeoutInMinutes: 15
- powershell: yarn test-browser-esm-no-install --sequential --build --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- powershell: .\scripts\test.bat --build --tfs "Unit Tests"
displayName: Run unit tests (Electron)
timeoutInMinutes: 15
- powershell: yarn test-node --build
displayName: Run unit tests (node.js)
timeoutInMinutes: 15
- powershell: yarn test-browser-no-install --sequential --build --browser chromium --tfs "Browser Unit Tests"
displayName: Run unit tests (Browser, Chromium)
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}:
- powershell: |
@@ -77,9 +98,14 @@ steps:
condition: succeededOrFailed()
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- powershell: .\scripts\test-integration.bat --tfs "Integration Tests"
displayName: Run integration tests (Electron)
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- powershell: .\scripts\test-integration-esm.bat --tfs "Integration Tests"
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- powershell: .\scripts\test-integration.bat --tfs "Integration Tests"
displayName: Run integration tests (Electron)
timeoutInMinutes: 20
- powershell: .\scripts\test-web-integration.bat --browser firefox
displayName: Run integration tests (Browser, Firefox)
@@ -90,20 +116,36 @@ steps:
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
- ${{ if eq(parameters.VSCODE_BUILD_ESM, true) }}:
- 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-esm.bat --build --tfs "Integration Tests" }
displayName: Run integration tests (Electron) [ESM]
timeoutInMinutes: 20
- ${{ if eq(parameters.VSCODE_BUILD_ESM, false) }}:
- 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
@@ -11,6 +11,9 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_BUILD_ESM
type: boolean
default: false
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
@@ -179,6 +182,7 @@ steps:
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 }}
VSCODE_BUILD_ESM: ${{ parameters.VSCODE_BUILD_ESM }}
${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1
+4
View File
@@ -34,11 +34,15 @@ gulp.task(compileClientTask);
const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), task.parallel(watchTask('out', false), watchApiProposalNamesTask)));
gulp.task(watchClientTask);
const watchClientESMTask = task.define('watch-client-esm', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), task.parallel(watchTask('out', false, 'src2'), watchApiProposalNamesTask)));
gulp.task(watchClientESMTask);
// 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)));
gulp.task(task.define('watch-esm', task.parallel(/* monacoTypecheckWatchTask, */ watchClientESMTask, watchExtensionsTask)));
// Default
gulp.task('default', _compileTask);
+23 -6
View File
@@ -54,7 +54,7 @@ const BUILD_TARGETS = [
{ platform: 'linux', arch: 'alpine' },
];
const serverResources = [
const serverResourceIncludes = [
// NLS
'out-build/nls.messages.json',
@@ -73,19 +73,36 @@ const serverResources = [
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh',
'out-build/vs/workbench/contrib/terminal/browser/media/shellIntegration-login.zsh',
'out-build/vs/workbench/contrib/terminal/browser/media/fish_xdg_data/fish/vendor_conf.d/shellIntegration.fish',
];
const serverResourceExcludes = [
'!out-build/vs/**/{electron-sandbox,electron-main}/**',
'!out-build/vs/editor/standalone/**',
'!out-build/vs/workbench/**/*-tb.png',
'!**/test/**'
];
const serverWithWebResources = [
const serverResources = [
...serverResourceIncludes,
...serverResourceExcludes
];
// Include all of server...
...serverResources,
// ...and all of web
const serverWithWebResourceIncludes = [
...serverResourceIncludes,
...vscodeWebResourceIncludes
];
const serverWithWebResourceExcludes = [
...serverResourceExcludes,
'!out-build/vs/code/**/*-dev.html',
'!out-build/vs/code/**/*-dev.esm.html',
];
const serverWithWebResources = [
...serverWithWebResourceIncludes,
...serverWithWebResourceExcludes
];
const serverEntryPoints = [
{
name: 'vs/server/node/server.main',
+2 -1
View File
@@ -56,6 +56,7 @@ const vscodeResources = [
'out-build/vs/**/*.{svg,png,html,jpg,mp3}',
'!out-build/vs/code/browser/**/*.html',
'!out-build/vs/code/**/*-dev.html',
'!out-build/vs/code/**/*-dev.esm.html',
'!out-build/vs/editor/standalone/**/*.svg',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
'out-build/vs/base/browser/ui/codicons/codicon/**',
@@ -70,8 +71,8 @@ const vscodeResources = [
'out-build/vs/workbench/contrib/terminal/browser/media/*.sh',
'out-build/vs/workbench/contrib/terminal/browser/media/*.zsh',
'out-build/vs/workbench/contrib/webview/browser/pre/*.js',
'!out-build/vs/workbench/contrib/issue/browser/*.html',
'!out-build/vs/workbench/contrib/issue/**/*-dev.html',
'!out-build/vs/workbench/contrib/issue/**/*-dev.esm.html',
'out-build/vs/**/markdown.css',
'out-build/vs/workbench/contrib/tasks/**/*.json',
'!**/test/**'
+3
View File
@@ -47,6 +47,7 @@ const vscodeWebResourceIncludes = [
// Extension Worker
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.esm.html',
// Web node paths (needed for integration tests)
'out-build/vs/webPackagePaths.js',
@@ -62,6 +63,8 @@ const vscodeWebResources = [
'!out-build/vs/**/{node,electron-sandbox,electron-main}/**',
'!out-build/vs/editor/standalone/**',
'!out-build/vs/workbench/**/*-tb.png',
'!out-build/vs/code/**/*-dev.html',
'!out-build/vs/code/**/*-dev.esm.html',
'!**/test/**'
];
+4 -4
View File
@@ -139,11 +139,11 @@ function compileTask(src, out, build, options = {}) {
task.taskName = `compile-${path.basename(src)}`;
return task;
}
function watchTask(out, build) {
function watchTask(out, build, srcPath = 'src') {
const task = () => {
const compile = createCompile('src', { build, emitError: false, transpileOnly: false, preserveEnglish: false });
const src = gulp.src('src/**', { base: 'src' });
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
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
+4 -4
View File
@@ -170,13 +170,13 @@ export function compileTask(src: string, out: string, build: boolean, options: {
return task;
}
export function watchTask(out: string, build: boolean): task.StreamTask {
export function watchTask(out: string, build: boolean, srcPath: string = 'src'): task.StreamTask {
const task = () => {
const compile = createCompile('src', { build, emitError: false, transpileOnly: false, preserveEnglish: false });
const compile = createCompile(srcPath, { build, emitError: false, transpileOnly: false, preserveEnglish: false });
const src = gulp.src('src/**', { base: 'src' });
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
const src = gulp.src(`${srcPath}/**`, { base: srcPath });
const watchSrc = watch(`${srcPath}/**`, { base: srcPath, readDelay: 200 });
const generator = new MonacoGenerator(true);
generator.execute();
+1 -1
View File
@@ -131,7 +131,7 @@ function createESMSourcesAndResources2(options) {
}
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs').replace(/\\/g, '/');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
+1 -1
View File
@@ -157,7 +157,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.module = 'es2022';
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs').replace(/\\/g, '/');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
-5
View File
@@ -81,11 +81,6 @@ for (let dir of dirs) {
}
}
if (/^(.build\/distro\/npm\/)?remote/.test(dir) && process.platform === 'win32' && (process.arch === 'arm64' || process.env['npm_config_arch'] === 'arm64')) {
// windows arm: do not execute `yarn` on remote folder
continue;
}
let opts;
if (dir === 'build') {
+1 -13
View File
@@ -122,19 +122,7 @@ function installHeaders() {
cp.execFileSync(node_gyp, ['install', '--dist-url', local.disturl, local.target], { shell: true });
}
// Avoid downloading headers for Windows arm64 till we move to Nodejs v19 in remote
// which is the first official release with support for the architecture. Downloading
// the headers for older versions now redirect to https://origin.nodejs.org/404.html
// which causes checksum validation error in node-gyp.
//
// gyp http 200 https://origin.nodejs.org/404.html
// gyp WARN install got an error, rolling back install
// gyp ERR! install error
// gyp ERR! stack Error: win-arm64/node.lib local checksum 4c62bed7a032f7b36984321b7ffdd60b596fac870672037ff879ae9ac9548fb7 not match remote undefined
//
if (remote !== undefined && !versions.has(remote.target) &&
process.env['npm_config_arch'] !== "arm64" &&
process.arch !== "arm64") {
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 });
}
@@ -7,7 +7,6 @@ import { PackageManager } from '@vscode/ts-package-manager';
import { basename, join } from 'path';
import * as vscode from 'vscode';
import { URI } from 'vscode-uri';
import { Throttler } from '../utils/async';
import { Disposable } from '../utils/dispose';
import { MemFs } from './memFs';
import { Logger } from '../logging/logger';
@@ -19,9 +18,7 @@ export class AutoInstallerFs extends Disposable implements vscode.FileSystemProv
private readonly memfs: MemFs;
private readonly packageManager: PackageManager;
private readonly _projectCache = new Map</* root */ string, {
readonly throttler: Throttler;
}>();
private readonly _projectCache = new Map</* root */ string, Promise<void> | undefined>();
private readonly _emitter = this._register(new vscode.EventEmitter<vscode.FileChangeEvent[]>());
readonly onDidChangeFile = this._emitter.event;
@@ -78,9 +75,8 @@ export class AutoInstallerFs extends Disposable implements vscode.FileSystemProv
}
watch(resource: vscode.Uri): vscode.Disposable {
const mapped = URI.file(new MappedUri(resource).path);
this.logger.trace(`AutoInstallerFs.watch. Original: ${resource.toString()}, Mapped: ${mapped.toString()}`);
return this.memfs.watch(mapped);
this.logger.trace(`AutoInstallerFs.watch. Resource: ${resource.toString()}}`);
return this.memfs.watch(resource);
}
async stat(uri: vscode.Uri): Promise<vscode.FileStat> {
@@ -151,20 +147,20 @@ export class AutoInstallerFs extends Disposable implements vscode.FileSystemProv
throw vscode.FileSystemError.FileNotFound();
}
const root = this.getProjectRoot(incomingUri.path);
const root = await this.getProjectRoot(incomingUri.original);
if (!root) {
return;
}
this.logger.trace(`AutoInstallerFs.ensurePackageContents. Path: ${incomingUri.path}, Root: ${root}`);
let projectEntry = this._projectCache.get(root);
if (!projectEntry) {
projectEntry = { throttler: new Throttler() };
this._projectCache.set(root, projectEntry);
const existingInstall = this._projectCache.get(root);
if (existingInstall) {
this.logger.trace(`AutoInstallerFs.ensurePackageContents. Found ongoing install for: ${root}/node_modules`);
return existingInstall;
}
projectEntry.throttler.queue(async () => {
const installing = (async () => {
const proj = await this.packageManager.resolveProject(root, await this.getInstallOpts(incomingUri.original, root));
try {
await proj.restore();
@@ -172,15 +168,16 @@ export class AutoInstallerFs extends Disposable implements vscode.FileSystemProv
console.error(`failed to restore package at ${incomingUri.path}: `, e);
throw e;
}
});
})();
this._projectCache.set(root, installing);
await installing;
}
private async getInstallOpts(originalUri: URI, root: string) {
const vsfs = vscode.workspace.fs;
let pkgJson;
try {
pkgJson = TEXT_DECODER.decode(await vsfs.readFile(originalUri.with({ path: join(root, 'package.json') })));
} catch (e) { }
// We definitely need a package.json to be there.
const pkgJson = TEXT_DECODER.decode(await vsfs.readFile(originalUri.with({ path: join(root, 'package.json') })));
let kdlLock;
try {
@@ -199,9 +196,19 @@ export class AutoInstallerFs extends Disposable implements vscode.FileSystemProv
};
}
private getProjectRoot(path: string): string | undefined {
const pkgPath = path.match(/(^.*)\/node_modules/);
return pkgPath?.[1];
private async getProjectRoot(incomingUri: URI): Promise<string | undefined> {
const vsfs = vscode.workspace.fs;
const pkgPath = incomingUri.path.match(/^(.*?)\/node_modules/);
const ret = pkgPath?.[1];
if (!ret) {
return;
}
try {
await vsfs.stat(incomingUri.with({ path: join(ret, 'package.json') }));
return ret;
} catch (e) {
return;
}
}
}
@@ -214,7 +221,7 @@ class MappedUri {
const parts = uri.path.match(/^\/([^\/]+)\/([^\/]*)(?:\/(.+))?$/);
if (!parts) {
throw new Error(`Invalid path: ${uri.path}`);
throw new Error(`Invalid uri: ${uri.toString()}, ${uri.path}`);
}
const scheme = parts[1];
@@ -53,9 +53,9 @@ export class FileWatcherManager {
this.watchFiles.set(path, { callback, pollingInterval, options });
const watchIds = [++this.watchId];
this.watchPort.postMessage({ type: 'watchFile', uri: uri, id: watchIds[0] });
if (this.enabledExperimentalTypeAcquisition && looksLikeNodeModules(path)) {
if (this.enabledExperimentalTypeAcquisition && looksLikeNodeModules(path) && uri.scheme !== 'vscode-global-typings') {
watchIds.push(++this.watchId);
this.watchPort.postMessage({ type: 'watchFile', uri: mapUri(uri, 'vscode-node-modules'), id: watchIds[1] });
this.watchPort.postMessage({ type: 'watchFile', uri: mapUri(uri, 'vscode-global-typings'), id: watchIds[1] });
}
return {
close: () => {
@@ -70,10 +70,12 @@ export class WebTypingsInstallerClient implements ts.server.ITypingsInstaller {
break;
case 'event::beginInstallTypes':
case 'event::endInstallTypes':
// TODO(@zkat): maybe do something with this?
case 'action::watchTypingLocations':
// Don't care.
break;
default:
throw new Error(`unexpected response: ${response}`);
throw new Error(`unexpected response: ${JSON.stringify(response)}`);
}
}
@@ -18,6 +18,10 @@ async function openRandomNotebookDocument() {
return vscode.workspace.openNotebookDocument(uri);
}
async function openUntitledNotebookDocument(data?: vscode.NotebookData) {
return vscode.workspace.openNotebookDocument('notebookCoreTest', data);
}
export async function saveAllFilesAndCloseAll() {
await saveAllEditors();
await closeAllEditors();
@@ -188,6 +192,27 @@ const apiTestSerializer: vscode.NotebookSerializer = {
assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString());
});
test('Opening an utitled notebook without content will only open the editor when shown.', async function () {
const document = await openUntitledNotebookDocument();
assert.strictEqual(vscode.window.activeNotebookEditor, undefined);
// opening a cell-uri opens a notebook editor
await vscode.window.showNotebookDocument(document);
assert.strictEqual(!!vscode.window.activeNotebookEditor, true);
assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString());
});
test('Opening an untitled notebook with content will open a dirty document.', async function () {
const language = 'python';
const cell = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, '', language);
const data = new vscode.NotebookData([cell]);
const doc = await vscode.workspace.openNotebookDocument('jupyter-notebook', data);
assert.strictEqual(doc.isDirty, true);
});
test('Cannot open notebook from cell-uri with vscode.open-command', async function () {
const document = await openRandomNotebookDocument();
+3 -2
View File
@@ -31,7 +31,7 @@ const binaryFileExtensions = new Set([
function migrate() {
console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`);
console.log(`STARTING MIGRATION of src to src2.`);
console.log(`STARTING AMD->ESM MIGRATION of src to src2.`);
// installing watcher quickly to avoid missing early events
const watchSrc = enableWatching ? watch('src/**', { base: 'src', readDelay: 200 }) : undefined;
@@ -49,7 +49,8 @@ function migrate() {
writeFileSync(join(dstFolder, '.gitignore'), `*`);
console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`);
console.log(`COMPLETED MIGRATION of src to src2. You can now launch yarn watch or yarn watch-client`);
console.log(`COMPLETED AMD->ESM MIGRATION of src to src2. You can now launch yarn watch-esm or yarn watch-client-esm`);
console.log(`Make sure to set the environment variable VSCODE_BUILD_ESM to a string of value 'true' if you want to build VS Code`);
if (watchSrc) {
console.log(`WATCHING src for changes...`);
+6 -1
View File
@@ -11,13 +11,17 @@
"scripts": {
"test": "echo Please run any of the test scripts from the scripts folder.",
"test-browser": "npx playwright install && node test/unit/browser/index.js",
"test-browser-esm": "npx playwright install && node test/unit/browser/index.esm.js",
"test-browser-no-install": "node test/unit/browser/index.js",
"test-browser-esm-no-install": "node test/unit/browser/index.esm.js",
"test-node": "mocha test/unit/node/index.js --delay --ui=tdd --timeout=5000 --exit",
"test-node-esm": "mocha test/unit/node/index.mjs --delay --ui=tdd --timeout=5000 --exit",
"test-extension": "vscode-test",
"preinstall": "node build/npm/preinstall.js",
"postinstall": "node build/npm/postinstall.js",
"compile": "node --max-old-space-size=4095 ./node_modules/gulp/bin/gulp.js compile",
"watch": "npm-run-all -lp watch-client watch-extensions",
"watch-esm": "npm-run-all -lp watch-client-esm watch-extensions",
"watchd": "deemon yarn watch",
"watch-webd": "deemon yarn watch-web",
"kill-watchd": "deemon --kill yarn watch",
@@ -25,6 +29,7 @@
"restart-watchd": "deemon --restart yarn watch",
"restart-watch-webd": "deemon --restart yarn watch-web",
"watch-client": "node --max-old-space-size=4095 ./node_modules/gulp/bin/gulp.js watch-client",
"watch-client-esm": "node --max-old-space-size=4095 ./node_modules/gulp/bin/gulp.js watch-client-esm",
"watch-clientd": "deemon yarn watch-client",
"kill-watch-clientd": "deemon --kill yarn watch-client",
"watch-extensions": "node --max-old-space-size=4095 ./node_modules/gulp/bin/gulp.js watch-extensions watch-extension-media",
@@ -105,7 +110,7 @@
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.0.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
+1 -1
View File
@@ -34,7 +34,7 @@
"tas-client-umd": "0.2.0",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.0.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
+1 -1
View File
@@ -18,6 +18,6 @@
"jschardet": "3.1.3",
"tas-client-umd": "0.2.0",
"vscode-oniguruma": "1.7.0",
"vscode-textmate": "9.0.0"
"vscode-textmate": "9.1.0"
}
}
+4 -4
View File
@@ -110,7 +110,7 @@ vscode-oniguruma@1.7.0:
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b"
integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==
vscode-textmate@9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c"
integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg==
vscode-textmate@9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.1.0.tgz#656a6aa163a9578397ba810733952bedb2b47202"
integrity sha512-lxKSVp2DkFOx9RDAvpiYUrB9/KT1fAfi1aE8CBGstP8N7rLF+Seifj8kDA198X0mYj1CjQUC+81+nQf8CO0nVA==
+4 -4
View File
@@ -688,10 +688,10 @@ vscode-regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/vscode-regexpp/-/vscode-regexpp-3.1.0.tgz#42d059b6fffe99bd42939c0d013f632f0cad823f"
integrity sha512-pqtN65VC1jRLawfluX4Y80MMG0DHJydWhe5ZwMHewZD6sys4LbU6lHwFAHxeuaVE6Y6+xZOtAw+9hvq7/0ejkg==
vscode-textmate@9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c"
integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg==
vscode-textmate@9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.1.0.tgz#656a6aa163a9578397ba810733952bedb2b47202"
integrity sha512-lxKSVp2DkFOx9RDAvpiYUrB9/KT1fAfi1aE8CBGstP8N7rLF+Seifj8kDA198X0mYj1CjQUC+81+nQf8CO0nVA==
wrappy@1:
version "1.0.2"
+4
View File
@@ -74,6 +74,10 @@ async function main() {
openSystemBrowser = true;
}
if (fs.existsSync(path.join(APP_ROOT, 'src2')) || fs.existsSync(path.join(APP_ROOT, 'out-build', 'esm'))) {
serverArgs.push('--esm');
}
serverArgs.push('--sourcesPath', APP_ROOT);
serverArgs.push(...process.argv.slice(2).filter(v => !v.startsWith('--playground') && v !== '--no-playground'));
+31
View File
@@ -0,0 +1,31 @@
@echo off
setlocal
set ELECTRON_RUN_AS_NODE=
pushd %~dp0\..
:: Get Code.exe location
for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"nameShort\":.*" product.json') do set NAMESHORT=%%~a
set NAMESHORT=%NAMESHORT: "=%
set NAMESHORT=%NAMESHORT:"=%.exe
set CODE=".build\electron\%NAMESHORT%"
:: Download Electron if needed
call node build\lib\electron.js
if %errorlevel% neq 0 node .\node_modules\gulp\bin\gulp.js electron
:: Run tests
set ELECTRON_ENABLE_LOGGING=1
%CODE% .\test\unit\electron\index.esm.js --crash-reporter-directory=%~dp0\..\.build\crashes %*
popd
endlocal
:: app.exit(0) is exiting with code 255 in Electron 1.7.4.
:: See https://github.com/microsoft/vscode/issues/28582
echo errorlevel: %errorlevel%
if %errorlevel% == 255 set errorlevel=0
exit /b %errorlevel%
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -e
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
ROOT=$(dirname $(dirname $(realpath "$0")))
else
ROOT=$(dirname $(dirname $(readlink -f $0)))
# --disable-dev-shm-usage: when run on docker containers where size of /dev/shm
# partition < 64MB which causes OOM failure for chromium compositor that uses the partition for shared memory
LINUX_EXTRA_ARGS="--disable-dev-shm-usage"
fi
cd $ROOT
if [[ "$OSTYPE" == "darwin"* ]]; then
NAME=`node -p "require('./product.json').nameLong"`
CODE="./.build/electron/$NAME.app/Contents/MacOS/Electron"
else
NAME=`node -p "require('./product.json').applicationName"`
CODE=".build/electron/$NAME"
fi
VSCODECRASHDIR=$ROOT/.build/crashes
# Node modules
test -d node_modules || yarn
# Get electron
yarn electron
# Unit Tests
if [[ "$OSTYPE" == "darwin"* ]]; then
cd $ROOT ; ulimit -n 4096 ; \
ELECTRON_ENABLE_LOGGING=1 \
"$CODE" \
test/unit/electron/index.esm.js --crash-reporter-directory=$VSCODECRASHDIR "$@"
else
cd $ROOT ; \
ELECTRON_ENABLE_LOGGING=1 \
"$CODE" \
test/unit/electron/index.esm.js --crash-reporter-directory=$VSCODECRASHDIR $LINUX_EXTRA_ARGS "$@"
fi
+119
View File
@@ -0,0 +1,119 @@
@echo off
setlocal
pushd %~dp0\..
set VSCODEUSERDATADIR=%TEMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,2%
set VSCODECRASHDIR=%~dp0\..\.build\crashes
set VSCODELOGSDIR=%~dp0\..\.build\logs\integration-tests
:: Figure out which Electron to use for running tests
if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
chcp 65001
set INTEGRATION_TEST_ELECTRON_PATH=.\scripts\code.bat
set VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE=1
echo Running integration tests out of sources.
) else (
set VSCODE_CLI=1
set ELECTRON_ENABLE_LOGGING=1
echo Running integration tests with '%INTEGRATION_TEST_ELECTRON_PATH%' as build.
)
echo Storing crash reports into '%VSCODECRASHDIR%'.
echo Storing log files into '%VSCODELOGSDIR%'.
:: Tests standalone (AMD)
echo.
echo ### node.js integration tests
call .\scripts\test-esm.bat --runGlob **\*.integrationTest.js %*
if %errorlevel% neq 0 exit /b %errorlevel%
:: Tests in the extension host
set API_TESTS_EXTRA_ARGS=--disable-telemetry --skip-welcome --skip-release-notes --crash-reporter-directory=%VSCODECRASHDIR% --logsPath=%VSCODELOGSDIR% --no-cached-data --disable-updates --use-inmemory-secretstorage --disable-extensions --disable-workspace-trust --user-data-dir=%VSCODEUSERDATADIR%
echo.
echo ### API tests (folder)
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### API tests (workspace)
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Colorize tests
call yarn test-extension -l vscode-colorize-tests
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### TypeScript tests
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test\unit %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Markdown tests
call yarn test-extension -l markdown-language-features
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Emmet tests
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\emmet\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Git tests
for /f "delims=" %%i in ('node -p "require('fs').realpathSync.native(require('os').tmpdir())"') do set TEMPDIR=%%i
set GITWORKSPACE=%TEMPDIR%\git-%RANDOM%
mkdir %GITWORKSPACE%
call "%INTEGRATION_TEST_ELECTRON_PATH%" %GITWORKSPACE% --extensionDevelopmentPath=%~dp0\..\extensions\git --extensionTestsPath=%~dp0\..\extensions\git\out\test %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Ipynb tests
call yarn test-extension -l ipynb
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Notebook Output tests
call yarn test-extension -l notebook-renderers
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### Configuration editing tests
set CFWORKSPACE=%TEMPDIR%\cf-%RANDOM%
mkdir %CFWORKSPACE%
call yarn test-extension -l configuration-editing
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### GitHub Authentication tests
call yarn test-extension -l github-authentication
if %errorlevel% neq 0 exit /b %errorlevel%
:: Tests standalone (CommonJS)
echo.
echo ### CSS tests
call %~dp0\node-electron.bat %~dp0\..\extensions\css-language-features/server/test/index.js
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### HTML tests
call %~dp0\node-electron.bat %~dp0\..\extensions\html-language-features/server/test/index.js
if %errorlevel% neq 0 exit /b %errorlevel%
:: Cleanup
rmdir /s /q %VSCODEUSERDATADIR%
popd
endlocal
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
set -e
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
ROOT=$(dirname $(dirname $(realpath "$0")))
else
ROOT=$(dirname $(dirname $(readlink -f $0)))
# --disable-dev-shm-usage: when run on docker containers where size of /dev/shm
# partition < 64MB which causes OOM failure for chromium compositor that uses the partition for shared memory
LINUX_EXTRA_ARGS="--disable-dev-shm-usage"
fi
VSCODEUSERDATADIR=`mktemp -d 2>/dev/null`
VSCODECRASHDIR=$ROOT/.build/crashes
VSCODELOGSDIR=$ROOT/.build/logs/integration-tests
cd $ROOT
# Figure out which Electron to use for running tests
if [ -z "$INTEGRATION_TEST_ELECTRON_PATH" ]
then
INTEGRATION_TEST_ELECTRON_PATH="./scripts/code.sh"
echo "Running integration tests out of sources."
else
export VSCODE_CLI=1
export ELECTRON_ENABLE_LOGGING=1
echo "Running integration tests with '$INTEGRATION_TEST_ELECTRON_PATH' as build."
fi
echo "Storing crash reports into '$VSCODECRASHDIR'."
echo "Storing log files into '$VSCODELOGSDIR'."
# Tests standalone (AMD)
echo
echo "### node.js integration tests"
echo
./scripts/test-esm.sh --runGlob **/*.integrationTest.js "$@"
# Tests in the extension host
API_TESTS_EXTRA_ARGS="--disable-telemetry --skip-welcome --skip-release-notes --crash-reporter-directory=$VSCODECRASHDIR --logsPath=$VSCODELOGSDIR --no-cached-data --disable-updates --use-inmemory-secretstorage --disable-extensions --disable-workspace-trust --user-data-dir=$VSCODEUSERDATADIR"
if [ -z "$INTEGRATION_TEST_APP_NAME" ]; then
kill_app() { true; }
else
kill_app() { killall $INTEGRATION_TEST_APP_NAME || true; }
fi
echo
echo "### API tests (folder)"
echo
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests $API_TESTS_EXTRA_ARGS
kill_app
echo
echo "### API tests (workspace)"
echo
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests $API_TESTS_EXTRA_ARGS
kill_app
echo
echo "### Colorize tests"
echo
yarn test-extension -l vscode-colorize-tests
kill_app
echo
echo "### TypeScript tests"
echo
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/typescript-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS
kill_app
echo
echo "### Markdown tests"
echo
yarn test-extension -l markdown-language-features
kill_app
echo
echo "### Emmet tests"
echo
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/emmet/test-workspace --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test $API_TESTS_EXTRA_ARGS
kill_app
echo
echo "### Git tests"
echo
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test $API_TESTS_EXTRA_ARGS
kill_app
echo
echo "### Ipynb tests"
echo
yarn test-extension -l ipynb
kill_app
echo
echo "### Notebook Output tests"
echo
yarn test-extension -l notebook-renderers
kill_app
echo
echo "### Configuration editing tests"
echo
yarn test-extension -l configuration-editing
kill_app
echo
echo "### GitHub Authentication tests"
echo
yarn test-extension -l github-authentication
kill_app
# Tests standalone (CommonJS)
echo
echo "### CSS tests"
echo
cd $ROOT/extensions/css-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
echo
echo "### HTML tests"
echo
cd $ROOT/extensions/html-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
# Cleanup
rm -rf $VSCODEUSERDATADIR
+60 -64
View File
@@ -11,20 +11,16 @@
* @import { IProductConfiguration } from './vs/base/common/product'
*/
// ESM-comment-begin
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// import * as path from 'path';
// import * as fs from 'fs';
// import { fileURLToPath } from 'url';
// import { createRequire, register } from 'node:module';
// import { product, pkg } from './bootstrap-meta.js';
// import * as bootstrapNode from './bootstrap-node.js';
// import './bootstrap-node.js';
// import * as performance from './vs/base/common/performance.js';
//
// const require = createRequire(import.meta.url);
// const isESM = true;
// const module = { exports: {} };
// const __dirname = path.dirname(fileURLToPath(import.meta.url));
//
@@ -171,77 +167,77 @@ async function doSetupNLS() {
//#region Loader Config
if (isESM) {
// ESM-uncomment-begin
// /**
// * @param {string=} entrypoint
// * @param {(value: any) => void} [onLoad]
// * @param {(err: Error) => void} [onError]
// */
// module.exports.load = function (entrypoint, onLoad, onError) {
// if (!entrypoint) {
// return;
// }
/**
* @param {string=} entrypoint
* @param {(value: any) => void} [onLoad]
* @param {(err: Error) => void} [onError]
*/
module.exports.load = function (entrypoint, onLoad, onError) {
if (!entrypoint) {
return;
}
// entrypoint = `./${entrypoint}.js`;
entrypoint = `./${entrypoint}.js`;
// onLoad = onLoad || function () { };
// onError = onError || function (err) { console.error(err); };
onLoad = onLoad || function () { };
onError = onError || function (err) { console.error(err); };
// setupNLS().then(() => {
// performance.mark(`code/fork/willLoadCode`);
// import(entrypoint).then(onLoad, onError);
// });
// };
// ESM-uncomment-end
setupNLS().then(() => {
performance.mark(`code/fork/willLoadCode`);
import(entrypoint).then(onLoad, onError);
});
};
} else {
// ESM-comment-begin
// @ts-ignore
const loader = require('./vs/loader');
// @ts-ignore
const loader = require('./vs/loader');
loader.config({
baseUrl: bootstrapNode.fileUriFromPath(__dirname, { isWindows: process.platform === 'win32' }),
catchError: true,
nodeRequire,
amdModulesPattern: /^vs\//,
recordStats: true
});
loader.config({
baseUrl: bootstrapNode.fileUriFromPath(__dirname, { isWindows: process.platform === 'win32' }),
catchError: true,
nodeRequire,
amdModulesPattern: /^vs\//,
recordStats: true
// Running in Electron
if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions['electron']) {
loader.define('fs', ['original-fs'], function (/** @type {import('fs')} */originalFS) {
return originalFS; // replace the patched electron fs with the original node fs for all AMD code
});
}
// Running in Electron
if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions['electron']) {
loader.define('fs', ['original-fs'], function (/** @type {import('fs')} */originalFS) {
return originalFS; // replace the patched electron fs with the original node fs for all AMD code
/**
* @param {string=} entrypoint
* @param {(value: any) => void} [onLoad]
* @param {(err: Error) => void} [onError]
*/
module.exports.load = function (entrypoint, onLoad, onError) {
if (!entrypoint) {
return;
}
// code cache config
if (process.env['VSCODE_CODE_CACHE_PATH']) {
loader.config({
nodeCachedData: {
path: process.env['VSCODE_CODE_CACHE_PATH'],
seed: entrypoint
}
});
}
/**
* @param {string=} entrypoint
* @param {(value: any) => void} [onLoad]
* @param {(err: Error) => void} [onError]
*/
module.exports.load = function (entrypoint, onLoad, onError) {
if (!entrypoint) {
return;
}
onLoad = onLoad || function () { };
onError = onError || function (err) { console.error(err); };
// code cache config
if (process.env['VSCODE_CODE_CACHE_PATH']) {
loader.config({
nodeCachedData: {
path: process.env['VSCODE_CODE_CACHE_PATH'],
seed: entrypoint
}
});
}
onLoad = onLoad || function () { };
onError = onError || function (err) { console.error(err); };
setupNLS().then(() => {
performance.mark('code/fork/willLoadCode');
loader([entrypoint], onLoad, onError);
});
};
}
setupNLS().then(() => {
performance.mark('code/fork/willLoadCode');
loader([entrypoint], onLoad, onError);
});
};
// ESM-comment-end
//#endregion
+38 -45
View File
@@ -10,8 +10,6 @@
const path = require('path');
const fs = require('fs');
const Module = require('module');
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// import * as path from 'path';
@@ -20,8 +18,6 @@ const isESM = false;
// import { createRequire } from 'node:module';
//
// const require = createRequire(import.meta.url);
// const Module = require('module');
// const isESM = true;
// const module = { exports: {} };
// const __dirname = path.dirname(fileURLToPath(import.meta.url));
// ESM-uncomment-end
@@ -86,32 +82,31 @@ module.exports.devInjectNodeModuleLookupPath = function (injectPath) {
}
const Module = require('node:module');
if (isESM) {
// register a loader hook
// ESM-uncomment-begin
// Module.register('./bootstrap-import.js', { parentURL: import.meta.url, data: injectPath });
// ESM-uncomment-end
} else {
const nodeModulesPath = path.join(__dirname, '../node_modules');
// ESM-uncomment-begin
// // register a loader hook
// Module.register('./bootstrap-import.js', { parentURL: import.meta.url, data: injectPath });
// ESM-uncomment-end
// ESM-comment-begin
const nodeModulesPath = path.join(__dirname, '../node_modules');
// @ts-ignore
const originalResolveLookupPaths = Module._resolveLookupPaths;
// @ts-ignore
const originalResolveLookupPaths = Module._resolveLookupPaths;
// @ts-ignore
Module._resolveLookupPaths = function (moduleName, parent) {
const paths = originalResolveLookupPaths(moduleName, parent);
if (Array.isArray(paths)) {
for (let i = 0, len = paths.length; i < len; i++) {
if (paths[i] === nodeModulesPath) {
paths.splice(i, 0, injectPath);
break;
}
// @ts-ignore
Module._resolveLookupPaths = function (moduleName, parent) {
const paths = originalResolveLookupPaths(moduleName, parent);
if (Array.isArray(paths)) {
for (let i = 0, len = paths.length; i < len; i++) {
if (paths[i] === nodeModulesPath) {
paths.splice(i, 0, injectPath);
break;
}
}
}
return paths;
};
}
return paths;
};
// ESM-comment-end
};
module.exports.removeGlobalNodeModuleLookupPaths = function () {
@@ -207,36 +202,34 @@ module.exports.configurePortable = function (product) {
* Helper to enable ASAR support.
*/
module.exports.enableASARSupport = function () {
if (isESM) {
return; // TODO@esm ASAR support is disabled in ESM
} else {
const NODE_MODULES_PATH = path.join(__dirname, '../node_modules');
const NODE_MODULES_ASAR_PATH = `${NODE_MODULES_PATH}.asar`;
// ESM-comment-begin
const NODE_MODULES_PATH = path.join(__dirname, '../node_modules');
const NODE_MODULES_ASAR_PATH = `${NODE_MODULES_PATH}.asar`;
// @ts-ignore
const originalResolveLookupPaths = Module._resolveLookupPaths;
// @ts-ignore
const originalResolveLookupPaths = Module._resolveLookupPaths;
// @ts-ignore
Module._resolveLookupPaths = function (request, parent) {
const paths = originalResolveLookupPaths(request, parent);
if (Array.isArray(paths)) {
for (let i = 0, len = paths.length; i < len; i++) {
if (paths[i] === NODE_MODULES_PATH) {
paths.splice(i, 0, NODE_MODULES_ASAR_PATH);
break;
}
// @ts-ignore
Module._resolveLookupPaths = function (request, parent) {
const paths = originalResolveLookupPaths(request, parent);
if (Array.isArray(paths)) {
for (let i = 0, len = paths.length; i < len; i++) {
if (paths[i] === NODE_MODULES_PATH) {
paths.splice(i, 0, NODE_MODULES_ASAR_PATH);
break;
}
}
}
return paths;
};
}
return paths;
};
// ESM-comment-end
};
/**
* Helper to convert a file path to a URI.
*
* TODO@bpasero check for removal once ESM has landed.
* TODO@bpasero TODO@esm check for removal once ESM has landed.
*
* @param {string} path
* @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config
+115 -122
View File
@@ -15,13 +15,6 @@
/* eslint-disable no-restricted-globals */
// ESM-comment-begin
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// const isESM = true;
// ESM-uncomment-end
(function (factory) {
// @ts-ignore
globalThis.MonacoBootstrapWindow = factory();
@@ -95,133 +88,133 @@ const isESM = false;
window['MonacoEnvironment'] = {};
if (isESM) {
// ESM-uncomment-begin
// // Signal before require()
// if (typeof options?.beforeRequire === 'function') {
// options.beforeRequire(configuration);
// }
// Signal before require()
if (typeof options?.beforeRequire === 'function') {
options.beforeRequire(configuration);
}
// const baseUrl = new URL(`${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out/`);
// globalThis._VSCODE_FILE_ROOT = baseUrl.toString();
const baseUrl = new URL(`${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out/`);
globalThis._VSCODE_FILE_ROOT = baseUrl.toString();
// // DEV ---------------------------------------------------------------------------------------
// // DEV: This is for development and enables loading CSS via import-statements via import-maps.
// // DEV: For each CSS modules that we have we defined an entry in the import map that maps to
// // DEV: a blob URL that loads the CSS via a dynamic @import-rule.
// // DEV ---------------------------------------------------------------------------------------
// if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) {
// performance.mark('code/willAddCssLoader');
// DEV ---------------------------------------------------------------------------------------
// DEV: This is for development and enables loading CSS via import-statements via import-maps.
// DEV: For each CSS modules that we have we defined an entry in the import map that maps to
// DEV: a blob URL that loads the CSS via a dynamic @import-rule.
// DEV ---------------------------------------------------------------------------------------
if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) {
performance.mark('code/willAddCssLoader');
// const style = document.createElement('style');
// style.type = 'text/css';
// style.media = 'screen';
// style.id = 'vscode-css-loading';
// document.head.appendChild(style);
const style = document.createElement('style');
style.type = 'text/css';
style.media = 'screen';
style.id = 'vscode-css-loading';
document.head.appendChild(style);
// globalThis._VSCODE_CSS_LOAD = function (url) {
// style.textContent += `@import url(${url});\n`;
// };
globalThis._VSCODE_CSS_LOAD = function (url) {
style.textContent += `@import url(${url});\n`;
};
// /**
// * @type { { imports: Record<string, string> }}
// */
// const importMap = { imports: {} };
// for (const cssModule of configuration.cssModules) {
// const cssUrl = new URL(cssModule, baseUrl).href;
// const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\n`;
// const blob = new Blob([jsSrc], { type: 'application/javascript' });
// importMap.imports[cssUrl] = URL.createObjectURL(blob);
// }
/**
* @type { { imports: Record<string, string> }}
*/
const importMap = { imports: {} };
for (const cssModule of configuration.cssModules) {
const cssUrl = new URL(cssModule, baseUrl).href;
const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\n`;
const blob = new Blob([jsSrc], { type: 'application/javascript' });
importMap.imports[cssUrl] = URL.createObjectURL(blob);
// const ttp = window.trustedTypes?.createPolicy('vscode-bootstrapImportMap', { createScript(value) { return value; }, });
// const importMapSrc = JSON.stringify(importMap, undefined, 2);
// const importMapScript = document.createElement('script');
// importMapScript.type = 'importmap';
// importMapScript.setAttribute('nonce', '0c6a828f1297');
// // @ts-ignore
// importMapScript.textContent = ttp?.createScript(importMapSrc) ?? importMapSrc;
// document.head.appendChild(importMapScript);
// performance.mark('code/didAddCssLoader');
// }
// const result = Promise.all(modulePaths.map(modulePath => {
// if (modulePath.includes('vs/css!')) {
// // ESM/CSS when seeing the old `vs/css!` prefix we use that as a signal to
// // load CSS via a <link> tag
// const cssModule = modulePath.replace('vs/css!', '');
// const link = document.createElement('link');
// link.rel = 'stylesheet';
// link.href = new URL(`${cssModule}.css`, baseUrl).href;
// document.head.appendChild(link);
// return Promise.resolve();
// } else {
// // ESM/JS module loading
// return import(new URL(`${modulePath}.js`, baseUrl).href);
// }
// }));
// result.then((res) => invokeResult(res[0]), onUnexpectedError);
// ESM-uncomment-end
// ESM-comment-begin
/** @type {LoaderConfig} */
const loaderConfig = {
baseUrl: `${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`,
preferScriptTags: true
};
// use a trusted types policy when loading via script tags
loaderConfig.trustedTypesPolicy = window.trustedTypes?.createPolicy('amdLoader', {
createScriptURL(value) {
if (value.startsWith(window.location.origin)) {
return value;
}
const ttp = window.trustedTypes?.createPolicy('vscode-bootstrapImportMap', { createScript(value) { return value; }, });
const importMapSrc = JSON.stringify(importMap, undefined, 2);
const importMapScript = document.createElement('script');
importMapScript.type = 'importmap';
importMapScript.setAttribute('nonce', '0c6a828f1297');
// @ts-ignore
importMapScript.textContent = ttp?.createScript(importMapSrc) ?? importMapSrc;
document.head.appendChild(importMapScript);
performance.mark('code/didAddCssLoader');
throw new Error(`Invalid script url: ${value}`);
}
});
const result = Promise.all(modulePaths.map(modulePath => {
if (modulePath.includes('vs/css!')) {
// ESM/CSS when seeing the old `vs/css!` prefix we use that as a signal to
// load CSS via a <link> tag
const cssModule = modulePath.replace('vs/css!', '');
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = new URL(`${cssModule}.css`, baseUrl).href;
document.head.appendChild(link);
return Promise.resolve();
// Teach the loader the location of the node modules we use in renderers
// This will enable to load these modules via <script> tags instead of
// using a fallback such as node.js require which does not exist in sandbox
const baseNodeModulesPath = isDev ? '../node_modules' : '../node_modules.asar';
loaderConfig.paths = {
'@vscode/tree-sitter-wasm': `${baseNodeModulesPath}/@vscode/tree-sitter-wasm/wasm/tree-sitter.js`,
'vscode-textmate': `${baseNodeModulesPath}/vscode-textmate/release/main.js`,
'vscode-oniguruma': `${baseNodeModulesPath}/vscode-oniguruma/release/main.js`,
'vsda': `${baseNodeModulesPath}/vsda/index.js`,
'@xterm/xterm': `${baseNodeModulesPath}/@xterm/xterm/lib/xterm.js`,
'@xterm/addon-clipboard': `${baseNodeModulesPath}/@xterm/addon-clipboard/lib/addon-clipboard.js`,
'@xterm/addon-image': `${baseNodeModulesPath}/@xterm/addon-image/lib/addon-image.js`,
'@xterm/addon-search': `${baseNodeModulesPath}/@xterm/addon-search/lib/addon-search.js`,
'@xterm/addon-serialize': `${baseNodeModulesPath}/@xterm/addon-serialize/lib/addon-serialize.js`,
'@xterm/addon-unicode11': `${baseNodeModulesPath}/@xterm/addon-unicode11/lib/addon-unicode11.js`,
'@xterm/addon-webgl': `${baseNodeModulesPath}/@xterm/addon-webgl/lib/addon-webgl.js`,
'@vscode/iconv-lite-umd': `${baseNodeModulesPath}/@vscode/iconv-lite-umd/lib/iconv-lite-umd.js`,
'jschardet': `${baseNodeModulesPath}/jschardet/dist/jschardet.min.js`,
'@vscode/vscode-languagedetection': `${baseNodeModulesPath}/@vscode/vscode-languagedetection/dist/lib/index.js`,
'vscode-regexp-languagedetection': `${baseNodeModulesPath}/vscode-regexp-languagedetection/dist/index.js`,
'tas-client-umd': `${baseNodeModulesPath}/tas-client-umd/lib/tas-client-umd.js`
};
} else {
// ESM/JS module loading
return import(new URL(`${modulePath}.js`, baseUrl).href);
}
}));
result.then((res) => invokeResult(res[0]), onUnexpectedError);
} else {
/** @type {LoaderConfig} */
const loaderConfig = {
baseUrl: `${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`,
preferScriptTags: true
};
// use a trusted types policy when loading via script tags
loaderConfig.trustedTypesPolicy = window.trustedTypes?.createPolicy('amdLoader', {
createScriptURL(value) {
if (value.startsWith(window.location.origin)) {
return value;
}
throw new Error(`Invalid script url: ${value}`);
}
});
// Teach the loader the location of the node modules we use in renderers
// This will enable to load these modules via <script> tags instead of
// using a fallback such as node.js require which does not exist in sandbox
const baseNodeModulesPath = isDev ? '../node_modules' : '../node_modules.asar';
loaderConfig.paths = {
'@vscode/tree-sitter-wasm': `${baseNodeModulesPath}/@vscode/tree-sitter-wasm/wasm/tree-sitter.js`,
'vscode-textmate': `${baseNodeModulesPath}/vscode-textmate/release/main.js`,
'vscode-oniguruma': `${baseNodeModulesPath}/vscode-oniguruma/release/main.js`,
'vsda': `${baseNodeModulesPath}/vsda/index.js`,
'@xterm/xterm': `${baseNodeModulesPath}/@xterm/xterm/lib/xterm.js`,
'@xterm/addon-clipboard': `${baseNodeModulesPath}/@xterm/addon-clipboard/lib/addon-clipboard.js`,
'@xterm/addon-image': `${baseNodeModulesPath}/@xterm/addon-image/lib/addon-image.js`,
'@xterm/addon-search': `${baseNodeModulesPath}/@xterm/addon-search/lib/addon-search.js`,
'@xterm/addon-serialize': `${baseNodeModulesPath}/@xterm/addon-serialize/lib/addon-serialize.js`,
'@xterm/addon-unicode11': `${baseNodeModulesPath}/@xterm/addon-unicode11/lib/addon-unicode11.js`,
'@xterm/addon-webgl': `${baseNodeModulesPath}/@xterm/addon-webgl/lib/addon-webgl.js`,
'@vscode/iconv-lite-umd': `${baseNodeModulesPath}/@vscode/iconv-lite-umd/lib/iconv-lite-umd.js`,
'jschardet': `${baseNodeModulesPath}/jschardet/dist/jschardet.min.js`,
'@vscode/vscode-languagedetection': `${baseNodeModulesPath}/@vscode/vscode-languagedetection/dist/lib/index.js`,
'vscode-regexp-languagedetection': `${baseNodeModulesPath}/vscode-regexp-languagedetection/dist/index.js`,
'tas-client-umd': `${baseNodeModulesPath}/tas-client-umd/lib/tas-client-umd.js`
};
// Signal before require.config()
if (typeof options?.beforeLoaderConfig === 'function') {
options.beforeLoaderConfig(loaderConfig);
}
// Configure loader
require.config(loaderConfig);
// Signal before require()
if (typeof options?.beforeRequire === 'function') {
options.beforeRequire(configuration);
}
// Actually require the main module as specified
require(modulePaths, invokeResult, onUnexpectedError);
// Signal before require.config()
if (typeof options?.beforeLoaderConfig === 'function') {
options.beforeLoaderConfig(loaderConfig);
}
// Configure loader
require.config(loaderConfig);
// Signal before require()
if (typeof options?.beforeRequire === 'function') {
options.beforeRequire(configuration);
}
// Actually require the main module as specified
require(modulePaths, invokeResult, onUnexpectedError);
// ESM-comment-end
/**
* @param {any} firstModule
*/
+64 -28
View File
@@ -5,9 +5,18 @@
import { createTrustedTypesPolicy } from 'vs/base/browser/trustedTypes';
import { onUnexpectedError } from 'vs/base/common/errors';
import { COI } from 'vs/base/common/network';
import { AppResourcePath, COI, FileAccess } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { coalesce } from 'vs/base/common/arrays';
// ESM-comment-begin
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// const isESM = true;
// ESM-uncomment-end
// Reuse the trusted types policy defined from worker bootstrap
// when available.
@@ -23,10 +32,10 @@ export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Work
if (!blobUrl.startsWith('blob:')) {
throw new URIError('Not a blob-url: ' + blobUrl);
}
return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, options);
return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, { ...options, type: isESM ? 'module' : undefined });
}
function getWorker(label: string): Worker | Promise<Worker> {
function getWorker(workerMainLocation: URI | undefined, label: string): Worker | Promise<Worker> {
// Option for hosts to overwrite the worker script (used in the standalone editor)
interface IMonacoEnvironment {
getWorker?(moduleId: string, label: string): Worker | Promise<Worker>;
@@ -39,56 +48,76 @@ function getWorker(label: string): Worker | Promise<Worker> {
}
if (typeof monacoEnvironment.getWorkerUrl === 'function') {
const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', label);
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label });
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: isESM ? 'module' : undefined });
}
}
// ESM-comment-begin
if (typeof require === 'function') {
// check if the JS lives on a different origin
const workerMain = require.toUrl('vs/base/worker/workerMain.js'); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321
const workerUrl = getWorkerBootstrapUrl(workerMain, label);
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label });
const workerMainLocation = require.toUrl('vs/base/worker/workerMain.js'); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321
const factoryModuleId = 'vs/base/worker/defaultWorkerFactory.js';
const workerBaseUrl = require.toUrl(factoryModuleId).slice(0, -factoryModuleId.length); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321
const workerUrl = getWorkerBootstrapUrl(label, workerMainLocation, workerBaseUrl);
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: isESM ? 'module' : undefined });
}
// ESM-comment-end
if (workerMainLocation) {
const workerUrl = getWorkerBootstrapUrl(label, workerMainLocation.toString(true));
const worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: isESM ? 'module' : undefined });
if (isESM) {
return whenESMWorkerReady(worker);
} else {
return worker;
}
}
throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
}
// ESM-comment-begin
export function getWorkerBootstrapUrl(scriptPath: string, label: string): string {
if (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, globalThis.origin.length) !== globalThis.origin) {
function getWorkerBootstrapUrl(label: string, workerScriptUrl: string, workerBaseUrl?: string): string {
if (/^((http:)|(https:)|(file:))/.test(workerScriptUrl) && workerScriptUrl.substring(0, globalThis.origin.length) !== globalThis.origin) {
// this is the cross-origin case
// i.e. the webpage is running at a different origin than where the scripts are loaded from
} else {
const start = scriptPath.lastIndexOf('?');
const end = scriptPath.lastIndexOf('#', start);
const start = workerScriptUrl.lastIndexOf('?');
const end = workerScriptUrl.lastIndexOf('#', start);
const params = start > 0
? new URLSearchParams(scriptPath.substring(start + 1, ~end ? end : undefined))
? new URLSearchParams(workerScriptUrl.substring(start + 1, ~end ? end : undefined))
: new URLSearchParams();
COI.addSearchParam(params, true, true);
const search = params.toString();
if (!search) {
scriptPath = `${scriptPath}#${label}`;
workerScriptUrl = `${workerScriptUrl}#${label}`;
} else {
scriptPath = `${scriptPath}?${params.toString()}#${label}`;
workerScriptUrl = `${workerScriptUrl}?${params.toString()}#${label}`;
}
}
const factoryModuleId = 'vs/base/worker/defaultWorkerFactory.js';
const workerBaseUrl = require.toUrl(factoryModuleId).slice(0, -factoryModuleId.length); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321
const blob = new Blob([[
const blob = new Blob([coalesce([
`/*${label}*/`,
`globalThis.MonacoEnvironment = { baseUrl: '${workerBaseUrl}' };`,
workerBaseUrl ? `globalThis.MonacoEnvironment = { baseUrl: '${workerBaseUrl}' };` : undefined,
`globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(globalThis._VSCODE_NLS_MESSAGES)};`,
`globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(globalThis._VSCODE_NLS_LANGUAGE)};`,
`globalThis._VSCODE_FILE_ROOT = '${globalThis._VSCODE_FILE_ROOT}';`,
`const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });`,
`globalThis.workerttPolicy = ttPolicy;`,
`importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');`,
isESM ? `await import(ttPolicy?.createScriptURL('${workerScriptUrl}') ?? '${workerScriptUrl}');` : `importScripts(ttPolicy?.createScriptURL('${workerScriptUrl}') ?? '${workerScriptUrl}');`, //
isESM ? `globalThis.postMessage({ type: 'vscode-worker-ready' });` : undefined, // in ESM signal we are ready after the async import
`/*${label}*/`
].join('')], { type: 'application/javascript' });
]).join('')], { type: 'application/javascript' });
return URL.createObjectURL(blob);
}
// ESM-comment-end
function whenESMWorkerReady(worker: Worker): Promise<Worker> {
return new Promise<Worker>((resolve, reject) => {
worker.onmessage = function (e) {
if (e.data.type === 'vscode-worker-ready') {
worker.onmessage = null;
resolve(worker);
}
};
worker.onerror = reject;
});
}
function isPromiseLike<T>(obj: any): obj is PromiseLike<T> {
if (typeof obj.then === 'function') {
@@ -107,11 +136,11 @@ class WebWorker extends Disposable implements IWorker {
private readonly label: string;
private worker: Promise<Worker> | null;
constructor(moduleId: string, id: number, label: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void) {
constructor(workerMainLocation: URI | undefined, moduleId: string, id: number, label: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void) {
super();
this.id = id;
this.label = label;
const workerOrPromise = getWorker(label);
const workerOrPromise = getWorker(workerMainLocation, label);
if (isPromiseLike(workerOrPromise)) {
this.worker = workerOrPromise;
} else {
@@ -161,19 +190,26 @@ export class DefaultWorkerFactory implements IWorkerFactory {
private _label: string | undefined;
private _webWorkerFailedBeforeError: any;
constructor(label: string | undefined) {
constructor(private readonly workerMainLocation: URI | undefined, label: string | undefined) {
this._label = label;
this._webWorkerFailedBeforeError = false;
}
public create(moduleId: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void): IWorker {
public create(modules: { moduleId: string; esmModuleId: string }, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void): IWorker {
const workerId = (++DefaultWorkerFactory.LAST_WORKER_ID);
if (this._webWorkerFailedBeforeError) {
throw this._webWorkerFailedBeforeError;
}
return new WebWorker(moduleId, workerId, this._label || 'anonymous' + workerId, onMessageCallback, (err) => {
let workerMainLocation = this.workerMainLocation;
const moduleId = modules.moduleId;
if (isESM) {
workerMainLocation = FileAccess.asBrowserUri(`${modules.esmModuleId}.esm.js` as AppResourcePath);
}
return new WebWorker(workerMainLocation, moduleId, workerId, this._label || 'anonymous' + workerId, onMessageCallback, (err) => {
logOnceWebWorkerWarning(err);
this._webWorkerFailedBeforeError = err;
onErrorCallback(err);
+1 -1
View File
@@ -209,7 +209,7 @@ export class Dialog extends Disposable {
// Handle button clicks
buttonMap.forEach((entry, index) => {
const primary = buttonMap[index].index === 0;
const button = this.options.buttonDetails ? this._register(buttonBar.addButtonWithDescription({ title: true, secondary: !primary, ...this.buttonStyles })) : this._register(buttonBar.addButton({ title: true, secondary: !primary, ...this.buttonStyles }));
const button = this.options.buttonDetails ? this._register(buttonBar.addButtonWithDescription({ secondary: !primary, ...this.buttonStyles })) : this._register(buttonBar.addButton({ secondary: !primary, ...this.buttonStyles }));
button.label = mnemonicButtonLabel(buttonMap[index].label, true);
if (button instanceof ButtonWithDescription) {
button.description = this.options.buttonDetails![buttonMap[index].index];
+35 -4
View File
@@ -9,11 +9,20 @@
* The code in this file is generated from files in ./src/
*/
// ESM-uncomment-begin
// let __marked_exports = {};
// (function() {
// function define(deps, factory) {
// factory(__marked_exports);
// }
// define.amd = true;
// ESM-uncomment-end
(function (global, factory) {
typeof define === 'function' && define.amd ? define(['exports'], factory) :
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {}));
})(this, (function (exports) {
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {}));
})(this, (function (exports) {
'use strict';
/**
@@ -2502,6 +2511,28 @@
exports.setOptions = setOptions;
exports.use = use;
exports.walkTokens = walkTokens;
}));
// ESM-uncomment-begin
// })();
// export var Hooks = (__marked_exports.Hooks || exports.Hooks);
// export var Lexer = (__marked_exports.Lexer || exports.Lexer);
// export var Marked = (__marked_exports.Marked || exports.Marked);
// export var Parser = (__marked_exports.Parser || exports.Parser);
// export var Renderer = (__marked_exports.Renderer || exports.Renderer);
// export var TextRenderer = (__marked_exports.TextRenderer || exports.TextRenderer);
// export var Tokenizer = (__marked_exports.Tokenizer || exports.Tokenizer);
// export var defaults = (__marked_exports.defaults || exports.defaults);
// export var getDefaults = (__marked_exports.getDefaults || exports.getDefaults);
// export var lexer = (__marked_exports.lexer || exports.lexer);
// export var marked = (__marked_exports.marked || exports.marked);
// export var options = (__marked_exports.options || exports.options);
// export var parse = (__marked_exports.parse || exports.parse);
// export var parseInline = (__marked_exports.parseInline || exports.parseInline);
// export var parser = (__marked_exports.parser || exports.parser);
// export var setOptions = (__marked_exports.setOptions || exports.setOptions);
// export var use = (__marked_exports.use || exports.use);
// export var walkTokens = (__marked_exports.walkTokens || exports.walkTokens);
// ESM-uncomment-end
//# sourceMappingURL=marked.umd.js.map
+25 -2
View File
@@ -253,7 +253,12 @@ class FileAccessImpl {
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
*/
asBrowserUri(resourcePath: AppResourcePath | ''): URI {
// ESM-comment-begin
const uri = this.toUri(resourcePath, require);
// ESM-comment-end
// ESM-uncomment-begin
// const uri = this.toUri(resourcePath);
// ESM-uncomment-end
return this.uriToBrowserUri(uri);
}
@@ -300,7 +305,12 @@ class FileAccessImpl {
* is responsible for loading.
*/
asFileUri(resourcePath: AppResourcePath | ''): URI {
// ESM-comment-begin
const uri = this.toUri(resourcePath, require);
// ESM-comment-end
// ESM-uncomment-begin
// const uri = this.toUri(resourcePath);
// ESM-uncomment-end
return this.uriToFileUri(uri);
}
@@ -325,12 +335,25 @@ class FileAccessImpl {
return uri;
}
private toUri(uriOrModule: URI | string, moduleIdToUrl: { toUrl(moduleId: string): string }): URI {
private toUri(uriOrModule: URI | string, moduleIdToUrl?: { toUrl(moduleId: string): string }): URI {
if (URI.isUri(uriOrModule)) {
return uriOrModule;
}
return URI.parse(moduleIdToUrl.toUrl(uriOrModule));
if (globalThis._VSCODE_FILE_ROOT) {
const rootUriOrPath = globalThis._VSCODE_FILE_ROOT;
// File URL (with scheme)
if (/^\w[\w\d+.-]*:\/\//.test(rootUriOrPath)) {
return URI.joinPath(URI.parse(rootUriOrPath, true), uriOrModule);
}
// File Path (no scheme)
const modulePath = paths.join(rootUriOrPath, uriOrModule);
return URI.file(modulePath);
}
return URI.parse(moduleIdToUrl!.toUrl(uriOrModule));
}
}
+23 -2
View File
@@ -6,10 +6,18 @@
import { transformErrorForSerialization } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { AppResourcePath, FileAccess } from 'vs/base/common/network';
import { getAllMethodNames } from 'vs/base/common/objects';
import { isWeb } from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';
// ESM-comment-begin
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// const isESM = true;
// ESM-uncomment-end
const INITIALIZE = '$initialize';
export interface IWorker extends IDisposable {
@@ -22,7 +30,7 @@ export interface IWorkerCallback {
}
export interface IWorkerFactory {
create(moduleId: string, callback: IWorkerCallback, onErrorCallback: (err: any) => void): IWorker;
create(modules: { moduleId: string; esmModuleId: string }, callback: IWorkerCallback, onErrorCallback: (err: any) => void): IWorker;
}
let webWorkerWarningLogged = false;
@@ -276,7 +284,7 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp
let lazyProxyReject: ((err: any) => void) | null = null;
this._worker = this._register(workerFactory.create(
'vs/base/common/worker/simpleWorker',
{ moduleId: 'vs/base/common/worker/simpleWorker', esmModuleId: moduleId },
(msg: Message) => {
this._protocol.handleMessage(msg);
},
@@ -532,6 +540,19 @@ export class SimpleWorkerServer<H extends object> {
globalThis.require.config(loaderConfig);
}
if (isESM) {
const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true);
return import(`${url}`).then((module: { create: IRequestHandlerFactory<H> }) => {
this._requestHandler = module.create(hostProxy);
if (!this._requestHandler) {
throw new Error(`No RequestHandler!`);
}
return getAllMethodNames(this._requestHandler);
});
}
return new Promise<string[]>((resolve, reject) => {
// Use the global require to be sure to get the global config
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IRequestHandlerFactory, SimpleWorkerServer } from 'vs/base/common/worker/simpleWorker';
type MessageEvent = {
data: any;
};
declare const globalThis: {
postMessage: (message: any) => void;
onmessage: (event: MessageEvent) => void;
};
let initialized = false;
function initialize<H extends object>(factory: IRequestHandlerFactory<H>) {
if (initialized) {
return;
}
initialized = true;
const simpleWorker = new SimpleWorkerServer<H>(
msg => globalThis.postMessage(msg),
host => factory(host)
);
globalThis.onmessage = (e: MessageEvent) => {
simpleWorker.onmessage(e.data);
};
}
export function bootstrapSimpleWorker<H extends object>(factory: IRequestHandlerFactory<H>) {
globalThis.onmessage = (_e: MessageEvent) => {
// Ignore first message in this case and initialize if not yet initialized
if (!initialized) {
initialize(factory);
}
};
}
@@ -12,9 +12,9 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { request } from 'vs/base/parts/request/browser/request';
import { streamToBuffer } from 'vs/base/common/buffer';
import { flakySuite } from 'vs/base/test/common/testUtils';
suite('Request', () => {
flakySuite('Request', () => {
let port: number;
let server: http.Server;
@@ -72,7 +72,7 @@ export interface ISandboxConfiguration {
};
/**
* DEV time only! All css-modules that we have.
* DEV time only: All CSS-modules that we have.
*/
cssModules?: string[];
}
+40 -15
View File
@@ -13,6 +13,7 @@
): undefined | Pick<TrustedTypePolicy<Options>, 'name' | Extract<keyof Options, keyof TrustedTypePolicyOptions>>;
}
const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment;
const monacoBaseUrl = monacoEnvironment && monacoEnvironment.baseUrl ? monacoEnvironment.baseUrl : '../../../';
function createTrustedTypesPolicy<Options extends TrustedTypePolicyOptions>(
@@ -111,23 +112,43 @@
});
}
function loadCode(moduleId: string) {
loadAMDLoader().then(() => {
configureAMDLoader();
require([moduleId], function (ws) {
setTimeout(function () {
const messageHandler = ws.create((msg: any, transfer?: Transferable[]) => {
(<any>globalThis).postMessage(msg, transfer);
}, null);
function loadCode(moduleId: string): Promise<SimpleWorkerModule> {
// ESM-uncomment-begin
// if (typeof loadAMDLoader === 'function') { /* fixes unused import, remove me */}
// const moduleUrl = new URL(`${moduleId}.js`, globalThis._VSCODE_FILE_ROOT);
// return import(moduleUrl.href);
// ESM-uncomment-end
globalThis.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports);
while (beforeReadyMessages.length > 0) {
const e = beforeReadyMessages.shift()!;
messageHandler.onmessage(e.data, e.ports);
}
}, 0);
// ESM-comment-begin
return loadAMDLoader().then(() => {
configureAMDLoader();
return new Promise<SimpleWorkerModule>((resolve, reject) => {
require([moduleId], resolve, reject);
});
});
// ESM-comment-end
}
interface MessageHandler {
onmessage(msg: any, ports: readonly MessagePort[]): void;
}
// shape of vs/base/common/worker/simpleWorker.ts
interface SimpleWorkerModule {
create(postMessage: (msg: any, transfer?: Transferable[]) => void): MessageHandler;
}
function setupWorkerServer(ws: SimpleWorkerModule) {
setTimeout(function () {
const messageHandler = ws.create((msg: any, transfer?: Transferable[]) => {
(<any>globalThis).postMessage(msg, transfer);
});
self.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports);
while (beforeReadyMessages.length > 0) {
self.onmessage(beforeReadyMessages.shift()!);
}
}, 0);
}
// If the loader is already defined, configure it immediately
@@ -146,6 +167,10 @@
}
isFirstMessage = false;
loadCode(message.data);
loadCode(message.data).then((ws) => {
setupWorkerServer(ws);
}, (err) => {
console.error(err);
});
};
})();
@@ -0,0 +1,67 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<script>
performance.mark('code/didStartRenderer');
</script>
<meta charset="utf-8" />
<!-- Mobile tweaks -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Code">
<link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" />
<!-- Disable pinch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<!-- Workbench Configuration -->
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONFIGURATION}}">
<!-- Workbench Auth Session -->
<meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}">
<!-- Builtin Extensions (running out of sources) -->
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
<!-- Workbench Icon/Manifest/CSS -->
<link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" />
<link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" />
<style id="vscode-css-modules" type="text/css" media="screen"></style>
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script>
const baseUrl = new URL('{{WORKBENCH_WEB_BASE_URL}}', window.location.origin).toString();
globalThis._VSCODE_FILE_ROOT = baseUrl + '/out/';
</script>
<script>
const sheet = document.getElementById('vscode-css-modules').sheet;
globalThis._VSCODE_CSS_LOAD = function (url) {
sheet.insertRule(`@import url(${url});`);
};
const importMap = { imports: {} };
const cssModules = JSON.parse('{{WORKBENCH_DEV_CSS_MODULES}}');
for (const cssModule of cssModules) {
const cssUrl = new URL(cssModule, globalThis._VSCODE_FILE_ROOT).href;
const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\n`;
const blob = new Blob([jsSrc], { type: 'application/javascript' });
importMap.imports[cssUrl] = URL.createObjectURL(blob);
}
const importMapElement = document.createElement('script');
importMapElement.type = 'importmap';
importMapElement.setAttribute('nonce', '1nline-m4p')
importMapElement.textContent = JSON.stringify(importMap, undefined, 2);
document.head.appendChild(importMapElement);
</script>
<script>
performance.mark('code/willLoadWorkbenchMain');
</script>
<script type="module" src="{{WORKBENCH_WEB_BASE_URL}}/out/vs/code/browser/workbench/workbench.js"></script>
</html>
@@ -0,0 +1,48 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<script>
performance.mark('code/didStartRenderer');
</script>
<meta charset="utf-8" />
<!-- Mobile tweaks -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Code">
<link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" />
<!-- Disable pinch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<!-- Workbench Configuration -->
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONFIGURATION}}">
<!-- Workbench Auth Session -->
<meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}">
<!-- Workbench Icon/Manifest/CSS -->
<link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" />
<link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" />
<link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.main.css">
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script>
const baseUrl = new URL('{{WORKBENCH_WEB_BASE_URL}}', window.location.origin).toString();
globalThis._VSCODE_FILE_ROOT = baseUrl + '/out/';
</script>
<script>
performance.mark('code/willLoadWorkbenchMain');
</script>
<!-- always ensure built in english NLS messages -->
<script type="module" src="{{WORKBENCH_NLS_FALLBACK_URL}}"></script>
<!-- attempt to load NLS messages in case non-english -->
<script type="module" src="{{WORKBENCH_NLS_URL}}"></script>
<script type="module" src="{{WORKBENCH_WEB_BASE_URL}}/out/vs/code/browser/workbench/workbench.js"></script>
</html>
+5
View File
@@ -121,6 +121,8 @@ import { Lazy } from 'vs/base/common/lazy';
import { IAuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
import { AuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService';
import { normalizeNFC } from 'vs/base/common/normalization';
import { ICSSDevelopmentService, CSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
/**
* The main VS Code application. There will only ever be one instance,
* even if the user starts many instances (e.g. from the command line).
@@ -1101,6 +1103,9 @@ export class CodeApplication extends Disposable {
// Proxy Auth
services.set(IProxyAuthService, new SyncDescriptor(ProxyAuthService));
// Dev Only: CSS service (for ESM)
services.set(ICSSDevelopmentService, new SyncDescriptor(CSSDevelopmentService, undefined, true));
// Init services that require it
await Promises.settled([
backupMainService.initialize(),
@@ -0,0 +1,43 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="
default-src
'none'
;
img-src
'self'
data:
;
script-src
'self'
blob:
'nonce-0c6a828f1297'
;
style-src
'self'
'unsafe-inline'
;
connect-src
'self'
https:
;
font-src
'self'
;
">
</head>
<body aria-label="">
<div id="process-list"></div>
</body>
<!-- Startup (do not modify order of script tags!) -->
<script src="../../../../vs/loader.js"></script>
<script src="../../../../bootstrap-window.js"></script>
<script src="./processExplorer.js"></script>
</html>
@@ -0,0 +1,42 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="
default-src
'none'
;
img-src
'self'
data:
;
script-src
'self'
blob:
'nonce-0c6a828f1297'
;
style-src
'self'
'unsafe-inline'
;
connect-src
'self'
https:
;
font-src
'self'
;
">
<link rel="stylesheet" href="./processExplorerMain.css">
</head>
<body aria-label="">
<div id="process-list"></div>
</body>
<!-- Startup (do not modify order of script tags!) -->
<script src="./processExplorer.js" type="module"></script>
</html>
@@ -0,0 +1,76 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="
default-src
'none'
;
img-src
'self'
data:
blob:
vscode-remote-resource:
vscode-managed-remote-resource:
https:
;
media-src
'self'
;
frame-src
'self'
vscode-webview:
;
script-src
'self'
'unsafe-eval'
blob:
'nonce-0c6a828f1297'
;
style-src
'self'
'unsafe-inline'
;
connect-src
'self'
https:
ws:
;
font-src
'self'
vscode-remote-resource:
vscode-managed-remote-resource:
https://*.vscode-unpkg.net
;
require-trusted-types-for
'script'
;
trusted-types
vscode-bootstrapImportMap
amdLoader
cellRendererEditorText
defaultWorkerFactory
diffEditorWidget
diffReview
domLineBreaksComputer
dompurify
editorGhostText
editorViewLayer
notebookRenderer
stickyScrollViewLayer
tokenizeToString
;
"/>
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script src="../../../../vs/loader.js"></script>
<script src="../../../../bootstrap-window.js"></script>
<script src="./workbench.js"></script>
</html>
@@ -0,0 +1,72 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="
default-src
'none'
;
img-src
'self'
data:
blob:
vscode-remote-resource:
vscode-managed-remote-resource:
https:
;
media-src
'self'
;
frame-src
'self'
vscode-webview:
;
script-src
'self'
'unsafe-eval'
blob:
;
style-src
'self'
'unsafe-inline'
;
connect-src
'self'
https:
ws:
;
font-src
'self'
vscode-remote-resource:
vscode-managed-remote-resource:
https://*.vscode-unpkg.net
;
require-trusted-types-for
'script'
;
trusted-types
amdLoader
cellRendererEditorText
defaultWorkerFactory
diffEditorWidget
diffReview
domLineBreaksComputer
dompurify
editorGhostText
editorViewLayer
notebookRenderer
stickyScrollViewLayer
tokenizeToString
;
"/>
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script src="./workbench.js" type="module"></script>
</html>
+4 -1
View File
@@ -398,7 +398,10 @@ export async function main(argv: string[]): Promise<any> {
return false;
}
if (target.type === 'page') {
return target.url.indexOf('workbench/workbench.html') > 0 || target.url.indexOf('workbench/workbench-dev.html') > 0;
return target.url.indexOf('workbench/workbench.html') > 0 ||
target.url.indexOf('workbench/workbench-dev.html') > 0 ||
target.url.indexOf('workbench/workbench.esm.html') > 0 ||
target.url.indexOf('workbench/workbench-dev.esm.html') > 0;
} else {
return true;
}
@@ -63,6 +63,7 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ
private readonly _logService: ILogService;
constructor(
workerMainLocation: URI | undefined,
@IModelService modelService: IModelService,
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,
@ILogService logService: ILogService,
@@ -71,7 +72,7 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ
) {
super();
this._modelService = modelService;
this._workerManager = this._register(new WorkerManager(this._modelService, languageConfigurationService));
this._workerManager = this._register(new WorkerManager(workerMainLocation, this._modelService, languageConfigurationService));
this._logService = logService;
// register default link-provider and default completions-provider
@@ -281,7 +282,7 @@ class WorkerManager extends Disposable {
private _editorWorkerClient: EditorWorkerClient | null;
private _lastWorkerUsedTime: number;
constructor(modelService: IModelService, private readonly languageConfigurationService: ILanguageConfigurationService) {
constructor(private readonly workerMainLocation: URI | undefined, modelService: IModelService, private readonly languageConfigurationService: ILanguageConfigurationService) {
super();
this._modelService = modelService;
this._editorWorkerClient = null;
@@ -335,7 +336,7 @@ class WorkerManager extends Disposable {
public withWorker(): Promise<EditorWorkerClient> {
this._lastWorkerUsedTime = (new Date()).getTime();
if (!this._editorWorkerClient) {
this._editorWorkerClient = new EditorWorkerClient(this._modelService, false, 'editorWorkerService', this.languageConfigurationService);
this._editorWorkerClient = new EditorWorkerClient(this.workerMainLocation, this._modelService, false, 'editorWorkerService', this.languageConfigurationService);
}
return Promise.resolve(this._editorWorkerClient);
}
@@ -484,6 +485,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien
private _disposed = false;
constructor(
workerMainLocation: URI | undefined,
modelService: IModelService,
keepIdleModels: boolean,
label: string | undefined,
@@ -492,7 +494,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien
super();
this._modelService = modelService;
this._keepIdleModels = keepIdleModels;
this._workerFactory = new DefaultWorkerFactory(label);
this._workerFactory = new DefaultWorkerFactory(workerMainLocation, label);
this._worker = null;
this._modelManager = null;
}
+11 -3
View File
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { FileAccess } from 'vs/base/common/network';
import { getAllMethodNames } from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import { EditorWorkerClient } from 'vs/editor/browser/services/editorWorkerService';
@@ -14,7 +15,14 @@ import { IModelService } from 'vs/editor/common/services/model';
* Specify an AMD module to load that will `create` an object that will be proxied.
*/
export function createWebWorker<T extends object>(modelService: IModelService, languageConfigurationService: ILanguageConfigurationService, opts: IWebWorkerOptions): MonacoWebWorker<T> {
return new MonacoWebWorkerImpl<T>(modelService, languageConfigurationService, opts);
return new MonacoWebWorkerImpl<T>(undefined, modelService, languageConfigurationService, opts);
}
/**
* @internal
*/
export function createWorkbenchWebWorker<T extends object>(modelService: IModelService, languageConfigurationService: ILanguageConfigurationService, opts: IWebWorkerOptions): MonacoWebWorker<T> {
return new MonacoWebWorkerImpl<T>(FileAccess.asBrowserUri('vs/base/worker/workerMain.js'), modelService, languageConfigurationService, opts);
}
/**
@@ -68,8 +76,8 @@ class MonacoWebWorkerImpl<T extends object> extends EditorWorkerClient implement
private _foreignModuleCreateData: any | null;
private _foreignProxy: Promise<T> | null;
constructor(modelService: IModelService, languageConfigurationService: ILanguageConfigurationService, opts: IWebWorkerOptions) {
super(modelService, opts.keepIdleModels || false, opts.label, languageConfigurationService);
constructor(workerMainLocation: URI | undefined, modelService: IModelService, languageConfigurationService: ILanguageConfigurationService, opts: IWebWorkerOptions) {
super(workerMainLocation, modelService, opts.keepIdleModels || false, opts.label, languageConfigurationService);
this._foreignModuleId = opts.moduleId;
this._foreignModuleCreateData = opts.createData || null;
this._foreignModuleHost = opts.host || null;
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { create } from 'vs/editor/common/services/editorSimpleWorker';
import { bootstrapSimpleEditorWorker } from './editorWorkerBootstrap';
bootstrapSimpleEditorWorker(create);
@@ -26,10 +26,18 @@ import { DetailedLineRangeMapping } from '../diff/rangeMapping';
import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers';
import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects';
import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';
import { AppResourcePath, FileAccess } from 'vs/base/common/network';
import { BugIndicatingError } from 'vs/base/common/errors';
import { IDocumentColorComputerTarget, computeDefaultDocumentColors } from 'vs/editor/common/languages/defaultDocumentColorsComputer';
import { FindSectionHeaderOptions, SectionHeader, findSectionHeaders } from 'vs/editor/common/services/findSectionHeaders';
// ESM-comment-begin
const isESM = false;
// ESM-comment-end
// ESM-uncomment-begin
// const isESM = true;
// ESM-uncomment-end
export interface IMirrorModel extends IMirrorTextModel {
readonly uri: URI;
readonly version: number;
@@ -818,20 +826,21 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
// static foreing module
return Promise.resolve(getAllMethodNames(this._foreignModule));
}
// ESM-comment-begin
return new Promise<any>((resolve, reject) => {
require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => {
const onModuleCallback = (foreignModule: { create: IForeignModuleFactory }) => {
this._foreignModule = foreignModule.create(ctx, createData);
resolve(getAllMethodNames(this._foreignModule));
};
}, reject);
if (!isESM) {
require([`${moduleId}`], onModuleCallback, reject);
} else {
const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true);
import(`${url}`).then(onModuleCallback).catch(reject);
}
});
// ESM-comment-end
// ESM-uncomment-begin
// return Promise.reject(new Error(`Unexpected usage`));
// ESM-uncomment-end
}
// foreign method request
@@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SimpleWorkerServer } from 'vs/base/common/worker/simpleWorker';
import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';
import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost';
type MessageEvent = {
data: any;
};
declare const globalThis: {
postMessage: (message: any) => void;
onmessage: (event: MessageEvent) => void;
};
let initialized = false;
export function initialize(factory: any) {
if (initialized) {
return;
}
initialized = true;
const simpleWorker = new SimpleWorkerServer((msg) => {
globalThis.postMessage(msg);
}, (host: IEditorWorkerHost) => new EditorSimpleWorker(host, null));
globalThis.onmessage = (e: MessageEvent) => {
simpleWorker.onmessage(e.data);
};
}
globalThis.onmessage = (e: MessageEvent) => {
// Ignore first message in this case and initialize if not yet initialized
if (!initialized) {
initialize(null);
}
};
type CreateFunction<C, D, R = any> = (ctx: C, data: D) => R;
export function bootstrapSimpleEditorWorker<C, D, R>(createFn: CreateFunction<C, D, R>) {
globalThis.onmessage = () => {
initialize((ctx: C, createData: D) => {
return createFn.call(self, ctx, createData);
});
};
}
+5 -1
View File
@@ -19,8 +19,12 @@ export namespace AccessibilityHelpNLS {
export const screenReaderModeEnabled = nls.localize("screenReaderModeEnabled", "Screen Reader Optimized Mode enabled.");
export const screenReaderModeDisabled = nls.localize("screenReaderModeDisabled", "Screen Reader Optimized Mode disabled.");
export const tabFocusModeOnMsg = nls.localize("tabFocusModeOnMsg", "Pressing Tab in the current editor will move focus to the next focusable element. Toggle this behavior{0}.", '<keybinding:editor.action.toggleTabFocusMode>');
export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior{0}", '<keybinding:editor.action.toggleTabFocusMode>');
export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior{0}.", '<keybinding:editor.action.toggleTabFocusMode>');
export const stickScroll = nls.localize("stickScrollKb", "Focus Sticky Scroll{0} to focus the currently nested scopes.", '<keybinding:editor.action.focusStickyDebugConsole>');
export const codeFolding = nls.localize("codeFolding", "Use code folding to collapse blocks of code and focus on the code you're interested in via the Toggle Folding Command{0}.", '<keybinding:editor.toggleFold>');
export const intellisense = nls.localize("intellisense", "Use Intellisense to improve coding efficiency and reduce errors. Trigger suggestions{0}.", '<keybinding:editor.action.triggerSuggest>');
export const showOrFocusHover = nls.localize("showOrFocusHover", "Show or focus the hover{0} to read information about the current symbol.", '<keybinding:editor.action.showHover>');
export const goToSymbol = nls.localize("goToSymbol", "Go to Symbol{0} to quickly navigate between symbols in the current file.", '<keybinding:workbench.action.gotoSymbol>');
export const showAccessibilityHelpAction = nls.localize("showAccessibilityHelpAction", "Show Accessibility Help");
export const listSignalSounds = nls.localize("listSignalSoundsCommand", "Run the command: List Signal Sounds for an overview of all sounds and their current status.");
export const listAlerts = nls.localize("listAnnouncementsCommand", "Run the command: List Signal Announcements for an overview of announcements and their current status.");
@@ -253,15 +253,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
const currLineEmptyOrIndented = isLineEmptyOrIndented(lineNumber);
const notEmpty = !nextLineEmptyOrIndented && !prevLineEmptyOrIndented;
let hasDecoration = false;
const currLineDecorations = this._editor.getLineDecorations(lineNumber);
if (currLineDecorations) {
for (const decoration of currLineDecorations) {
if (decoration.options.glyphMarginClassName?.includes(Codicon.debugBreakpoint.id)) {
hasDecoration = true;
}
}
}
const hasDecoration = !!(currLineDecorations?.length);
// check above and below. if both are blocked, display lightbulb in the gutter.
if (!nextLineEmptyOrIndented && !prevLineEmptyOrIndented && !hasDecoration) {
@@ -13,6 +13,7 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua
import { Disposable } from 'vs/base/common/lifecycle';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { registerEditorFeature } from 'vs/editor/common/editorFeatures';
import { FileAccess } from 'vs/base/common/network';
export class DefaultDocumentColorProvider implements DocumentColorProvider {
@@ -22,7 +23,7 @@ export class DefaultDocumentColorProvider implements DocumentColorProvider {
modelService: IModelService,
languageConfigurationService: ILanguageConfigurationService,
) {
this._editorWorkerClient = new EditorWorkerClient(modelService, false, 'editorWorkerService', languageConfigurationService);
this._editorWorkerClient = new EditorWorkerClient(FileAccess.asBrowserUri('vs/base/worker/workerMain.js'), modelService, false, 'editorWorkerService', languageConfigurationService);
}
async provideDocumentColors(model: ITextModel, _token: CancellationToken): Promise<IColorInformation[] | null> {
@@ -92,7 +92,7 @@ export class ContentHoverController extends Disposable implements IEditorContrib
this._hoverSettings = {
enabled: hoverOpts.enabled,
sticky: hoverOpts.sticky,
hidingDelay: hoverOpts.delay
hidingDelay: hoverOpts.hidingDelay
};
if (hoverOpts.enabled) {
@@ -77,7 +77,7 @@ export class MarginHoverController extends Disposable implements IEditorContribu
this._hoverSettings = {
enabled: hoverOpts.enabled,
sticky: hoverOpts.sticky,
hidingDelay: hoverOpts.delay
hidingDelay: hoverOpts.hidingDelay
};
if (hoverOpts.enabled) {
@@ -509,27 +509,42 @@ export class SuggestController implements IEditorContribution {
// clear only now - after all tasks are done
Promise.all(tasks).finally(() => {
this._reportSuggestionAcceptedTelemetry(item, model, isResolved, _commandExectionDuration, _additionalEditsAppliedAsync, event.index);
this._reportSuggestionAcceptedTelemetry(item, model, isResolved, _commandExectionDuration, _additionalEditsAppliedAsync, event.index, event.model.items);
this.model.clear();
cts.dispose();
});
}
private _reportSuggestionAcceptedTelemetry(item: CompletionItem, model: ITextModel, itemResolved: boolean, commandExectionDuration: number, additionalEditsAppliedAsync: number, index: number): void {
private _reportSuggestionAcceptedTelemetry(item: CompletionItem, model: ITextModel, itemResolved: boolean, commandExectionDuration: number, additionalEditsAppliedAsync: number, index: number, completionItems: CompletionItem[]): void {
if (Math.floor(Math.random() * 100) === 0) {
// throttle telemetry event because accepting completions happens a lot
return;
}
const labelMap = new Map<string, number[]>();
for (let i = 0; i < Math.min(30, completionItems.length); i++) {
const label = completionItems[i].textLabel;
if (labelMap.has(label)) {
labelMap.get(label)!.push(i);
} else {
labelMap.set(label, [i]);
}
}
const firstIndexArray = labelMap.get(item.textLabel);
const hasDuplicates = firstIndexArray && firstIndexArray.length > 1;
const firstIndex = hasDuplicates ? firstIndexArray[0] : -1;
type AcceptedSuggestion = {
extensionId: string; providerId: string;
fileExtension: string; languageId: string; basenameHash: string; kind: number;
resolveInfo: number; resolveDuration: number;
commandDuration: number;
additionalEditsAsync: number;
index: number;
label: string;
index: number; firstIndex: number;
};
type AcceptedSuggestionClassification = {
owner: 'jrieken';
@@ -544,8 +559,8 @@ export class SuggestController implements IEditorContribution {
resolveDuration: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'How long resolving took to finish' };
commandDuration: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'How long a completion item command took' };
additionalEditsAsync: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Info about asynchronously applying additional edits' };
index: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The order of the completion item in the list.' };
label: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The label of the completion item.' };
index: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The index of the completion item in the sorted list.' };
firstIndex: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'When there are multiple completions, the index of the first instance.' };
};
this._telemetryService.publicLog2<AcceptedSuggestion, AcceptedSuggestionClassification>('suggest.acceptedSuggestion', {
@@ -560,7 +575,7 @@ export class SuggestController implements IEditorContribution {
commandDuration: commandExectionDuration,
additionalEditsAsync: additionalEditsAppliedAsync,
index,
label: item.textLabel
firstIndex,
});
}
@@ -1010,13 +1025,13 @@ registerEditorCommand(new SuggestCommand({
group: 'right',
order: 1,
when: ContextKeyExpr.and(SuggestContext.DetailsVisible, SuggestContext.CanResolve),
title: nls.localize('detail.more', "show less")
title: nls.localize('detail.more', "Show Less")
}, {
menuId: suggestWidgetStatusbarMenu,
group: 'right',
order: 1,
when: ContextKeyExpr.and(SuggestContext.DetailsVisible.toNegated(), SuggestContext.CanResolve),
title: nls.localize('detail.less', "show more")
title: nls.localize('detail.less', "Show More")
}]
}));
@@ -66,7 +66,7 @@ suite('suggest, word distance', function () {
private _worker = new EditorSimpleWorker(new class extends mock<IEditorWorkerHost>() { }, null);
constructor() {
super(modelService, new class extends mock<ITextResourceConfigurationService>() { }, new NullLogService(), new TestLanguageConfigurationService(), new LanguageFeaturesService());
super(undefined, modelService, new class extends mock<ITextResourceConfigurationService>() { }, new NullLogService(), new TestLanguageConfigurationService(), new LanguageFeaturesService());
this._worker.acceptNewModel({
url: model.uri.toString(),
lines: model.getLinesContent(),
+1 -27
View File
@@ -3,30 +3,4 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SimpleWorkerServer } from 'vs/base/common/worker/simpleWorker';
import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';
import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost';
let initialized = false;
export function initialize(foreignModule: any) {
if (initialized) {
return;
}
initialized = true;
const simpleWorker = new SimpleWorkerServer((msg) => {
globalThis.postMessage(msg);
}, (host: IEditorWorkerHost) => new EditorSimpleWorker(host, foreignModule));
globalThis.onmessage = (e: MessageEvent) => {
simpleWorker.onmessage(e.data);
};
}
globalThis.onmessage = (e: MessageEvent) => {
// Ignore first message in this case and initialize if not yet initialized
if (!initialized) {
initialize(null);
}
};
export * from 'vs/editor/common/services/editorWorkerBootstrap';
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/editor/common/languages/languageConfigurationRegistry';
import 'vs/editor/standalone/browser/standaloneCodeEditorService';
import 'vs/editor/standalone/browser/standaloneLayoutService';
import 'vs/platform/undoRedo/common/undoRedoService';
@@ -89,6 +88,8 @@ import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/com
import { DefaultConfiguration } from 'vs/platform/configuration/common/configurations';
import { WorkspaceEdit } from 'vs/editor/common/languages';
import { AccessibilitySignal, AccessibilityModality, IAccessibilitySignalService, Sound } from 'vs/platform/accessibilitySignal/browser/accessibilitySignalService';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
import { LogService } from 'vs/platform/log/common/logService';
import { getEditorFeatures } from 'vs/editor/common/editorFeatures';
import { onUnexpectedError } from 'vs/base/common/errors';
@@ -1072,6 +1073,18 @@ class StandaloneContextMenuService extends ContextMenuService {
}
}
class StandaloneEditorWorkerService extends EditorWorkerService {
constructor(
@IModelService modelService: IModelService,
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,
@ILogService logService: ILogService,
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
) {
super(undefined, modelService, configurationService, logService, languageConfigurationService, languageFeaturesService);
}
}
class StandaloneAccessbilitySignalService implements IAccessibilitySignalService {
_serviceBrand: undefined;
async playSignal(cue: AccessibilitySignal, options: {}): Promise<void> {
@@ -1130,7 +1143,7 @@ registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Eager
registerSingleton(IProgressService, StandaloneProgressService, InstantiationType.Eager);
registerSingleton(IEditorProgressService, StandaloneEditorProgressService, InstantiationType.Eager);
registerSingleton(IStorageService, InMemoryStorageService, InstantiationType.Eager);
registerSingleton(IEditorWorkerService, EditorWorkerService, InstantiationType.Eager);
registerSingleton(IEditorWorkerService, StandaloneEditorWorkerService, InstantiationType.Eager);
registerSingleton(IBulkEditService, StandaloneBulkEditService, InstantiationType.Eager);
registerSingleton(IWorkspaceTrustManagementService, StandaloneWorkspaceTrustManagementService, InstantiationType.Eager);
registerSingleton(ITextModelService, StandaloneTextModelService, InstantiationType.Eager);
+18 -6
View File
@@ -166,6 +166,7 @@ type MenuItemGroup = [string, Array<IMenuItem | ISubmenuItem>];
class MenuInfoSnapshot {
protected _menuGroups: MenuItemGroup[] = [];
private _allMenuIds: Set<MenuId> = new Set();
private _structureContextKeys: Set<string> = new Set();
private _preconditionContextKeys: Set<string> = new Set();
private _toggledContextKeys: Set<string> = new Set();
@@ -175,6 +176,11 @@ class MenuInfoSnapshot {
protected readonly _collectContextKeysForSubmenus: boolean,
) {
this.refresh();
this._allMenuIds.add(_id);
}
get allMenuIds(): ReadonlySet<MenuId> {
return this._allMenuIds;
}
get structureContextKeys(): ReadonlySet<string> {
@@ -193,6 +199,7 @@ class MenuInfoSnapshot {
// reset
this._menuGroups.length = 0;
this._allMenuIds.clear();
this._structureContextKeys.clear();
this._preconditionContextKeys.clear();
this._toggledContextKeys.clear();
@@ -209,8 +216,8 @@ class MenuInfoSnapshot {
}
group[1].push(item);
// keep keys for eventing
this._collectContextKeys(item);
// keep keys and submenu ids for eventing
this._collectContextKeysAndSubmenuIds(item);
}
}
@@ -219,7 +226,7 @@ class MenuInfoSnapshot {
return menuItems;
}
private _collectContextKeys(item: IMenuItem | ISubmenuItem): void {
private _collectContextKeysAndSubmenuIds(item: IMenuItem | ISubmenuItem): void {
MenuInfoSnapshot._fillInKbExprKeys(item.when, this._structureContextKeys);
@@ -237,7 +244,9 @@ class MenuInfoSnapshot {
} else if (this._collectContextKeysForSubmenus) {
// recursively collect context keys from submenus so that this
// menu fires events when context key changes affect submenus
MenuRegistry.getMenuItems(item.submenu).forEach(this._collectContextKeys, this);
MenuRegistry.getMenuItems(item.submenu).forEach(this._collectContextKeysAndSubmenuIds, this);
this._allMenuIds.add(item.submenu);
}
}
@@ -383,8 +392,11 @@ class MenuImpl implements IMenu {
}, options.eventDebounceDelay);
this._disposables.add(rebuildMenuSoon);
this._disposables.add(MenuRegistry.onDidChangeMenu(e => {
if (e.has(id)) {
rebuildMenuSoon.schedule();
for (const id of this._menuInfo.allMenuIds) {
if (e.has(id)) {
rebuildMenuSoon.schedule();
break;
}
}
}));
@@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------------------------
* 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 { relative } from 'path';
import { isESM } from 'vs/base/common/amd';
import { FileAccess } from 'vs/base/common/network';
import { StopWatch } from 'vs/base/common/stopwatch';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
export const ICSSDevelopmentService = createDecorator<ICSSDevelopmentService>('ICSSDevelopmentService');
export interface ICSSDevelopmentService {
_serviceBrand: undefined;
isEnabled: boolean;
getCssModules(): Promise<string[]>;
}
export class CSSDevelopmentService implements ICSSDevelopmentService {
declare _serviceBrand: undefined;
private _cssModules?: Promise<string[]>;
constructor(
@IEnvironmentService private readonly envService: IEnvironmentService,
@ILogService private readonly logService: ILogService
) { }
get isEnabled(): boolean {
return !this.envService.isBuilt && isESM;
}
getCssModules(): Promise<string[]> {
this._cssModules ??= this.computeCssModules();
return this._cssModules;
}
private async computeCssModules(): Promise<string[]> {
if (!this.isEnabled) {
return [];
}
const rg = await import('@vscode/ripgrep');
return await new Promise<string[]>((resolve) => {
const sw = StopWatch.create();
const chunks: string[][] = [];
const decoder = new TextDecoder();
const basePath = FileAccess.asFileUri('').fsPath;
const process = spawn(rg.rgPath, ['-g', '**/*.css', '--files', '--no-ignore', basePath], {});
process.stdout.on('data', data => {
const chunk = decoder.decode(data, { stream: true });
chunks.push(chunk.split('\n').filter(Boolean));
});
process.on('error', err => {
this.logService.error('[CSS_DEV] FAILED to compute CSS data', err);
resolve([]);
});
process.on('close', () => {
const result = chunks.flat().map(path => relative(basePath, path).replace(/\\/g, '/')).filter(Boolean).sort();
resolve(result);
this.logService.info(`[CSS_DEV] DONE, ${result.length} css modules (${Math.round(sw.elapsed())}ms)`);
});
});
}
}
@@ -1,73 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { importAMDNodeModule } from 'vs/amdX';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { isESM } from 'vs/base/common/amd';
(isESM ? suite : suite.skip)('Modules Loading in ESM via importAMDNodeModule()', () => {
test('@vscode/iconv-lite-umd', async () => {
const module = await importAMDNodeModule<typeof import('@vscode/iconv-lite-umd')>('@vscode/iconv-lite-umd', 'lib/iconv-lite-umd.js');
assert.ok(typeof module.getDecoder === 'function');
});
test.skip('@vscode/tree-sitter-wasm', async () => {
//TODO@esm this cannot be resolved in ESM because the module is not self-contained
const module = await importAMDNodeModule<typeof import('@vscode/tree-sitter-wasm')>('@vscode/tree-sitter-wasm', 'wasm/tree-sitter.js');
assert.ok(typeof module.Parser === 'function');
});
test('jschardet', async () => {
const jschardet = await importAMDNodeModule<typeof import('jschardet')>('jschardet', isESM ? 'dist/jschardet.js' : 'dist/jschardet.min.js');
assert.ok(typeof jschardet.detect === 'function');
});
test('tas-client-umd', async () => {
const tas = await importAMDNodeModule<typeof import('tas-client-umd')>('tas-client-umd', 'lib/tas-client-umd.js');
assert.ok(typeof tas.ExperimentationService === 'function');
});
test('vscode-oniguruma', async () => {
const oniguruma = await importAMDNodeModule<typeof import('vscode-oniguruma')>('vscode-oniguruma', 'release/main.js');
assert.ok(typeof oniguruma.loadWASM === 'function');
});
test('vscode-textmate', async () => {
const textmate = await importAMDNodeModule<typeof import('vscode-textmate')>('vscode-textmate', 'release/main.js');
assert.ok(typeof textmate.parseRawGrammar === 'function');
});
test('@xterm', async () => {
const xterm = await importAMDNodeModule<typeof import('@xterm/xterm')>('@xterm/xterm', 'lib/xterm.js');
assert.ok(typeof xterm.Terminal === 'function');
const addon1 = await importAMDNodeModule<typeof import('@xterm/addon-clipboard')>('@xterm/addon-clipboard', 'lib/addon-clipboard.js');
assert.ok(typeof addon1.ClipboardAddon === 'function');
const addon2 = await importAMDNodeModule<typeof import('@xterm/addon-image')>('@xterm/addon-image', 'lib/addon-image.js');
assert.ok(typeof addon2.ImageAddon === 'function');
const addon3 = await importAMDNodeModule<typeof import('@xterm/addon-search')>('@xterm/addon-search', 'lib/addon-search.js');
assert.ok(typeof addon3.SearchAddon === 'function');
const addon4 = await importAMDNodeModule<typeof import('@xterm/addon-unicode11')>('@xterm/addon-unicode11', 'lib/addon-unicode11.js');
assert.ok(typeof addon4.Unicode11Addon === 'function');
const addon5 = await importAMDNodeModule<typeof import('@xterm/addon-webgl')>('@xterm/addon-webgl', 'lib/addon-webgl.js');
assert.ok(typeof addon5.WebglAddon === 'function');
const addon6 = await importAMDNodeModule<typeof import('@xterm/addon-serialize')>('@xterm/addon-serialize', 'lib/addon-serialize.js');
assert.ok(typeof addon6.SerializeAddon === 'function');
});
test.skip('@vscode/vscode-languagedetection', async () => { // TODO this test prints to console which is disallowed
const languagedetection = await importAMDNodeModule<typeof import('@vscode/vscode-languagedetection')>('@vscode/vscode-languagedetection', 'dist/lib/index.js');
assert.ok(typeof languagedetection.ModelOperations === 'function');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -1,26 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { isWeb } from 'vs/base/common/platform';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { isESM } from 'vs/base/common/amd';
(isESM ? suite : suite.skip)('Modules Loading in ESM via direct import()', () => {
(isWeb ? test.skip : test)('@microsoft/1ds-post-js', async () => { // TODO@esm fails in web?
// eslint-disable-next-line local/code-amd-node-module
const { default: module } = await import('@microsoft/1ds-post-js');
assert.ok(typeof module.PostChannel === 'function');
});
(isWeb ? test.skip : test)('@microsoft/1ds-core-js', async () => { // TODO@esm fails in web?
// eslint-disable-next-line local/code-amd-node-module
const { default: module } = await import('@microsoft/1ds-core-js');
assert.ok(typeof module.AppInsightsCore === 'function');
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import assert from 'assert';
import { isWindows } from 'vs/base/common/platform';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
import { flakySuite } from 'vs/base/test/common/testUtils';
function testErrorMessage(module: string): string {
@@ -13,7 +13,7 @@ function testErrorMessage(module: string): string {
flakySuite('Native Modules (all platforms)', () => {
test.skip('kerberos', async () => { // TODO fails on macOS ARM?
(isMacintosh ? test.skip : test)('kerberos', async () => { // Somehow fails on macOS ARM?
const { default: kerberos } = await import('kerberos');
assert.ok(typeof kerberos.initializeClient === 'function', testErrorMessage('kerberos'));
});
@@ -150,21 +150,6 @@ flakySuite('Native Modules (all platforms)', () => {
});
assert.ok(windowsCerts.length > 0, testErrorMessage('@vscode/proxy-agent'));
});
// These tests require certain modules from `vscode-distro` to work and are otherwise skipped.
// test('vsda', async function () {
// const vsda = await import('vsda');
// const signer = new vsda.signer();
// const signed = await signer.sign('value');
// assert.ok(typeof signed === 'string', testErrorMessage('vsda'));
// assert.ok(typeof (vsda as any).validator === 'function', testErrorMessage('vsda'));
// });
// test('@vscode/vsce-sign', async function () {
// const vsceSign = await import('@vscode/vsce-sign');
// assert.ok(typeof vsceSign.verify === 'function', testErrorMessage('@vscode/vsce-sign'));
// });
});
(!isWindows ? suite.skip : suite)('Native Modules (Windows)', () => {
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { importAMDNodeModule } from 'vs/amdX';
import { getErrorMessage } from 'vs/base/common/errors';
import { IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
@@ -103,12 +104,12 @@ export class ExtensionSignatureVerificationService implements IExtensionSignatur
private async resolveVsceSign(): Promise<typeof vsceSign> {
// ESM-uncomment-begin
// if (typeof importAMDNodeModule === 'function') { /* fixes unused import, remove me */}
// const mod = '@vscode/vsce-sign';
// return import(mod);
// ESM-uncomment-end
// ESM-comment-begin
const { importAMDNodeModule } = await import('vs/amdX');
return importAMDNodeModule('@vscode/vsce-sign', 'src/main.js');
// ESM-comment-end
}
@@ -278,6 +278,9 @@ const _allApiProposals = {
notebookMime: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMime.d.ts',
},
notebookReplDocument: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookReplDocument.d.ts',
},
notebookVariableProvider: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookVariableProvider.d.ts',
},
@@ -22,6 +22,8 @@ import { IIPCObjectUrl, IProtocolMainService } from 'vs/platform/protocol/electr
import { zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
import { ICodeWindow, IWindowState } from 'vs/platform/window/electron-main/window';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { isESM } from 'vs/base/common/amd';
import { ICSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
interface IBrowserWindowOptions {
backgroundColor: string | undefined;
@@ -49,6 +51,7 @@ export class IssueMainService implements IIssueMainService {
@INativeHostMainService private readonly nativeHostMainService: INativeHostMainService,
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
@ICSSDevelopmentService private readonly cssDevelopmentService: ICSSDevelopmentService,
) { }
//#region Used by renderer
@@ -85,11 +88,12 @@ export class IssueMainService implements IIssueMainService {
nls: {
messages: globalThis._VSCODE_NLS_MESSAGES,
language: globalThis._VSCODE_NLS_LANGUAGE
}
},
cssModules: this.cssDevelopmentService.isEnabled ? await this.cssDevelopmentService.getCssModules() : undefined
});
this.issueReporterWindow.loadURL(
FileAccess.asBrowserUri(`vs/workbench/contrib/issue/electron-sandbox/issueReporter${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true)
FileAccess.asBrowserUri(`vs/workbench/contrib/issue/electron-sandbox/issueReporter${this.environmentMainService.isBuilt ? '' : '-dev'}.${isESM ? 'esm.' : ''}html`).toString(true)
);
this.issueReporterWindow.on('close', () => {
@@ -15,6 +15,7 @@ import { IDiagnosticsService, isRemoteDiagnosticError, PerformanceInfo, SystemIn
import { IDiagnosticsMainService } from 'vs/platform/diagnostics/electron-main/diagnosticsMainService';
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
import { ICSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
import { IProcessMainService, ProcessExplorerData, ProcessExplorerWindowConfiguration } from 'vs/platform/issue/common/issue';
import { ILogService } from 'vs/platform/log/common/log';
import { INativeHostMainService } from 'vs/platform/native/electron-main/nativeHostMainService';
@@ -25,6 +26,7 @@ import { IStateService } from 'vs/platform/state/node/state';
import { UtilityProcess } from 'vs/platform/utilityProcess/electron-main/utilityProcess';
import { zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
import { IWindowState } from 'vs/platform/window/electron-main/window';
import { isESM } from 'vs/base/common/amd';
const processExplorerWindowState = 'issue.processExplorerWindowState';
@@ -57,6 +59,7 @@ export class ProcessMainService implements IProcessMainService {
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
@IProductService private readonly productService: IProductService,
@IStateService private readonly stateService: IStateService,
@ICSSDevelopmentService private readonly cssDevelopmentService: ICSSDevelopmentService
) {
this.registerListeners();
}
@@ -157,11 +160,12 @@ export class ProcessMainService implements IProcessMainService {
nls: {
messages: globalThis._VSCODE_NLS_MESSAGES,
language: globalThis._VSCODE_NLS_LANGUAGE
}
},
cssModules: this.cssDevelopmentService.isEnabled ? await this.cssDevelopmentService.getCssModules() : undefined
});
this.processExplorerWindow.loadURL(
FileAccess.asBrowserUri(`vs/code/electron-sandbox/processExplorer/processExplorer${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true)
FileAccess.asBrowserUri(`vs/code/electron-sandbox/processExplorer/processExplorer${this.environmentMainService.isBuilt ? '' : '-dev'}.${isESM ? 'esm.' : ''}html`).toString(true)
);
this.processExplorerWindow.on('close', () => {
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { create } from './profileAnalysisWorker';
import { bootstrapSimpleWorker } from 'vs/base/common/worker/simpleWorkerBootstrap';
bootstrapSimpleWorker(create);
@@ -5,6 +5,7 @@
import { DefaultWorkerFactory } from 'vs/base/browser/defaultWorkerFactory';
import { FileAccess } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { SimpleWorkerClient } from 'vs/base/common/worker/simpleWorker';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -41,7 +42,7 @@ class ProfileAnalysisWorkerService implements IProfileAnalysisWorkerService {
declare _serviceBrand: undefined;
private readonly _workerFactory = new DefaultWorkerFactory('CpuProfileAnalysis');
private readonly _workerFactory = new DefaultWorkerFactory(FileAccess.asBrowserUri('vs/base/worker/workerMain.js'), 'CpuProfileAnalysis');
constructor(
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@@ -96,7 +96,8 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ
let headers: Record<string, string> | undefined;
if (this.environmentService.crossOriginIsolated) {
if (basename(path) === 'workbench.html' || basename(path) === 'workbench-dev.html') {
const pathBasename = basename(path);
if (pathBasename === 'workbench.html' || pathBasename === 'workbench-dev.html' || pathBasename === 'workbench.esm.html' || pathBasename === 'workbench-dev.esm.html') {
headers = COI.CoopAndCoep;
} else {
headers = COI.getHeadersFromQuery(request.url);
+2 -1
View File
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { importAMDNodeModule } from 'vs/amdX';
import { AbstractSignService, IVsdaValidator } from 'vs/platform/sign/common/abstractSignService';
import { ISignService } from 'vs/platform/sign/common/sign';
@@ -30,13 +31,13 @@ export class SignService extends AbstractSignService implements ISignService {
private async vsda(): Promise<typeof vsda> {
// ESM-uncomment-begin
// if (typeof importAMDNodeModule === 'function') { /* fixes unused import, remove me */}
// const mod = 'vsda';
// const { default: vsda } = await import(mod);
// return vsda;
// ESM-uncomment-end
// ESM-comment-begin
const { importAMDNodeModule } = await import('vs/amdX');
return importAMDNodeModule('vsda', 'index.js');
// ESM-comment-end
}
@@ -5,6 +5,7 @@
import type { IExtendedConfiguration, IExtendedTelemetryItem, ITelemetryItem, ITelemetryUnloadState } from '@microsoft/1ds-core-js';
import type { IChannelConfiguration, IXHROverride, PostChannel } from '@microsoft/1ds-post-js';
import { importAMDNodeModule } from 'vs/amdX';
import { onUnexpectedError } from 'vs/base/common/errors';
import { mixin } from 'vs/base/common/objects';
import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils';
@@ -22,11 +23,11 @@ const endpointHealthUrl = 'https://mobile.events.data.microsoft.com/ping';
async function getClient(instrumentationKey: string, addInternalFlag?: boolean, xhrOverride?: IXHROverride): Promise<IAppInsightsCore> {
// ESM-comment-begin
const { importAMDNodeModule } = await import('vs/amdX');
const oneDs = await importAMDNodeModule<typeof import('@microsoft/1ds-core-js')>('@microsoft/1ds-core-js', 'dist/ms.core.js');
const postPlugin = await importAMDNodeModule<typeof import('@microsoft/1ds-post-js')>('@microsoft/1ds-post-js', 'dist/ms.post.js');
// ESM-comment-end
// ESM-uncomment-begin
// if (typeof importAMDNodeModule === 'function') { /* fixes unused import, remove me */}
// // eslint-disable-next-line local/code-amd-node-module
// const oneDs = await import('@microsoft/1ds-core-js');
// // eslint-disable-next-line local/code-amd-node-module
@@ -44,6 +44,7 @@ import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electr
import { ILoggerMainService } from 'vs/platform/log/electron-main/loggerService';
import { firstOrDefault } from 'vs/base/common/arrays';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { isESM } from 'vs/base/common/amd';
export interface IWindowCreationOptions {
readonly state: IWindowState;
@@ -1036,7 +1037,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
this.readyState = ReadyState.NAVIGATING;
// Load URL
this._win.loadURL(FileAccess.asBrowserUri(`vs/code/electron-sandbox/workbench/workbench${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true));
this._win.loadURL(FileAccess.asBrowserUri(`vs/code/electron-sandbox/workbench/workbench${this.environmentMainService.isBuilt ? '' : '-dev'}.${isESM ? 'esm.' : ''}html`).toString(true));
// Remember that we did load
const wasLoaded = this.wasLoaded;
@@ -56,6 +56,7 @@ import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electr
import { ILoggerMainService } from 'vs/platform/log/electron-main/loggerService';
import { IAuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
import { IAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow';
import { ICSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
//#region Helper Interfaces
@@ -229,7 +230,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
@IFileService private readonly fileService: IFileService,
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
@IThemeMainService private readonly themeMainService: IThemeMainService,
@IAuxiliaryWindowsMainService private readonly auxiliaryWindowsMainService: IAuxiliaryWindowsMainService
@IAuxiliaryWindowsMainService private readonly auxiliaryWindowsMainService: IAuxiliaryWindowsMainService,
@ICSSDevelopmentService private readonly cssDevelopmentService: ICSSDevelopmentService
) {
super();
@@ -1471,7 +1473,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
accessibilitySupport: app.accessibilitySupportEnabled,
colorScheme: this.themeMainService.getColorScheme(),
policiesData: this.policyService.serialize(),
continueOn: this.environmentMainService.continueOn
continueOn: this.environmentMainService.continueOn,
cssModules: this.cssDevelopmentService.isEnabled ? await this.cssDevelopmentService.getCssModules() : undefined
};
// New window
@@ -9,7 +9,7 @@ import * as http from 'http';
import * as net from 'net';
import { performance } from 'perf_hooks';
import * as url from 'url';
import { LoaderStats } from 'vs/base/common/amd';
import { LoaderStats, isESM } from 'vs/base/common/amd';
import { VSBuffer } from 'vs/base/common/buffer';
import { CharCode } from 'vs/base/common/charCode';
import { isSigPipeError, onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
@@ -781,7 +781,7 @@ export async function createServer(address: string | net.AddressInfo | null, arg
serverBasePath = `/${serverBasePath}`;
}
const hasWebClient = fs.existsSync(FileAccess.asFileUri('vs/code/browser/workbench/workbench.html').fsPath);
const hasWebClient = fs.existsSync(FileAccess.asFileUri(`vs/code/browser/workbench/workbench.${isESM ? 'esm.' : ''}html`).fsPath);
if (hasWebClient && address && typeof address !== 'string') {
// ships the web ui!
+4
View File
@@ -77,6 +77,7 @@ import { RemoteExtensionsScannerChannel, RemoteExtensionsScannerService } from '
import { RemoteExtensionsScannerChannelName } from 'vs/platform/remote/common/remoteExtensionsScanner';
import { RemoteUserDataProfilesServiceChannel } from 'vs/platform/userDataProfile/common/userDataProfileIpc';
import { NodePtyHostStarter } from 'vs/platform/terminal/node/nodePtyHostStarter';
import { CSSDevelopmentService, ICSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
const eventPrefix = 'monacoworkbench';
@@ -131,6 +132,9 @@ export async function setupServerServices(connectionToken: ServerConnectionToken
services.set(IUserDataProfilesService, userDataProfilesService);
socketServer.registerChannel('userDataProfiles', new RemoteUserDataProfilesServiceChannel(userDataProfilesService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)));
// Dev Only: CSS service (for ESM)
services.set(ICSSDevelopmentService, new SyncDescriptor(CSSDevelopmentService, undefined, true));
// Initialize
const [, , machineId, sqmId, devDeviceId] = await Promise.all([
configurationService.initialize(),
+18 -3
View File
@@ -28,6 +28,8 @@ import { IProductConfiguration } from 'vs/base/common/product';
import { isString } from 'vs/base/common/types';
import { CharCode } from 'vs/base/common/charCode';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { isESM } from 'vs/base/common/amd';
import { ICSSDevelopmentService } from 'vs/platform/cssDev/node/cssDevService';
const textMimeType: { [ext: string]: string | undefined } = {
'.html': 'text/html',
@@ -108,6 +110,7 @@ export class WebClientServer {
@ILogService private readonly _logService: ILogService,
@IRequestService private readonly _requestService: IRequestService,
@IProductService private readonly _productService: IProductService,
@ICSSDevelopmentService private readonly _cssDevService: ICSSDevelopmentService
) {
this._webExtensionResourceUrlTemplate = this._productService.extensionsGallery?.resourceUrlTemplate ? URI.parse(this._productService.extensionsGallery.resourceUrlTemplate) : undefined;
@@ -297,7 +300,7 @@ export class WebClientServer {
const resolveWorkspaceURI = (defaultLocation?: string) => defaultLocation && URI.file(path.resolve(defaultLocation)).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority });
const filePath = FileAccess.asFileUri(this._environmentService.isBuilt ? 'vs/code/browser/workbench/workbench.html' : 'vs/code/browser/workbench/workbench-dev.html').fsPath;
const filePath = FileAccess.asFileUri(`vs/code/browser/workbench/workbench${this._environmentService.isBuilt ? '' : '-dev'}.${isESM ? 'esm.' : ''}html`).fsPath;
const authSessionInfo = !this._environmentService.isBuilt && this._environmentService.args['github-auth'] ? {
id: generateUuid(),
providerId: 'github',
@@ -356,6 +359,16 @@ export class WebClientServer {
WORKBENCH_NLS_FALLBACK_URL: `${this._staticRoute}/out/nls.messages.js`
};
// DEV ---------------------------------------------------------------------------------------
// DEV: This is for development and enables loading CSS via import-statements via import-maps.
// DEV: The server needs to send along all CSS modules so that the client can construct the
// DEV: import-map.
// DEV ---------------------------------------------------------------------------------------
if (this._cssDevService.isEnabled) {
const cssModules = await this._cssDevService.getCssModules();
values['WORKBENCH_DEV_CSS_MODULES'] = JSON.stringify(cssModules);
}
if (useTestResolver) {
const bundledExtensions: { extensionPath: string; packageJSON: IExtensionManifest }[] = [];
for (const extensionPath of ['vscode-test-resolver', 'github-authentication']) {
@@ -374,13 +387,15 @@ export class WebClientServer {
return void res.end('Not found');
}
const webWorkerExtensionHostIframeScriptSHA = 'sha256-V28GQnL3aYxbwgpV3yW1oJ+VKKe/PBSzWntNyH8zVXA=';
const webWorkerExtensionHostIframeScriptSHA = isESM ? 'sha256-2Q+j4hfT09+1+imS46J2YlkCtHWQt0/BE79PXjJ0ZJ8=' : 'sha256-V28GQnL3aYxbwgpV3yW1oJ+VKKe/PBSzWntNyH8zVXA=';
const cspDirectives = [
'default-src \'self\';',
'img-src \'self\' https: data: blob:;',
'media-src \'self\';',
`script-src 'self' 'unsafe-eval' ${WORKBENCH_NLS_BASE_URL ?? ''} ${this._getScriptCspHashes(data).join(' ')} '${webWorkerExtensionHostIframeScriptSHA}' ${useTestResolver ? '' : `http://${remoteAuthority}`};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
isESM ?
`script-src 'self' 'unsafe-eval' ${WORKBENCH_NLS_BASE_URL ?? ''} blob: 'nonce-1nline-m4p' ${this._getScriptCspHashes(data).join(' ')} '${webWorkerExtensionHostIframeScriptSHA}' 'sha256-/r7rqQ+yrxt57sxLuQ6AMYcy/lUpvAIzHjIJt/OeLWU=' ${useTestResolver ? '' : `http://${remoteAuthority}`};` : // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.esm.html
`script-src 'self' 'unsafe-eval' ${WORKBENCH_NLS_BASE_URL ?? ''} ${this._getScriptCspHashes(data).join(' ')} '${webWorkerExtensionHostIframeScriptSHA}' ${useTestResolver ? '' : `http://${remoteAuthority}`};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data: blob:;',
@@ -125,30 +125,45 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS
}
}
async $tryCreateNotebook(options: { viewType: string; content?: NotebookDataDto }): Promise<UriComponents> {
const ref = await this._notebookEditorModelResolverService.resolve({ untitledResource: undefined }, options.viewType);
// untitled notebooks are disposed when they get saved. we should not hold a reference
// to such a disposed notebook and therefore dispose the reference as well
ref.object.notebook.onWillDispose(() => {
ref.dispose();
});
// untitled notebooks are dirty by default
this._proxy.$acceptDirtyStateChanged(ref.object.resource, true);
// apply content changes... slightly HACKY -> this triggers a change event
if (options.content) {
const data = NotebookDto.fromNotebookDataDto(options.content);
ref.object.notebook.reset(data.cells, data.metadata, ref.object.notebook.transientOptions);
const ref = await this._notebookEditorModelResolverService.resolve({ untitledResource: undefined }, options.viewType);
// untitled notebooks are disposed when they get saved. we should not hold a reference
// to such a disposed notebook and therefore dispose the reference as well
ref.object.notebook.onWillDispose(() => {
ref.dispose();
});
// untitled notebooks with content are dirty by default
this._proxy.$acceptDirtyStateChanged(ref.object.resource, true);
// apply content changes... slightly HACKY -> this triggers a change event
if (options.content) {
const data = NotebookDto.fromNotebookDataDto(options.content);
ref.object.notebook.reset(data.cells, data.metadata, ref.object.notebook.transientOptions);
}
return ref.object.notebook.uri;
} else {
// If we aren't adding content, we don't need to resolve the full editor model yet.
// This will allow us to adjust settings when the editor is opened, e.g. scratchpad
const notebook = await this._notebookEditorModelResolverService.createUntitledNotebookTextModel(options.viewType);
return notebook.uri;
}
return ref.object.resource;
}
async $tryOpenNotebook(uriComponents: UriComponents): Promise<URI> {
const uri = URI.revive(uriComponents);
const ref = await this._notebookEditorModelResolverService.resolve(uri, undefined);
if (uriComponents.scheme === 'untitled') {
// untitled notebooks are disposed when they get saved. we should not hold a reference
// to such a disposed notebook and therefore dispose the reference as well
ref.object.notebook.onWillDispose(() => {
ref.dispose();
});
}
this._modelReferenceCollection.add(uri, ref);
return uri;
}
@@ -107,7 +107,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/c
import { UIKind } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { ExcludeSettingOptions, oldToNewTextSearchResult, TextSearchCompleteMessageType, TextSearchCompleteMessageTypeNew, TextSearchContextNew, TextSearchMatchNew } from 'vs/workbench/services/search/common/searchExtTypes';
import { ExcludeSettingOptions, TextSearchCompleteMessageType, TextSearchCompleteMessageTypeNew, TextSearchContextNew, TextSearchMatchNew, oldToNewTextSearchResult } from 'vs/workbench/services/search/common/searchExtTypes';
import type * as vscode from 'vscode';
export interface IExtensionRegistries {
@@ -1818,6 +1818,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
ChatResponseCommandButtonPart: extHostTypes.ChatResponseCommandButtonPart,
ChatResponseDetectedParticipantPart: extHostTypes.ChatResponseDetectedParticipantPart,
ChatResponseConfirmationPart: extHostTypes.ChatResponseConfirmationPart,
ChatResponseMovePart: extHostTypes.ChatResponseMovePart,
ChatResponseReferencePartStatusKind: extHostTypes.ChatResponseReferencePartStatusKind,
ChatRequestTurn: extHostTypes.ChatRequestTurn,
ChatResponseTurn: extHostTypes.ChatResponseTurn,
@@ -23,7 +23,7 @@ import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extH
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { ChatAgentLocation, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents';
import { ChatAgentLocation, IChatAgentRequest, IChatAgentResult, IChatAgentResultTimings } from 'vs/workbench/contrib/chat/common/chatAgents';
import { ChatAgentVoteDirection, IChatContentReference, IChatFollowup, IChatResponseErrorDetails, IChatUserActionEvent } from 'vs/workbench/contrib/chat/common/chatService';
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier';
@@ -48,7 +48,7 @@ class ChatAgentResponseStream {
this._isClosed = true;
}
get timings() {
get timings(): IChatAgentResultTimings {
return {
firstProgress: this._firstProgress,
totalElapsed: this._stopWatch.elapsed()
@@ -72,7 +72,7 @@ class ChatAgentResponseStream {
const _report = (progress: IChatProgressDto, task?: (progress: vscode.Progress<vscode.ChatResponseWarningPart | vscode.ChatResponseReferencePart>) => Thenable<string | void>) => {
// Measure the time to the first progress update with real markdown content
if (typeof this._firstProgress === 'undefined' && 'content' in progress) {
if (typeof this._firstProgress === 'undefined' && (progress.kind === 'markdownContent' || progress.kind === 'markdownVuln')) {
this._firstProgress = this._stopWatch.elapsed();
}
@@ -241,7 +241,8 @@ class ChatAgentResponseStream {
part instanceof extHostTypes.ChatResponseDetectedParticipantPart ||
part instanceof extHostTypes.ChatResponseWarningPart ||
part instanceof extHostTypes.ChatResponseConfirmationPart ||
part instanceof extHostTypes.ChatResponseCodeCitationPart
part instanceof extHostTypes.ChatResponseCodeCitationPart ||
part instanceof extHostTypes.ChatResponseMovePart
) {
checkProposedApiEnabled(that._extension, 'chatParticipantAdditions');
}
+7 -13
View File
@@ -145,8 +145,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
return result;
}
private static _convertNotebookRegistrationData(extension: IExtensionDescription, registration: vscode.NotebookRegistrationData | undefined): INotebookContributionData | undefined {
if (!registration) {
return;
@@ -205,13 +203,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
return assertIsDefined(document?.apiNotebook);
}
async showNotebookDocument(notebookOrUri: vscode.NotebookDocument | URI, options?: vscode.NotebookDocumentShowOptions): Promise<vscode.NotebookEditor> {
if (URI.isUri(notebookOrUri)) {
notebookOrUri = await this.openNotebookDocument(notebookOrUri);
}
async showNotebookDocument(notebook: vscode.NotebookDocument, options?: vscode.NotebookDocumentShowOptions): Promise<vscode.NotebookEditor> {
let resolvedOptions: INotebookDocumentShowOptions;
if (typeof options === 'object') {
resolvedOptions = {
@@ -222,11 +214,13 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
};
} else {
resolvedOptions = {
preserveFocus: false
preserveFocus: false,
pinned: true
};
}
const editorId = await this._notebookEditorsProxy.$tryShowNotebookDocument(notebookOrUri.uri, notebookOrUri.notebookType, resolvedOptions);
const viewType = options?.asRepl ? 'repl' : notebook.notebookType;
const editorId = await this._notebookEditorsProxy.$tryShowNotebookDocument(notebook.uri, viewType, resolvedOptions);
const editor = editorId && this._editors.get(editorId)?.apiEditor;
if (editor) {
@@ -234,9 +228,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
}
if (editorId) {
throw new Error(`Could NOT open editor for "${notebookOrUri.uri.toString()}" because another editor opened in the meantime.`);
throw new Error(`Could NOT open editor for "${notebook.uri.toString()}" because another editor opened in the meantime.`);
} else {
throw new Error(`Could NOT open editor for "${notebookOrUri.uri.toString()}".`);
throw new Error(`Could NOT open editor for "${notebook.uri.toString()}".`);
}
}
@@ -40,7 +40,7 @@ import { DEFAULT_EDITOR_ASSOCIATION, SaveReason } from 'vs/workbench/common/edit
import { IViewBadge } from 'vs/workbench/common/views';
import { ChatAgentLocation, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents';
import { IChatRequestVariableEntry } from 'vs/workbench/contrib/chat/common/chatModel';
import { IChatAgentDetection, IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgressMessage, IChatTaskDto, IChatTaskResult, IChatTextEdit, IChatTreeData, IChatUserActionEvent, IChatWarningMessage } from 'vs/workbench/contrib/chat/common/chatService';
import { IChatAgentDetection, IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatMoveMessage, IChatProgressMessage, IChatTaskDto, IChatTaskResult, IChatTextEdit, IChatTreeData, IChatUserActionEvent, IChatWarningMessage } from 'vs/workbench/contrib/chat/common/chatService';
import { IToolData, IToolResult } from 'vs/workbench/contrib/chat/common/languageModelToolsService';
import * as chatProvider from 'vs/workbench/contrib/chat/common/languageModels';
import { DebugTreeItemCollapsibleState, IDebugVisualizationTreeItem } from 'vs/workbench/contrib/debug/common/debug';
@@ -2454,6 +2454,19 @@ export namespace ChatResponseWarningPart {
}
}
export namespace ChatResponseMovePart {
export function from(part: vscode.ChatResponseMovePart): Dto<IChatMoveMessage> {
return {
kind: 'move',
uri: part.uri,
range: Range.from(part.range),
};
}
export function to(part: Dto<IChatMoveMessage>): vscode.ChatResponseMovePart {
return new types.ChatResponseMovePart(URI.revive(part.uri), Range.to(part.range));
}
}
export namespace ChatTask {
export function from(part: vscode.ChatResponseProgressPart2): IChatTaskDto {
return {
@@ -2561,7 +2574,7 @@ export namespace ChatResponseCodeCitationPart {
export namespace ChatResponsePart {
export function from(part: vscode.ChatResponsePart | vscode.ChatResponseTextEditPart | vscode.ChatResponseMarkdownWithVulnerabilitiesPart | vscode.ChatResponseDetectedParticipantPart | vscode.ChatResponseWarningPart | vscode.ChatResponseConfirmationPart | vscode.ChatResponseReferencePart2, commandsConverter: CommandsConverter, commandDisposables: DisposableStore): extHostProtocol.IChatProgressDto {
export function from(part: vscode.ChatResponsePart | vscode.ChatResponseTextEditPart | vscode.ChatResponseMarkdownWithVulnerabilitiesPart | vscode.ChatResponseDetectedParticipantPart | vscode.ChatResponseWarningPart | vscode.ChatResponseConfirmationPart | vscode.ChatResponseReferencePart2 | vscode.ChatResponseMovePart, commandsConverter: CommandsConverter, commandDisposables: DisposableStore): extHostProtocol.IChatProgressDto {
if (part instanceof types.ChatResponseMarkdownPart) {
return ChatResponseMarkdownPart.from(part);
} else if (part instanceof types.ChatResponseAnchorPart) {
@@ -2586,6 +2599,8 @@ export namespace ChatResponsePart {
return ChatResponseConfirmationPart.from(part);
} else if (part instanceof types.ChatResponseCodeCitationPart) {
return ChatResponseCodeCitationPart.from(part);
} else if (part instanceof types.ChatResponseMovePart) {
return ChatResponseMovePart.from(part);
}
return {
@@ -4486,6 +4486,14 @@ export class ChatResponseCodeCitationPart {
}
}
export class ChatResponseMovePart {
constructor(
public readonly uri: vscode.Uri,
public readonly range: vscode.Range,
) {
}
}
export class ChatResponseTextEditPart {
uri: vscode.Uri;
edits: vscode.TextEdit[];
@@ -0,0 +1,9 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { create } from './extensionHostWorker';
const data = create();
self.onmessage = (e) => data.onmessage(e.data);
@@ -295,7 +295,7 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
},
'workbench.editor.enablePreview': {
'type': 'boolean',
'description': localize('enablePreview', "Controls whether opened editors show as preview editors. Preview editors do not stay open, are reused until explicitly set to be kept open (via double-click or editing), and show file names in italics."),
'description': localize('enablePreview', "Controls whether preview mode is used when editors open. There is a maximum of one preview mode editor per editor group. This editor displays its filename in italics on its tab or title label and in the Open Editors view. Its contents will be replaced by the next editor opened in preview mode. Making a change in a preview mode editor will persist it, as will a double-click on its label, or the 'Keep Open' option in its label context menu. Opening a file from Explorer with a double-click persists its editor immediately."),
'default': true
},
'workbench.editor.enablePreviewFromQuickOpen': {
@@ -94,6 +94,10 @@ class EditorAccessibilityHelpProvider extends Disposable implements IAccessibleV
} else {
content.push(AccessibilityHelpNLS.tabFocusModeOffMsg);
}
content.push(AccessibilityHelpNLS.codeFolding);
content.push(AccessibilityHelpNLS.intellisense);
content.push(AccessibilityHelpNLS.showOrFocusHover);
content.push(AccessibilityHelpNLS.goToSymbol);
content.push(AccessibilityHelpNLS.startDebugging);
content.push(AccessibilityHelpNLS.setBreakpoint);
content.push(AccessibilityHelpNLS.debugExecuteSelection);
@@ -8,7 +8,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { localize, localize2 } from 'vs/nls';
import { Action2 } from 'vs/platform/actions/common/actions';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IProductService } from 'vs/platform/product/common/productService';
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
import { IAuthenticationAccessService } from 'vs/workbench/services/authentication/browser/authenticationAccessService';
@@ -26,23 +26,51 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
});
}
override async run(accessor: ServicesAccessor, options?: { providerId: string; accountLabel: string }): Promise<void> {
const productService = accessor.get(IProductService);
const extensionService = accessor.get(IExtensionService);
const dialogService = accessor.get(IDialogService);
const quickInputService = accessor.get(IQuickInputService);
const authenticationService = accessor.get(IAuthenticationService);
const authenticationUsageService = accessor.get(IAuthenticationUsageService);
const authenticationAccessService = accessor.get(IAuthenticationAccessService);
override run(accessor: ServicesAccessor, options?: { providerId: string; accountLabel: string }): Promise<void> {
const instantiationService = accessor.get(IInstantiationService);
return instantiationService.createInstance(ManageTrustedExtensionsForAccountActionImpl).run(options);
}
}
let providerId = options?.providerId;
let accountLabel = options?.accountLabel;
interface TrustedExtensionsQuickPickItem extends IQuickPickItem {
extension: AllowedExtension;
lastUsed?: number;
}
class ManageTrustedExtensionsForAccountActionImpl {
constructor(
@IProductService private readonly _productService: IProductService,
@IExtensionService private readonly _extensionService: IExtensionService,
@IDialogService private readonly _dialogService: IDialogService,
@IQuickInputService private readonly _quickInputService: IQuickInputService,
@IAuthenticationService private readonly _authenticationService: IAuthenticationService,
@IAuthenticationUsageService private readonly _authenticationUsageService: IAuthenticationUsageService,
@IAuthenticationAccessService private readonly _authenticationAccessService: IAuthenticationAccessService
) { }
async run(options?: { providerId: string; accountLabel: string }) {
const { providerId, accountLabel } = await this._resolveProviderAndAccountLabel(options?.providerId, options?.accountLabel);
if (!providerId || !accountLabel) {
return;
}
const items = await this._getItems(providerId, accountLabel);
if (!items.length) {
return;
}
const disposables = new DisposableStore();
const picker = this._createQuickPick(disposables, providerId, accountLabel);
picker.items = items;
picker.selectedItems = items.filter((i): i is TrustedExtensionsQuickPickItem => i.type !== 'separator' && !!i.picked);
picker.show();
}
private async _resolveProviderAndAccountLabel(providerId: string | undefined, accountLabel: string | undefined) {
if (!providerId || !accountLabel) {
const accounts = new Array<{ providerId: string; providerLabel: string; accountLabel: string }>();
for (const id of authenticationService.getProviderIds()) {
const providerLabel = authenticationService.getProvider(id).label;
const sessions = await authenticationService.getSessions(id);
for (const id of this._authenticationService.getProviderIds()) {
const providerLabel = this._authenticationService.getProvider(id).label;
const sessions = await this._authenticationService.getSessions(id);
const uniqueAccountLabels = new Set<string>();
for (const session of sessions) {
if (!uniqueAccountLabels.has(session.account.label)) {
@@ -52,7 +80,7 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
}
}
const pick = await quickInputService.pick(
const pick = await this._quickInputService.pick(
accounts.map(account => ({
providerId: account.providerId,
label: account.accountLabel,
@@ -68,12 +96,15 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
providerId = pick.providerId;
accountLabel = pick.label;
} else {
return;
return { providerId: undefined, accountLabel: undefined };
}
}
return { providerId, accountLabel };
}
const allowedExtensions = authenticationAccessService.readAllowedExtensions(providerId, accountLabel);
const trustedExtensionAuthAccess = productService.trustedExtensionAuthAccess;
private async _getItems(providerId: string, accountLabel: string) {
const allowedExtensions = this._authenticationAccessService.readAllowedExtensions(providerId, accountLabel);
const trustedExtensionAuthAccess = this._productService.trustedExtensionAuthAccess;
const trustedExtensionIds =
// Case 1: trustedExtensionAuthAccess is an array
Array.isArray(trustedExtensionAuthAccess)
@@ -86,7 +117,7 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
const allowedExtension = allowedExtensions.find(ext => ext.id === extensionId);
if (!allowedExtension) {
// Add the extension to the allowedExtensions list
const extension = await extensionService.getExtension(extensionId);
const extension = await this._extensionService.getExtension(extensionId);
if (extension) {
allowedExtensions.push({
id: extensionId,
@@ -103,21 +134,11 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
}
if (!allowedExtensions.length) {
dialogService.info(localize('noTrustedExtensions', "This account has not been used by any extensions."));
return;
this._dialogService.info(localize('noTrustedExtensions', "This account has not been used by any extensions."));
return [];
}
interface TrustedExtensionsQuickPickItem extends IQuickPickItem {
extension: AllowedExtension;
lastUsed?: number;
}
const disposableStore = new DisposableStore();
const quickPick = disposableStore.add(quickInputService.createQuickPick<TrustedExtensionsQuickPickItem>({ useSeparators: true }));
quickPick.canSelectMany = true;
quickPick.customButton = true;
quickPick.customLabel = localize('manageTrustedExtensions.cancel', 'Cancel');
const usages = authenticationUsageService.readAccountUsages(providerId, accountLabel);
const usages = this._authenticationUsageService.readAccountUsages(providerId, accountLabel);
const trustedExtensions = [];
const otherExtensions = [];
for (const extension of allowedExtensions) {
@@ -131,34 +152,43 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
}
const sortByLastUsed = (a: AllowedExtension, b: AllowedExtension) => (b.lastUsed || 0) - (a.lastUsed || 0);
const toQuickPickItem = function (extension: AllowedExtension): IQuickPickItem & { extension: AllowedExtension } {
const lastUsed = extension.lastUsed;
const description = lastUsed
? localize({ key: 'accountLastUsedDate', comment: ['The placeholder {0} is a string with time information, such as "3 days ago"'] }, "Last used this account {0}", fromNow(lastUsed, true))
: localize('notUsed', "Has not used this account");
let tooltip: string | undefined;
let disabled: boolean | undefined;
if (extension.trusted) {
tooltip = localize('trustedExtensionTooltip', "This extension is trusted by Microsoft and\nalways has access to this account");
disabled = true;
}
return {
label: extension.name,
extension,
description,
tooltip,
disabled,
picked: extension.allowed === undefined || extension.allowed
};
};
const items: Array<TrustedExtensionsQuickPickItem | IQuickPickSeparator> = [
...otherExtensions.sort(sortByLastUsed).map(toQuickPickItem),
{ type: 'separator', label: localize('trustedExtensions', "Trusted by Microsoft") },
...trustedExtensions.sort(sortByLastUsed).map(toQuickPickItem)
const items = [
...otherExtensions.sort(sortByLastUsed).map(this._toQuickPickItem),
{ type: 'separator', label: localize('trustedExtensions', "Trusted by Microsoft") } satisfies IQuickPickSeparator,
...trustedExtensions.sort(sortByLastUsed).map(this._toQuickPickItem)
];
quickPick.items = items;
quickPick.selectedItems = items.filter((item): item is TrustedExtensionsQuickPickItem => item.type !== 'separator' && (item.extension.allowed === undefined || item.extension.allowed));
return items;
}
private _toQuickPickItem(extension: AllowedExtension): TrustedExtensionsQuickPickItem {
const lastUsed = extension.lastUsed;
const description = lastUsed
? localize({ key: 'accountLastUsedDate', comment: ['The placeholder {0} is a string with time information, such as "3 days ago"'] }, "Last used this account {0}", fromNow(lastUsed, true))
: localize('notUsed', "Has not used this account");
let tooltip: string | undefined;
let disabled: boolean | undefined;
if (extension.trusted) {
tooltip = localize('trustedExtensionTooltip', "This extension is trusted by Microsoft and\nalways has access to this account");
disabled = true;
}
return {
label: extension.name,
extension,
description,
tooltip,
disabled,
picked: extension.allowed === undefined || extension.allowed
};
}
private _createQuickPick(disposableStore: DisposableStore, providerId: string, accountLabel: string) {
const quickPick = disposableStore.add(this._quickInputService.createQuickPick<TrustedExtensionsQuickPickItem>({ useSeparators: true }));
quickPick.canSelectMany = true;
quickPick.customButton = true;
quickPick.customLabel = localize('manageTrustedExtensions.cancel', 'Cancel');
quickPick.title = localize('manageTrustedExtensions', "Manage Trusted Extensions");
quickPick.placeholder = localize('manageExtensions', "Choose which extensions can access this account");
@@ -171,7 +201,7 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
updatedAllowedList.forEach(extension => {
extension.allowed = allowedExtensionsSet.has(extension);
});
authenticationAccessService.updateAllowedExtensions(providerId, accountLabel, updatedAllowedList);
this._authenticationAccessService.updateAllowedExtensions(providerId, accountLabel, updatedAllowedList);
quickPick.hide();
}));
@@ -182,8 +212,6 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
disposableStore.add(quickPick.onDidCustom(() => {
quickPick.hide();
}));
quickPick.show();
return quickPick;
}
}
@@ -37,7 +37,7 @@ export function registerChatTitleActions() {
id: MenuId.ChatMessageTitle,
group: 'navigation',
order: 1,
when: ContextKeyExpr.and(CONTEXT_RESPONSE, CONTEXT_VOTE_UP_ENABLED)
when: ContextKeyExpr.and(CONTEXT_RESPONSE, CONTEXT_VOTE_UP_ENABLED, CONTEXT_RESPONSE_FILTERED.negate())
}
});
}
@@ -77,7 +77,7 @@ export function registerChatTitleActions() {
id: MenuId.ChatMessageTitle,
group: 'navigation',
order: 2,
when: CONTEXT_RESPONSE
when: ContextKeyExpr.and(CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED.negate())
}
});
}
@@ -353,7 +353,6 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
templateData.rowContainer.classList.toggle('interactive-request', isRequestVM(element));
templateData.rowContainer.classList.toggle('interactive-response', isResponseVM(element));
templateData.rowContainer.classList.toggle('interactive-welcome', isWelcomeVM(element));
templateData.rowContainer.classList.toggle('filtered-response', isFiltered);
templateData.rowContainer.classList.toggle('show-detail-progress', isResponseVM(element) && !element.isComplete && !element.progressMessages.length);
templateData.username.textContent = element.username;
if (!this.rendererOptions.noHeader) {
@@ -484,30 +483,37 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
this.renderDetail(element, templateData);
}
const isFiltered = !!(isResponseVM(element) && element.errorDetails?.responseIsFiltered);
const parts: IChatContentPart[] = [];
value.forEach((data, index) => {
const context: IChatContentPartRenderContext = {
element,
index,
content: value,
preceedingContentParts: parts,
};
const newPart = this.renderChatContentPart(data, templateData, context);
if (newPart) {
templateData.value.appendChild(newPart.domNode);
parts.push(newPart);
}
});
if (!isFiltered) {
value.forEach((data, index) => {
const context: IChatContentPartRenderContext = {
element,
index,
content: value,
preceedingContentParts: parts,
};
const newPart = this.renderChatContentPart(data, templateData, context);
if (newPart) {
templateData.value.appendChild(newPart.domNode);
parts.push(newPart);
}
});
}
if (templateData.renderedParts) {
dispose(templateData.renderedParts);
}
templateData.renderedParts = parts;
if (isRequestVM(element) && element.variables.length) {
const newPart = this.renderAttachments(element.variables, element.contentReferences, templateData);
if (newPart) {
templateData.value.appendChild(newPart.domNode);
templateData.elementDisposables.add(newPart);
if (!isFiltered) {
if (isRequestVM(element) && element.variables.length) {
const newPart = this.renderAttachments(element.variables, element.contentReferences, templateData);
if (newPart) {
templateData.value.appendChild(newPart.domNode);
templateData.elementDisposables.add(newPart);
}
}
}
@@ -648,12 +648,6 @@
color: var(--vscode-icon-foreground) !important;
}
.interactive-item-container.filtered-response .value > .rendered-markdown {
pointer-events: none;
-webkit-mask-image: linear-gradient(rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.05) 60%, rgba(0, 0, 0, 0.00) 80%);
mask-image: linear-gradient(rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.05) 60%, rgba(0, 0, 0, 0.00) 80%);
}
/* #region Quick Chat */
.quick-input-widget .interactive-session .interactive-input-part {

Some files were not shown because too many files have changed in this diff Show More