Sfoglia il codice sorgente

Merge branch 'main' into patch-1

Henning Dieterichs 2 anni fa
parent
commit
1f0d010563
71 ha cambiato i file con 9843 aggiunte e 3327 eliminazioni
  1. 56 0
      .azure-pipelines/publish-nightly.yml
  2. 58 0
      .azure-pipelines/publish-stable.yml
  3. 8 2
      .github/workflows/ci.yml
  4. 0 25
      .github/workflows/pr-chat.yml
  5. 0 235
      .github/workflows/publish.yml
  6. 8 4
      .github/workflows/publish/computeState.js
  7. 0 19
      .github/workflows/publish/setDevDependencyVersion.js
  8. 0 17
      .github/workflows/publish/setVersion.js
  9. 4 0
      .gitignore
  10. 2 0
      .prettierignore
  11. 4 1
      .vscode/settings.json
  12. 10 1
      CHANGELOG.md
  13. 10 1
      CONTRIBUTING.md
  14. 1 0
      MAINTAINING.md
  15. 13 83
      build/importTypescript.ts
  16. 2 1
      build/tsconfig.json
  17. 2 0
      build/utils.ts
  18. 6980 2236
      package-lock.json
  19. 19 5
      package.json
  20. 31 31
      samples/browser-esm-vite-react/package-lock.json
  21. 1 1
      samples/browser-esm-vite-react/package.json
  22. 7 5
      samples/browser-esm-vite-react/src/components/Editor.tsx
  23. 1 1
      samples/browser-esm-webpack-small/index.js
  24. 12 12
      samples/browser-esm-webpack-typescript-react/package-lock.json
  25. 3 1
      samples/electron-amd-nodeIntegration/main.js
  26. 3 2
      samples/electron-esm-webpack/.gitignore
  27. 213 323
      samples/package-lock.json
  28. 4 1
      samples/package.json
  29. 34 0
      scripts/ci/monaco-editor-core.sh
  30. 33 0
      scripts/ci/monaco-editor.sh
  31. 67 0
      scripts/ci/prepare-monaco-editor-core.ts
  32. 50 0
      scripts/ci/prepare-monaco-editor.ts
  33. 55 0
      scripts/lib/index.ts
  34. 1 1
      src/basic-languages/cpp/cpp.ts
  35. 27 0
      src/basic-languages/elixir/elixir.test.ts
  36. 25 1
      src/basic-languages/elixir/elixir.ts
  37. 1 1
      src/basic-languages/kotlin/kotlin.contribution.ts
  38. 4 0
      src/basic-languages/pgsql/pgsql.ts
  39. 1 0
      src/basic-languages/typescript/typescript.ts
  40. 2 0
      src/basic-languages/xml/xml.contribution.ts
  41. 603 18
      src/language/typescript/lib/typescriptServices-amd.js
  42. 1 3
      src/language/typescript/lib/typescriptServices.d.ts
  43. 609 24
      src/language/typescript/lib/typescriptServices.js
  44. 103 3
      src/language/typescript/monaco.contribution.ts
  45. 119 32
      src/language/typescript/tsMode.ts
  46. 2 2
      src/language/typescript/tsWorker.ts
  47. 2 2
      test/smoke/amd/index.html
  48. 6 1
      test/smoke/common.js
  49. 0 0
      test/smoke/esbuild/index.html
  50. 5 0
      test/smoke/esbuild/index.js
  51. 1 1
      test/smoke/package-esbuild.ts
  52. 19 0
      test/smoke/package-vite.ts
  53. 56 0
      test/smoke/package-webpack.ts
  54. 11 0
      test/smoke/parcel/index.html
  55. 35 0
      test/smoke/parcel/index.js
  56. 6 0
      test/smoke/parcel/package.json
  57. 22 12
      test/smoke/runner.js
  58. 64 41
      test/smoke/smoke.test.js
  59. 10 0
      test/smoke/vite/index.html
  60. 31 0
      test/smoke/vite/index.js
  61. 0 0
      test/smoke/webpack/index.html
  62. 0 0
      test/smoke/webpack/index.js
  63. 2 0
      test/unit/all.js
  64. 3 0
      test/unit/setup.js
  65. 12 12
      webpack-plugin/package-lock.json
  66. 0 2
      webpack-plugin/package.json
  67. 0 39
      webpack-plugin/smoketest/webpack-cross-origin.config.js
  68. 0 36
      webpack-plugin/smoketest/webpack.config.js
  69. 182 42
      website/playground/monaco.d.ts.txt
  70. 6 6
      website/playground/new-samples/extending-language-services/color-provider-example/sample.js
  71. 181 41
      website/typedoc/monaco.d.ts

+ 56 - 0
.azure-pipelines/publish-nightly.yml

@@ -0,0 +1,56 @@
+###############################################################################################
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#  Licensed under the MIT License. See License.txt in the project root for license information.
+###############################################################################################
+name: $(Date:yyyyMMdd)$(Rev:.r)
+
+trigger: none
+pr: none
+
+schedules:
+  - cron: '0 7 * * *'
+    displayName: Daily release
+    branches:
+      include:
+        - main
+    always: true
+
+resources:
+  repositories:
+    - repository: templates
+      type: github
+      name: microsoft/vscode-engineering
+      ref: main
+      endpoint: Monaco
+
+extends:
+  template: azure-pipelines/npm-package/pipeline.yml@templates
+  parameters:
+    npmPackages:
+      - name: monaco-editor-core
+        workingDirectory: $(Build.SourcesDirectory)/dependencies/vscode/out-monaco-editor-core
+        testPlatforms: []
+        buildSteps:
+          - script: npm ci
+            displayName: Install NPM dependencies
+
+          - script: yarn ts-node ./scripts/ci/prepare-monaco-editor-core nightly
+            displayName: Setup, Build & Test monaco-editor-core
+
+        tag: next
+        publishPackage: true
+        publishRequiresApproval: false
+
+      - name: monaco-editor
+        workingDirectory: $(Build.SourcesDirectory)/release
+        testPlatforms: []
+        buildSteps:
+          - script: npm ci
+            displayName: Install NPM dependencies
+
+          - script: yarn ts-node ./scripts/ci/prepare-monaco-editor nightly
+            displayName: Setup, Build & Test monaco-editor
+
+        tag: next
+        publishPackage: true
+        publishRequiresApproval: false

+ 58 - 0
.azure-pipelines/publish-stable.yml

@@ -0,0 +1,58 @@
+###############################################################################################
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#  Licensed under the MIT License. See License.txt in the project root for license information.
+###############################################################################################
+name: $(Date:yyyyMMdd)$(Rev:.r)
+
+trigger: none
+pr: none
+
+resources:
+  repositories:
+    - repository: templates
+      type: github
+      name: microsoft/vscode-engineering
+      ref: main
+      endpoint: Monaco
+
+parameters:
+  - name: publishMonacoEditorCore
+    displayName: 🚀 Publish Monaco Editor Core
+    type: boolean
+    default: false
+  - name: publishMonacoEditor
+    displayName: 🚀 Publish Editor Core
+    type: boolean
+    default: false
+
+extends:
+  template: azure-pipelines/npm-package/pipeline.yml@templates
+  parameters:
+    npmPackages:
+      - name: monaco-editor-core
+        workingDirectory: $(Build.SourcesDirectory)/dependencies/vscode/out-monaco-editor-core
+        testPlatforms: []
+        buildSteps:
+          - script: npm ci
+            displayName: Install NPM dependencies
+
+          - script: yarn ts-node ./scripts/ci/prepare-monaco-editor-core stable
+            displayName: Setup, Build & Test monaco-editor-core
+
+        tag: latest
+        publishPackage: ${{ parameters.publishMonacoEditorCore }}
+        publishRequiresApproval: false
+
+      - name: monaco-editor
+        workingDirectory: $(Build.SourcesDirectory)/release
+        testPlatforms: []
+        buildSteps:
+          - script: npm ci
+            displayName: Install NPM dependencies
+
+          - script: yarn ts-node ./scripts/ci/prepare-monaco-editor stable
+            displayName: Setup, Build & Test monaco-editor
+
+        tag: latest
+        publishPackage: ${{ parameters.publishMonacoEditor }}
+        publishRequiresApproval: false

+ 8 - 2
.github/workflows/ci.yml

@@ -5,7 +5,7 @@ on: [push, pull_request]
 jobs:
   build:
     name: CI
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
 
@@ -48,11 +48,17 @@ jobs:
         run: npm run compile --prefix webpack-plugin
 
       - name: Package using webpack plugin
-        run: npm run package-for-smoketest --prefix webpack-plugin
+        run: npm run package-for-smoketest-webpack
 
       - name: Package using esbuild
         run: npm run package-for-smoketest-esbuild
 
+      - name: Package using vite
+        run: npm run package-for-smoketest-vite
+
+      - name: Package using parcel
+        run: npm run package-for-smoketest-parcel --prefix test/smoke/parcel
+
       - name: Run smoke test
         run: npm run smoketest
 

+ 0 - 25
.github/workflows/pr-chat.yml

@@ -1,25 +0,0 @@
-name: PR Chat
-on:
-  pull_request_target:
-    types: [opened, ready_for_review, closed]
-
-jobs:
-  main:
-    runs-on: ubuntu-latest
-    if: ${{ !github.event.pull_request.draft }}
-    steps:
-      - name: Checkout Actions
-        uses: actions/checkout@v2
-        with:
-          repository: 'microsoft/vscode-github-triage-actions'
-          ref: stable
-          path: ./actions
-      - name: Install Actions
-        run: npm install --production --prefix ./actions
-      - name: Run Code Review Chat
-        uses: ./actions/code-review-chat
-        with:
-          token: ${{secrets.GITHUB_TOKEN}}
-          slack_token: ${{ secrets.SLACK_TOKEN }}
-          slack_bot_name: 'VSCodeBot'
-          notification_channel: codereview

+ 0 - 235
.github/workflows/publish.yml

@@ -1,235 +0,0 @@
-name: Publish to npm
-
-on:
-  schedule:
-    - cron: '0 7 * * *'
-  # enable users to manually trigger with workflow_dispatch
-  workflow_dispatch:
-    inputs:
-      nightly:
-        description: 'is nightly?'
-        required: true
-        default: 'true'
-jobs:
-  publish:
-    if: ${{ github.repository == 'microsoft/monaco-editor' }}
-    name: Publish to npm
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/setup-node@v2
-        with:
-          node-version: 16
-
-      - name: (monaco-editor) checkout
-        uses: actions/checkout@v2
-        with:
-          repository: 'microsoft/monaco-editor'
-          path: './monaco-editor'
-
-      - name: Compute state
-        id: state
-        run: |
-          echo '::echo::on'
-          node ./monaco-editor/.github/workflows/publish/computeState.js "${{github.event_name}}" "${{github.event.inputs.nightly}}"
-        # outputs: dist_tag, version, vscode_branch, skip_monaco_editor_core, skip_monaco_editor
-
-      - name: (vscode) checkout
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        uses: actions/checkout@v2
-        with:
-          repository: 'microsoft/vscode'
-          ref: ${{ steps.state.outputs.vscode_branch }}
-          path: './vscode'
-
-      - name: (vscode-loc) checkout
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        uses: actions/checkout@v2
-        with:
-          repository: 'microsoft/vscode-loc'
-          path: './vscode-loc'
-
-      - name: (vscode) execute `yarn`
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn --frozen-lockfile --network-timeout 180000
-
-      - name: (vscode) Download Playwright
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: ./vscode
-        run: yarn playwright-install
-
-      - name: (vscode) Run Hygiene Checks
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn gulp hygiene
-
-      - name: (vscode) Run Valid Layers Checks
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn valid-layers-check
-
-      - name: (vscode) Compile /build/
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn --cwd build compile
-
-      - name: (vscode) Run eslint
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn eslint
-
-      - name: (vscode) Run Monaco Editor Checks
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn monaco-compile-check
-
-      - name: (vscode) Compile
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn --max_old_space_size=4095 compile
-
-      - name: (vscode) Run Unit Tests (Browser)
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn test-browser --browser chromium
-
-      - name: (vscode) Patch package.json version
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        run: node ./monaco-editor/.github/workflows/publish/setVersion.js ./vscode/build/monaco/package.json ${{ steps.state.outputs.version }}
-
-      - name: (vscode) Editor Distro
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: yarn gulp editor-distro
-
-      - name: Editor ESM sources check
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode/test/monaco'
-        run: yarn run esm-check
-
-      - name: (vscode) Typings validation prep
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode'
-        run: mkdir typings-test
-
-      - name: (vscode) Typings validation
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: ./vscode/typings-test
-        run: |
-          yarn init -yp
-          ../node_modules/.bin/tsc --init
-          echo "import '../out-monaco-editor-core';" > a.ts
-          ../node_modules/.bin/tsc --noEmit
-
-      - name: (vscode) Package Editor with Webpack
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: ./vscode/test/monaco
-        run: yarn run bundle-webpack
-
-      - name: (vscode) Compile Editor Tests
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: ./vscode/test/monaco
-        run: yarn run compile
-
-      - name: (vscode) Run Editor Tests
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        timeout-minutes: 5
-        working-directory: ./vscode/test/monaco
-        run: yarn test
-
-      - name: Set `npm` config
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        run: npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
-        env:
-          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
-
-      - name: Publish `monaco-editor-core`
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: './vscode/out-monaco-editor-core'
-        run: npm publish --tag ${{ steps.state.outputs.dist_tag }}
-
-      - name: Delete `npm` config
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        run: npm config delete //registry.npmjs.org/:_authToken
-
-      - name: (monaco-editor) Patch package.json version
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        run: node ./monaco-editor/.github/workflows/publish/setVersion.js ./monaco-editor/package.json ${{ steps.state.outputs.version }}
-
-      - name: (monaco-editor) execute `npm ci` (1)
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm ci
-
-      - name: (monaco-editor) execute `npm ci` (2)
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor/webpack-plugin'
-        run: npm ci
-
-      - name: (monaco-editor) Patch package.json monaco-editor-core dev dependency version
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        run: node ./monaco-editor/.github/workflows/publish/setDevDependencyVersion.js ./monaco-editor/package.json monaco-editor-core ${{ steps.state.outputs.version }}
-
-      - name: (monaco-editor) execute `npm install` to pick up local monaco-editor-core
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm install
-
-      - name: (monaco-editor) Install OS Dependencies for Playwright
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: sudo npm run playwright-install-deps
-
-      - name: (monaco-editor) Check prettier
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run prettier-check
-
-      - name: (monaco-editor) Build
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run release
-
-      - name: (monaco-editor) Run unit tests
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm test
-
-      - name: (monaco-editor) Compile webpack plugin
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run compile --prefix webpack-plugin
-
-      - name: (monaco-editor) Package using webpack plugin
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run package-for-smoketest --prefix webpack-plugin
-
-      - name: (monaco-editor) Run smoke test
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run smoketest
-
-      - name: (monaco-editor) Build website
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor'
-        run: npm run build-website
-
-      - name: Set `npm` config
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        run: npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
-        env:
-          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
-
-      - name: Publish `monaco-editor`
-        if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
-        working-directory: './monaco-editor/release'
-        run: npm publish --tag ${{ steps.state.outputs.dist_tag }}
-
-      - name: Create Issue On Failure
-        if: failure()
-        uses: JasonEtco/create-an-issue@9e6213aec58987fa7d2f4deb8b256b99e63107a2
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          filename: ./monaco-editor/.github/publish-failure-issue-template.md

+ 8 - 4
.github/workflows/publish/computeState.js

@@ -90,10 +90,14 @@ function npmGetLatestVersion(packageName) {
  * @returns {boolean}
  */
 function npmExists(packageName, version) {
-	const output = cp.execSync(`npm show ${packageName}@${version} version`).toString();
-	const result = output.split(/\r\n|\r|\n/g)[0];
-	if (result.trim().length === 0) {
+	try {
+		const output = cp.execSync(`npm show ${packageName}@${version} version`).toString();
+		const result = output.split(/\r\n|\r|\n/g)[0];
+		if (result.trim().length === 0) {
+			return false;
+		}
+		return true;
+	} catch (err) {
 		return false;
 	}
-	return true;
 }

+ 0 - 19
.github/workflows/publish/setDevDependencyVersion.js

@@ -1,19 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-//@ts-check
-
-const fs = require('fs');
-
-if (process.argv.length !== 5) {
-	console.error(
-		`usage: node setDevDependencyVersion.js <PATH_TO_PACKAGE_JSON_FILE> <PACKAGE> <VERSION>`
-	);
-	process.exit(1);
-}
-
-const packagejson = JSON.parse(fs.readFileSync(process.argv[2]).toString());
-packagejson['devDependencies'][process.argv[3]] = process.argv[4];
-fs.writeFileSync(process.argv[2], JSON.stringify(packagejson, null, '\t') + '\n');

+ 0 - 17
.github/workflows/publish/setVersion.js

@@ -1,17 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-//@ts-check
-
-const fs = require('fs');
-
-if (process.argv.length !== 4) {
-	console.error(`usage: node setVersion.js <PATH_TO_PACKAGE_JSON_FILE> <VERSION>`);
-	process.exit(1);
-}
-
-const packagejson = JSON.parse(fs.readFileSync(process.argv[2]).toString());
-packagejson.version = process.argv[3];
-fs.writeFileSync(process.argv[2], JSON.stringify(packagejson, null, '\t') + '\n');

+ 4 - 0
.gitignore

@@ -1,4 +1,8 @@
 **/node_modules/
 **/out/
 **/release/
+**/dependencies/
 /test/manual/generated/**
+/test/smoke/vite/dist/**
+/test/smoke/parcel/dist/**
+/test/smoke/parcel/.cache/**

+ 2 - 0
.prettierignore

@@ -13,3 +13,5 @@
 /test/manual/generated/
 /website/lib/
 /website/typedoc/monaco.d.ts
+/test/smoke/vite/dist
+/test/smoke/parcel/dist

+ 4 - 1
.vscode/settings.json

@@ -9,5 +9,8 @@
 		"**/release": true,
 		"**/out": true
 	},
-	"typescript.tsdk": "./node_modules/typescript/lib"
+	"typescript.tsdk": "./node_modules/typescript/lib",
+	"git.branchProtection": ["main", "release/*"],
+	"git.branchProtectionPrompt": "alwaysCommitToNewBranch",
+	"git.branchRandomName.enable": true
 }

+ 10 - 1
CHANGELOG.md

@@ -1,5 +1,14 @@
 # Monaco Editor Changelog
 
+## [0.35.1]
+
+- Adds sticky scrolling
+- Renamed the option `enableDropIntoEditor` to `dropIntoEditor`
+
+## [0.34.1]
+
+- Adds API to register global actions, commands, or keybinding rules
+
 ## [0.34.0]
 
 - Introduction of `IEditor.createDecorationsCollection` API
@@ -492,7 +501,7 @@ Contributions to `monaco-typescript`:
 - Many improvements in `monaco-typescript`: support for "deprecated" tags, API to participate in the web worker, improved lib.d.ts resolving.
 - New tokenization support for: Julia, Scala, Lexon, Terraform HCL, Dart, Systemverilog.
 - New semantic tokens provider [sample on the playground](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-semantic-tokens-provider-example).
-- New [shadow dom sample](https://github.com/microsoft/monaco-editor-samples/tree/master/browser-amd-shadow-dom)
+- New [shadow dom sample](https://github.com/microsoft/monaco-editor/tree/main/samples/browser-amd-shadow-dom)
 - New `overflowWidgetsDomNode` constructor option to pass in a parent for overflowing widgets.
 - New `minimap.size` option: `proportional`, `fill`, `fit`.
 - New `OnTypeRename` provider and option `renameOnType`.

+ 10 - 1
CONTRIBUTING.md

@@ -74,7 +74,16 @@ Open [http://localhost:8080/monaco-editor/test/manual/?editor=src](http://localh
 /src/monaco-editor> npm run compile --prefix webpack-plugin
 
 # package using the webpack plugin
-/src/monaco-editor> npm run package-for-smoketest --prefix webpack-plugin
+/src/monaco-editor> npm run package-for-smoketest-webpack
+
+# package using esbuild
+/src/monaco-editor> npm run package-for-smoketest-esbuild
+
+# package using vite
+/src/monaco-editor> npm run package-for-smoketest-vite
+
+# package using parcel
+/src/monaco-editor> npm run package-for-smoketest-parcel --prefix test/smoke/parcel
 
 # run the smoketest
 /src/monaco-editor> npm run smoketest-debug

+ 1 - 0
MAINTAINING.md

@@ -2,6 +2,7 @@
 
 (For maintainers)
 
+- [P1 Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+-label%3Afeature-request+-label%3Aquestion+-label%3Aupstream+-label%3A%22help+wanted%22+-label%3A%22info-needed%22+-label%3A%22as-designed%22+-label%3Abug+-label%3A*question+)
 - [Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+no%3Aassignee+-label%3Afeature-request+-label%3Aquestion+-label%3Aupstream+-label%3A%22help+wanted%22+-label%3A%22info-needed%22+-label%3A%22as-designed%22+)
 
 ## Updating TypeScript

+ 13 - 83
build/importTypescript.ts

@@ -35,73 +35,18 @@ const TYPESCRIPT_LIB_DESTINATION = path.join(REPO_ROOT, 'src/language/typescript
 export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
 	);
 
-	let tsServices = fs
-		.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.js'))
-		.toString();
+	let tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescript.js')).toString();
 
-	// Ensure we never run into the node system...
-	// (this also removes require calls that trick webpack into shimming those modules...)
-	tsServices = tsServices.replace(
-		/\n    ts\.sys =([^]*)\n    \}\)\(\);/m,
-		`\n    // MONACOCHANGE\n    ts.sys = undefined;\n    // END MONACOCHANGE`
-	);
-
-	// Eliminate more require() calls...
-	tsServices = tsServices.replace(
-		/^( +)etwModule = require\(.*$/m,
-		'$1// MONACOCHANGE\n$1etwModule = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)var result = ts\.sys\.require\(.*$/m,
-		'$1// MONACOCHANGE\n$1var result = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)fs = require\("fs"\);$/m,
-		'$1// MONACOCHANGE\n$1fs = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)debugger;$/m,
-		'$1// MONACOCHANGE\n$1// debugger;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/= require\("perf_hooks"\)/m,
-		'/* MONACOCHANGE */= {}/* END MONACOCHANGE */'
-	);
-	tsServices = tsServices.replace(
-		/typeof require === "function"/m,
-		'/* MONACOCHANGE */false/* END MONACOCHANGE */'
-	);
-
-	tsServices = tsServices.replace(
-		/module.exports = ts;/m,
-		'/* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */'
-	);
-
-	// Flag any new require calls (outside comments) so they can be corrected preemptively.
-	// To avoid missing cases (or using an even more complex regex), temporarily remove comments
-	// about require() and then check for lines actually calling require().
-	// \/[*/] matches the start of a comment (single or multi-line).
-	// ^\s+\*[^/] matches (presumably) a later line of a multi-line comment.
-	const tsServicesNoCommentedRequire = tsServices.replace(
-		/(\/[*/]|^\s+\*[^/]).*\brequire\(.*/gm,
-		''
-	);
-	const linesWithRequire = tsServicesNoCommentedRequire.match(/^.*?\brequire\(.*$/gm);
-
-	// Allow error messages to include references to require() in their strings
-	const runtimeRequires =
-		linesWithRequire &&
-		linesWithRequire.filter((l) => !l.includes(': diag(') && !l.includes('ts.DiagnosticCategory'));
-
-	if (runtimeRequires && runtimeRequires.length && linesWithRequire) {
-		console.error(
-			'Found new require() calls on the following lines. These should be removed to avoid breaking webpack builds.\n'
-		);
-		console.error(
-			runtimeRequires.map((r) => `${r} (${tsServicesNoCommentedRequire.indexOf(r)})`).join('\n')
-		);
-		process.exit(1);
-	}
+	// The output from this build will only be accessible via AMD or ESM; rather than removing
+	// references to require/module, define them as dummy variables that bundlers will ignore.
+	// The TS code can figure out that it's not running under Node even with these defined.
+	tsServices =
+		`
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
+` + tsServices;
 
 	const tsServices_amd =
 		generatedNote +
@@ -118,15 +63,6 @@ define("vs/language/typescript/lib/typescriptServices", [], function() { return
 		stripSourceMaps(tsServices_amd)
 	);
 
-	// Remove pattern that creates warnings with esbuild
-	// e.g.
-	// > /src/typescript/lib/typescriptServices.js:20:21: warning: Top-level "this" will be replaced with undefined since this file is an ECMAScript module
-	// 20 │ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
-	//    ╵                      ~~~~
-	//
-
-	tsServices = tsServices.replace(/\nvar ([^ ]+) = \(this && this\.([^)]+)\) \|\|/gm, '\nvar $1 =');
-
 	const tsServices_esm =
 		generatedNote +
 		tsServices +
@@ -149,14 +85,8 @@ export var typescript = ts;
 		stripSourceMaps(tsServices_esm)
 	);
 
-	let dtsServices = fs
-		.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.d.ts'))
-		.toString();
-	dtsServices += `
-// MONACOCHANGE
-export = ts;
-// END MONACOCHANGE
-`;
+	let dtsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescript.d.ts')).toString();
+
 	fs.writeFileSync(
 		path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.d.ts'),
 		generatedNote + dtsServices

+ 2 - 1
build/tsconfig.json

@@ -1,7 +1,8 @@
 {
 	"compilerOptions": {
 		"noEmit": true,
+		"module": "CommonJS",
 		"esModuleInterop": true
 	},
-	"files": ["./**/*"]
+	"include": ["./**/*"]
 }

+ 2 - 0
build/utils.ts

@@ -104,6 +104,7 @@ export function buildESM(options: { base: string; entryPoints: string[]; externa
 		bundle: true,
 		target: 'esnext',
 		format: 'esm',
+		drop: ['debugger'],
 		define: {
 			AMD: 'false'
 		},
@@ -141,6 +142,7 @@ function buildOneAMD(
 		bundle: true,
 		target: 'esnext',
 		format: 'iife',
+		drop: ['debugger'],
 		define: {
 			AMD: 'true'
 		},

File diff suppressed because it is too large
+ 6980 - 2236
package-lock.json


+ 19 - 5
package.json

@@ -1,15 +1,15 @@
 {
 	"name": "monaco-editor",
-	"version": "0.34.0",
-	"vscode": "4b8a47f3570a4a05ace9d00ae0df044b55befcd5",
+	"version": "0.34.1",
+	"vscodeRef": "0316a754aa4c25208bef91937efbce2ab1e3ce37",
 	"private": true,
 	"description": "A browser based code editor",
+	"homepage": "https://github.com/microsoft/monaco-editor",
 	"author": "Microsoft Corporation",
 	"license": "MIT",
 	"scripts": {
 		"build-website": "ts-node ./build/website && npm run typedoc",
 		"import-typescript": "ts-node ./build/importTypescript",
-		"package-for-smoketest-esbuild": "ts-node ./test/smoke/package-esbuild",
 		"playwright-install": "node ./node_modules/playwright/install.js",
 		"playwright-install-deps": "playwright install-deps",
 		"postinstall": "ts-node ./build/postinstall",
@@ -18,8 +18,12 @@
 		"pretty-quick": "pretty-quick --staged",
 		"release": "ts-node ./build/build && ts-node ./build/release",
 		"simpleserver": "ts-node ./build/simpleserver",
-		"smoketest-debug": "node ./test/smoke/runner.js --debug-tests",
+		"package-for-smoketest-webpack": "ts-node ./test/smoke/package-webpack",
+		"package-for-smoketest-webpack-cross-origin": "ts-node ./test/smoke/package-webpack --cross-origin",
+		"package-for-smoketest-esbuild": "ts-node ./test/smoke/package-esbuild",
+		"package-for-smoketest-vite": "ts-node ./test/smoke/package-vite",
 		"smoketest": "node ./test/smoke/runner.js",
+		"smoketest-debug": "node ./test/smoke/runner.js --debug-tests",
 		"test": "mocha test/unit/all.js",
 		"deps-all-remove": "ts-node ./build/npm/removeAll",
 		"deps-all-install": "ts-node ./build/npm/installAll",
@@ -37,28 +41,38 @@
 		"@typescript/vfs": "^1.3.5",
 		"chai": "^4.3.6",
 		"clean-css": "^5.2.4",
+		"css-loader": "^6.7.1",
 		"esbuild": "^0.14.49",
 		"esbuild-plugin-alias": "^0.2.1",
+		"file-loader": "^6.2.0",
 		"glob": "^7.2.0",
 		"husky": "^7.0.4",
 		"jsdom": "^19.0.0",
 		"jsonc-parser": "^3.0.0",
 		"mocha": "^9.2.0",
-		"monaco-editor-core": "0.34.0-dev.20220720",
+		"monaco-editor-core": "0.35.0-dev.20221208",
+		"parcel": "^2.7.0",
 		"playwright": "^1.18.1",
 		"prettier": "^2.5.1",
 		"pretty-quick": "^3.1.3",
 		"requirejs": "^2.3.6",
+		"style-loader": "^3.3.1",
 		"terser": "^5.14.2",
 		"ts-node": "^10.6.0",
 		"typedoc": "^0.22.11",
 		"typescript": "4.5.5",
+		"vite": "^3.1.8",
 		"vscode-css-languageservice": "5.4.1",
 		"vscode-html-languageservice": "4.2.4",
 		"vscode-json-languageservice": "4.2.1",
 		"vscode-languageserver-textdocument": "^1.0.4",
 		"vscode-languageserver-types": "3.16.0",
 		"vscode-uri": "3.0.3",
+		"webpack": "^5.74.0",
 		"yaserver": "^0.4.0"
+	},
+	"alias": {
+		"process": false,
+		"buffer": false
 	}
 }

+ 31 - 31
samples/browser-esm-vite-react/package-lock.json

@@ -13,7 +13,7 @@
 				"react": "^17.0.2",
 				"react-dom": "^17.0.2",
 				"typescript": "^4.5.5",
-				"vite": "^2.7.13"
+				"vite": "^2.9.13"
 			}
 		},
 		"node_modules/@ampproject/remapping": {
@@ -1104,9 +1104,9 @@
 			}
 		},
 		"node_modules/json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true,
 			"bin": {
 				"json5": "lib/cli.js"
@@ -1140,9 +1140,9 @@
 			"dev": true
 		},
 		"node_modules/nanoid": {
-			"version": "3.3.2",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz",
-			"integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==",
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
 			"dev": true,
 			"bin": {
 				"nanoid": "bin/nanoid.cjs"
@@ -1191,9 +1191,9 @@
 			}
 		},
 		"node_modules/postcss": {
-			"version": "8.4.12",
-			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
-			"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
+			"version": "8.4.16",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
+			"integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==",
 			"dev": true,
 			"funding": [
 				{
@@ -1206,7 +1206,7 @@
 				}
 			],
 			"dependencies": {
-				"nanoid": "^3.3.1",
+				"nanoid": "^3.3.4",
 				"picocolors": "^1.0.0",
 				"source-map-js": "^1.0.2"
 			},
@@ -1372,13 +1372,13 @@
 			}
 		},
 		"node_modules/vite": {
-			"version": "2.8.6",
-			"resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
-			"integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
+			"version": "2.9.13",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.13.tgz",
+			"integrity": "sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw==",
 			"dev": true,
 			"dependencies": {
-				"esbuild": "^0.14.14",
-				"postcss": "^8.4.6",
+				"esbuild": "^0.14.27",
+				"postcss": "^8.4.13",
 				"resolve": "^1.22.0",
 				"rollup": "^2.59.0"
 			},
@@ -2116,9 +2116,9 @@
 			"dev": true
 		},
 		"json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true
 		},
 		"loose-envify": {
@@ -2143,9 +2143,9 @@
 			"dev": true
 		},
 		"nanoid": {
-			"version": "3.3.2",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz",
-			"integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==",
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
 			"dev": true
 		},
 		"node-releases": {
@@ -2179,12 +2179,12 @@
 			"dev": true
 		},
 		"postcss": {
-			"version": "8.4.12",
-			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
-			"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
+			"version": "8.4.16",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
+			"integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==",
 			"dev": true,
 			"requires": {
-				"nanoid": "^3.3.1",
+				"nanoid": "^3.3.4",
 				"picocolors": "^1.0.0",
 				"source-map-js": "^1.0.2"
 			}
@@ -2298,14 +2298,14 @@
 			"dev": true
 		},
 		"vite": {
-			"version": "2.8.6",
-			"resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
-			"integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
+			"version": "2.9.13",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.13.tgz",
+			"integrity": "sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw==",
 			"dev": true,
 			"requires": {
-				"esbuild": "^0.14.14",
+				"esbuild": "^0.14.27",
 				"fsevents": "~2.3.2",
-				"postcss": "^8.4.6",
+				"postcss": "^8.4.13",
 				"resolve": "^1.22.0",
 				"rollup": "^2.59.0"
 			}

+ 1 - 1
samples/browser-esm-vite-react/package.json

@@ -15,6 +15,6 @@
 		"@types/react-dom": "^17.0.11",
 		"@vitejs/plugin-react": "^1.1.4",
 		"typescript": "^4.5.5",
-		"vite": "^2.7.13"
+		"vite": "^2.9.13"
 	}
 }

+ 7 - 5
samples/browser-esm-vite-react/src/components/Editor.tsx

@@ -7,13 +7,15 @@ export const Editor: VFC = () => {
 	const monacoEl = useRef(null);
 
 	useEffect(() => {
-		if (monacoEl && !editor) {
-			setEditor(
-				monaco.editor.create(monacoEl.current!, {
+		if (monacoEl) {
+			setEditor((editor) => {
+				if (editor) return;
+
+				return monaco.editor.create(monacoEl.current!, {
 					value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
 					language: 'typescript'
-				})
-			);
+				});
+			});
 		}
 
 		return () => editor?.dispose();

+ 1 - 1
samples/browser-esm-webpack-small/index.js

@@ -17,7 +17,7 @@ import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js';
 // import 'monaco-editor/esm/vs/editor/contrib/cursorUndo/cursorUndo.js';
 // import 'monaco-editor/esm/vs/editor/contrib/dnd/dnd.js';
 // import 'monaco-editor/esm/vs/editor/contrib/documentSymbols/documentSymbols.js';
-import 'monaco-editor/esm/vs/editor/contrib/find/findController.js';
+import 'monaco-editor/esm/vs/editor/contrib/find/browser/findController.js';
 // import 'monaco-editor/esm/vs/editor/contrib/folding/folding.js';
 // import 'monaco-editor/esm/vs/editor/contrib/fontZoom/fontZoom.js';
 // import 'monaco-editor/esm/vs/editor/contrib/format/formatActions.js';

+ 12 - 12
samples/browser-esm-webpack-typescript-react/package-lock.json

@@ -2822,9 +2822,9 @@
 			"dev": true
 		},
 		"node_modules/json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true,
 			"bin": {
 				"json5": "lib/cli.js"
@@ -2844,9 +2844,9 @@
 			}
 		},
 		"node_modules/loader-utils": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
-			"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+			"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
 			"dev": true,
 			"dependencies": {
 				"big.js": "^5.2.2",
@@ -5639,9 +5639,9 @@
 			"dev": true
 		},
 		"json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true
 		},
 		"loader-runner": {
@@ -5652,9 +5652,9 @@
 			"peer": true
 		},
 		"loader-utils": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
-			"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+			"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
 			"dev": true,
 			"requires": {
 				"big.js": "^5.2.2",

+ 3 - 1
samples/electron-amd-nodeIntegration/main.js

@@ -10,7 +10,9 @@ function createWindow() {
 		height: 600,
 		webPreferences: {
 			nodeIntegration: true,
-			worldSafeExecuteJavaScript: true
+			worldSafeExecuteJavaScript: true,
+			sandbox: false,
+			contextIsolation: false
 		}
 	});
 	mainWindow.loadURL(`file://${__dirname}/electron-index.html`);

+ 3 - 2
samples/electron-esm-webpack/.gitignore

@@ -1,2 +1,3 @@
-/dist/*.js
-/dist/*.ttf
+dist/*.js
+dist/*.txt
+dist/*.ttf

File diff suppressed because it is too large
+ 213 - 323
samples/package-lock.json


+ 4 - 1
samples/package.json

@@ -11,7 +11,7 @@
 	"license": "MIT",
 	"devDependencies": {
 		"css-loader": "^5.2.7",
-		"electron": "^17.2.0",
+		"electron": "^19.1.8",
 		"file-loader": "^6.2.0",
 		"glob": "^7.2.0",
 		"html-webpack-plugin": "^5.5.0",
@@ -25,5 +25,8 @@
 		"webpack-dev-server": "^4.7.4",
 		"webpack": "^5.68.0",
 		"yaserver": "^0.4.0"
+	},
+	"overrides": {
+		"@electron/get": "2.0.0"
 	}
 }

+ 34 - 0
scripts/ci/monaco-editor-core.sh

@@ -0,0 +1,34 @@
+#!/bin/bash
+set -e
+
+# cwd must be the vscode repository.
+
+yarn --frozen-lockfile --network-timeout 180000
+yarn playwright-install
+yarn gulp hygiene
+yarn valid-layers-check
+yarn --cwd build compile
+yarn eslint
+yarn monaco-compile-check
+yarn --max_old_space_size=4095 compile
+
+yarn test-browser --browser chromium
+
+yarn gulp editor-distro
+mkdir typings-test
+
+cd typings-test
+yarn init -yp
+../node_modules/.bin/tsc --init
+echo "import '../out-monaco-editor-core';" > a.ts
+../node_modules/.bin/tsc --noEmit
+cd ..
+
+cd test/monaco
+yarn run esm-check
+yarn run bundle-webpack
+yarn run compile
+yarn test
+cd ../..
+
+# npm package is now in dependencies/vscode/out-monaco-editor-core, ready to be published

+ 33 - 0
scripts/ci/monaco-editor.sh

@@ -0,0 +1,33 @@
+#!/bin/bash
+set -e
+
+# execute `npm install` to pick up local monaco-editor-core
+npm install
+# Install OS Dependencies for Playwright
+sudo npm run playwright-install-deps
+# Check prettier
+npm run prettier-check
+# Build
+npm run release
+
+# Run unit tests
+npm test
+
+# Compile webpack plugin
+npm run compile --prefix webpack-plugin
+# Package using webpack plugin
+npm run package-for-smoketest-webpack
+# Package using esbuild
+npm run package-for-smoketest-esbuild
+# Package using vite
+npm run package-for-smoketest-vite
+# Package using parcel
+npm run package-for-smoketest-parcel --prefix test/smoke/parcel
+
+# Run smoke test
+npm run smoketest
+
+# Build website
+npm run build-website
+
+# npm package is now ready to be published in ./release

+ 67 - 0
scripts/ci/prepare-monaco-editor-core.ts

@@ -0,0 +1,67 @@
+import { mkdir, rm } from 'fs/promises';
+import { join, resolve } from 'path';
+import { group, gitShallowClone, run, writeJsonFile, getNightlyVersion } from '../lib';
+
+const selfPath = __dirname;
+const rootPath = join(selfPath, '..', '..');
+const dependenciesPath = join(rootPath, 'dependencies');
+const vscodePath = resolve(dependenciesPath, 'vscode');
+const monacoEditorPackageJsonPath = resolve(rootPath, 'package.json');
+
+async function prepareMonacoEditorCoreReleaseStableOrNightly() {
+	const monacoEditorPackageJson = require(monacoEditorPackageJsonPath) as {
+		version: string;
+		vscodeRef: string;
+	};
+	let version: string;
+	let ref: string;
+
+	const arg = process.argv[2];
+	if (arg === 'stable') {
+		version = monacoEditorPackageJson.version;
+		ref = monacoEditorPackageJson.vscodeRef;
+	} else if (arg === 'nightly') {
+		version = getNightlyVersion(monacoEditorPackageJson.version);
+		ref = 'main';
+	} else {
+		throw new Error('Invalid argument');
+	}
+
+	await prepareMonacoEditorCoreRelease(version, ref);
+
+	// npm package is now in dependencies/vscode/out-monaco-editor-core, ready to be published
+}
+
+async function prepareMonacoEditorCoreRelease(version: string, vscodeRef: string) {
+	await mkdir(vscodePath, { recursive: true });
+
+	await rm(dependenciesPath, { force: true, recursive: true });
+
+	await group('Checkout vscode', async () => {
+		await gitShallowClone(vscodePath, 'https://github.com/microsoft/vscode.git', vscodeRef);
+	});
+	await group('Checkout vscode-loc', async () => {
+		await gitShallowClone(
+			// Must be a sibling to the vscode repository
+			'dependencies/vscode-loc',
+			'https://github.com/microsoft/vscode-loc.git',
+			'main'
+		);
+	});
+
+	await group('Set Version', async () => {
+		const monacoEditorCorePackageJsonSourcePath = resolve(
+			vscodePath,
+			'./build/monaco/package.json'
+		);
+		const packageJson = require(monacoEditorCorePackageJsonSourcePath) as { version: string };
+		packageJson.version = version;
+		await writeJsonFile(monacoEditorCorePackageJsonSourcePath, packageJson);
+	});
+
+	await group('Building & Testing', async () => {
+		await run(resolve(selfPath, './monaco-editor-core.sh'), { cwd: vscodePath });
+	});
+}
+
+prepareMonacoEditorCoreReleaseStableOrNightly();

+ 50 - 0
scripts/ci/prepare-monaco-editor.ts

@@ -0,0 +1,50 @@
+import { readFile } from 'fs/promises';
+import { join, resolve } from 'path';
+import { getNightlyVersion, group, run, writeJsonFile } from '../lib';
+
+const selfPath = __dirname;
+const rootPath = join(selfPath, '..', '..');
+const monacoEditorPackageJsonPath = resolve(rootPath, 'package.json');
+
+async function prepareMonacoEditorReleaseStableOrNightly() {
+	const monacoEditorPackageJson = JSON.parse(
+		await readFile(monacoEditorPackageJsonPath, { encoding: 'utf-8' })
+	) as { version: string };
+
+	let version: string;
+
+	const arg = process.argv[2];
+	if (arg === 'stable') {
+		version = monacoEditorPackageJson.version;
+	} else if (arg === 'nightly') {
+		version = getNightlyVersion(monacoEditorPackageJson.version);
+	} else {
+		throw new Error('Invalid argument');
+	}
+
+	await prepareMonacoEditorRelease(version);
+
+	// npm package is now in ./release, ready to be published
+}
+
+async function prepareMonacoEditorRelease(version: string) {
+	await group('npm ci', async () => {
+		await run('npm ci', { cwd: resolve(rootPath, 'webpack-plugin') });
+	});
+
+	await group('Set Version', async () => {
+		const packageJson = JSON.parse(
+			await readFile(monacoEditorPackageJsonPath, { encoding: 'utf-8' })
+		) as { version: string; devDependencies: Record<string, string> };
+		packageJson.version = version;
+		packageJson.devDependencies['monaco-editor-core'] = version;
+
+		await writeJsonFile(monacoEditorPackageJsonPath, packageJson);
+	});
+
+	await group('Building & Testing', async () => {
+		await run(resolve(selfPath, './monaco-editor.sh'), { cwd: rootPath });
+	});
+}
+
+prepareMonacoEditorReleaseStableOrNightly();

+ 55 - 0
scripts/lib/index.ts

@@ -0,0 +1,55 @@
+import { spawn } from 'child_process';
+import { mkdir, writeFile } from 'fs/promises';
+
+export interface RunOptions {
+	cwd: string;
+}
+
+export async function run(command: string, options: RunOptions) {
+	console.log(`Running ${command} in ${options.cwd}`);
+	const process = spawn(command, { shell: true, cwd: options.cwd, stdio: 'inherit' });
+	return new Promise<void>((resolve, reject) => {
+		process.on('exit', (code) => {
+			if (code !== 0) {
+				reject(new Error(`Command ${command} exited with code ${code}`));
+			} else {
+				resolve();
+			}
+		});
+	});
+}
+
+export async function gitShallowClone(targetPath: string, repositoryUrl: string, ref: string) {
+	await mkdir(targetPath, { recursive: true });
+	const options: RunOptions = { cwd: targetPath };
+	await run('git init', options);
+	await run(`git remote add origin ${repositoryUrl}`, options);
+	await run(`git fetch --depth 1 origin ${ref}`, options);
+	await run(`git checkout ${ref}`, options);
+}
+
+export async function group(name: string, body: () => Promise<void>): Promise<void> {
+	console.log(`##[group]${name}`);
+	try {
+		await body();
+	} catch (e) {
+		console.error(e);
+		throw e;
+	} finally {
+		console.log('##[endgroup]');
+	}
+}
+
+export async function writeJsonFile(filePath: string, jsonData: unknown): Promise<void> {
+	await writeFile(filePath, JSON.stringify(jsonData, null, '\t') + '\n');
+}
+
+export function getNightlyVersion(version: string): string {
+	const pieces = version.split('.');
+	const minor = parseInt(pieces[1], 10);
+	const date = new Date();
+	const yyyy = date.getUTCFullYear();
+	const mm = String(date.getUTCMonth() + 1).padStart(2, '0');
+	const dd = String(date.getUTCDate()).padStart(2, '0');
+	return `0.${minor + 1}.0-dev.${yyyy}${mm}${dd}`;
+}

+ 1 - 1
src/basic-languages/cpp/cpp.ts

@@ -272,7 +272,7 @@ export const language = <languages.IMonarchLanguage>{
 
 	// we include these common regular expressions
 	symbols: /[=><!~?:&|+\-*\/\^%]+/,
-	escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
+	escapes: /\\(?:[0abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
 	integersuffix: /([uU](ll|LL|l|L)|(ll|LL|l|L)?[uU]?)/,
 	floatsuffix: /[fFlL]?/,
 	encoding: /u|u8|U|L/,

+ 27 - 0
src/basic-languages/elixir/elixir.test.ts

@@ -383,5 +383,32 @@ testTokenization('elixir', [
 				{ startIndex: 15, type: 'delimiter.square.elixir' }
 			]
 		}
+	],
+	// Bitstrings
+	[
+		{
+			line: '<<height::32-integer, width::32-integer, data::binary>>',
+			tokens: [
+				{ startIndex: 0, type: 'delimiter.angle.special.elixir' },
+				{ startIndex: 2, type: 'identifier.elixir' },
+				{ startIndex: 8, type: 'operator.elixir' },
+				{ startIndex: 10, type: 'number.elixir' },
+				{ startIndex: 12, type: 'operator.elixir' },
+				{ startIndex: 13, type: 'identifier.elixir' },
+				{ startIndex: 20, type: 'punctuation.elixir' },
+				{ startIndex: 21, type: 'white.elixir' },
+				{ startIndex: 22, type: 'identifier.elixir' },
+				{ startIndex: 27, type: 'operator.elixir' },
+				{ startIndex: 29, type: 'number.elixir' },
+				{ startIndex: 31, type: 'operator.elixir' },
+				{ startIndex: 32, type: 'identifier.elixir' },
+				{ startIndex: 39, type: 'punctuation.elixir' },
+				{ startIndex: 40, type: 'white.elixir' },
+				{ startIndex: 41, type: 'identifier.elixir' },
+				{ startIndex: 45, type: 'operator.elixir' },
+				{ startIndex: 47, type: 'identifier.elixir' },
+				{ startIndex: 53, type: 'delimiter.angle.special.elixir' }
+			]
+		}
 	]
 ]);

+ 25 - 1
src/basic-languages/elixir/elixir.ts

@@ -167,7 +167,7 @@ export const language = <languages.IMonarchLanguage>{
 		// Keyword list shorthand
 
 		keywordsShorthand: [
-			[/(@atomName)(:)/, ['constant', 'constant.punctuation']],
+			[/(@atomName)(:)(\s+)/, ['constant', 'constant.punctuation', 'white']],
 			// Use positive look-ahead to ensure the string is followed by :
 			// and should be considered a keyword.
 			[
@@ -532,6 +532,13 @@ export const language = <languages.IMonarchLanguage>{
 					next: '@doubleQuotedHeredocDocstring'
 				}
 			],
+			[
+				/\@(module|type)?doc (~[sS])?'''/,
+				{
+					token: 'comment.block.documentation',
+					next: '@singleQuotedHeredocDocstring'
+				}
+			],
 			[
 				/\@(module|type)?doc (~[sS])?"/,
 				{
@@ -539,6 +546,13 @@ export const language = <languages.IMonarchLanguage>{
 					next: '@doubleQuotedStringDocstring'
 				}
 			],
+			[
+				/\@(module|type)?doc (~[sS])?'/,
+				{
+					token: 'comment.block.documentation',
+					next: '@singleQuotedStringDocstring'
+				}
+			],
 			[/\@(module|type)?doc false/, 'comment.block.documentation'],
 			// Module attributes
 			[/\@(@variableName)/, 'variable']
@@ -549,11 +563,21 @@ export const language = <languages.IMonarchLanguage>{
 			{ include: '@docstringContent' }
 		],
 
+		singleQuotedHeredocDocstring: [
+			[/'''/, { token: 'comment.block.documentation', next: '@pop' }],
+			{ include: '@docstringContent' }
+		],
+
 		doubleQuotedStringDocstring: [
 			[/"/, { token: 'comment.block.documentation', next: '@pop' }],
 			{ include: '@docstringContent' }
 		],
 
+		singleQuotedStringDocstring: [
+			[/'/, { token: 'comment.block.documentation', next: '@pop' }],
+			{ include: '@docstringContent' }
+		],
+
 		// Operators, punctuation, brackets
 
 		symbols: [

+ 1 - 1
src/basic-languages/kotlin/kotlin.contribution.ts

@@ -10,7 +10,7 @@ declare var require: any;
 
 registerLanguage({
 	id: 'kotlin',
-	extensions: ['.kt'],
+	extensions: ['.kt', '.kts'],
 	aliases: ['Kotlin', 'kotlin'],
 	mimetypes: ['text/x-kotlin-source', 'text/x-kotlin'],
 	loader: () => {

+ 4 - 0
src/basic-languages/pgsql/pgsql.ts

@@ -627,11 +627,15 @@ export const language = <languages.IMonarchLanguage>{
 		'range_intersect_agg',
 		'range_merge',
 		'rank',
+		'regexp_count',
+		'regexp_instr',
+		'regexp_like',
 		'regexp_match',
 		'regexp_matches',
 		'regexp_replace',
 		'regexp_split_to_array',
 		'regexp_split_to_table',
+		'regexp_substr',
 		'regr_avgx',
 		'regr_avgy',
 		'regr_count',

+ 1 - 0
src/basic-languages/typescript/typescript.ts

@@ -137,6 +137,7 @@ export const language = {
 		'require',
 		'global',
 		'return',
+		'satisfies',
 		'set',
 		'static',
 		'string',

+ 2 - 0
src/basic-languages/xml/xml.contribution.ts

@@ -16,6 +16,8 @@ registerLanguage({
 		'.ascx',
 		'.csproj',
 		'.config',
+		'.props',
+		'.targets',
 		'.wxi',
 		'.wxl',
 		'.wxs',

+ 603 - 18
src/language/typescript/lib/typescriptServices-amd.js

@@ -1,6 +1,11 @@
 //
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
+
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation. All rights reserved.
 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
@@ -2554,9 +2559,7 @@ var ts;
             return true;
         }
         function fail(message, stackCrawlMark) {
-            // MONACOCHANGE
-            // debugger;
-            // END MONACOCHANGE
+            debugger;
             var e = new Error(message ? "Debug Failure. ".concat(message) : "Debug Failure.");
             if (Error.captureStackTrace) {
                 Error.captureStackTrace(e, stackCrawlMark || fail);
@@ -3058,9 +3061,7 @@ var ts;
             try {
                 if (ts.sys && ts.sys.require) {
                     var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
-                    // MONACOCHANGE
-                    var result = undefined;
-                    // END MONACOCHANGE
+                    var result = ts.sys.require(basePath, "./compiler-debug");
                     if (!result.error) {
                         result.module.init(ts);
                         extendedDebugModule = result.module;
@@ -3512,10 +3513,10 @@ var ts;
         }
     }
     function tryGetNodePerformanceHooks() {
-        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && /* MONACOCHANGE */false/* END MONACOCHANGE */) {
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && typeof require === "function") {
             try {
                 var performance_1;
-                var _a /* MONACOCHANGE */= {}/* END MONACOCHANGE */, nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
+                var _a = require("perf_hooks"), nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
                 if (hasRequiredAPI(nodePerformance_1, PerformanceObserver_1)) {
                     performance_1 = nodePerformance_1;
                     // There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not
@@ -3746,9 +3747,7 @@ var ts;
         var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
         // require() will throw an exception if the module is not found
         // It may also return undefined if not installed properly
-        // MONACOCHANGE
-        etwModule = undefined;
-        // END MONACOCHANGE
+        etwModule = require(etwModulePath);
     }
     catch (e) {
         etwModule = undefined;
@@ -3777,9 +3776,7 @@ var ts;
             ts.Debug.assert(!ts.tracing, "Tracing already started");
             if (fs === undefined) {
                 try {
-                    // MONACOCHANGE
-                    fs = undefined;
-                    // END MONACOCHANGE
+                    fs = require("fs");
                 }
                 catch (e) {
                     throw new Error("tracing requires having fs\n(original error: ".concat(e.message || e, ")"));
@@ -7463,9 +7460,596 @@ var ts;
     ts.getNodeMajorVersion = getNodeMajorVersion;
     // TODO: GH#18217 this is used as if it's certainly defined in many places.
     // eslint-disable-next-line prefer-const
-    // MONACOCHANGE
-    ts.sys = undefined;
-    // END MONACOCHANGE
+    ts.sys = (function () {
+        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
+        // byte order mark from the specified encoding. Using any other byte order mark does
+        // not actually work.
+        var byteOrderMarkIndicator = "\uFEFF";
+        function getNodeSystem() {
+            var _a;
+            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
+            var _fs = require("fs");
+            var _path = require("path");
+            var _os = require("os");
+            // crypto can be absent on reduced node installations
+            var _crypto;
+            try {
+                _crypto = require("crypto");
+            }
+            catch (_b) {
+                _crypto = undefined;
+            }
+            var activeSession;
+            var profilePath = "./profile.cpuprofile";
+            var hitSystemWatcherLimit = false;
+            var Buffer = require("buffer").Buffer;
+            var nodeVersion = getNodeMajorVersion();
+            var isNode4OrLater = nodeVersion >= 4;
+            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
+            var platform = _os.platform();
+            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
+            var realpathSync = (_a = _fs.realpathSync.native) !== null && _a !== void 0 ? _a : _fs.realpathSync;
+            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
+            var getCurrentDirectory = ts.memoize(function () { return process.cwd(); });
+            var _c = createSystemWatchFunctions({
+                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
+                getModifiedTime: getModifiedTime,
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                fsWatch: fsWatch,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                getCurrentDirectory: getCurrentDirectory,
+                fileExists: fileExists,
+                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
+                directoryExists: directoryExists,
+                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
+                realpath: realpath,
+                tscWatchFile: process.env.TSC_WATCHFILE,
+                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
+                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
+                defaultWatchFileKind: function () { var _a, _b; return (_b = (_a = sys).defaultWatchFileKind) === null || _b === void 0 ? void 0 : _b.call(_a); },
+            }), watchFile = _c.watchFile, watchDirectory = _c.watchDirectory;
+            var nodeSystem = {
+                args: process.argv.slice(2),
+                newLine: _os.EOL,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                write: function (s) {
+                    process.stdout.write(s);
+                },
+                getWidthOfTerminal: function () {
+                    return process.stdout.columns;
+                },
+                writeOutputIsTTY: function () {
+                    return process.stdout.isTTY;
+                },
+                readFile: readFile,
+                writeFile: writeFile,
+                watchFile: watchFile,
+                watchDirectory: watchDirectory,
+                resolvePath: function (path) { return _path.resolve(path); },
+                fileExists: fileExists,
+                directoryExists: directoryExists,
+                createDirectory: function (directoryName) {
+                    if (!nodeSystem.directoryExists(directoryName)) {
+                        // Wrapped in a try-catch to prevent crashing if we are in a race
+                        // with another copy of ourselves to create the same directory
+                        try {
+                            _fs.mkdirSync(directoryName);
+                        }
+                        catch (e) {
+                            if (e.code !== "EEXIST") {
+                                // Failed for some other reason (access denied?); still throw
+                                throw e;
+                            }
+                        }
+                    }
+                },
+                getExecutingFilePath: function () {
+                    return __filename;
+                },
+                getCurrentDirectory: getCurrentDirectory,
+                getDirectories: getDirectories,
+                getEnvironmentVariable: function (name) {
+                    return process.env[name] || "";
+                },
+                readDirectory: readDirectory,
+                getModifiedTime: getModifiedTime,
+                setModifiedTime: setModifiedTime,
+                deleteFile: deleteFile,
+                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
+                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
+                getMemoryUsage: function () {
+                    if (global.gc) {
+                        global.gc();
+                    }
+                    return process.memoryUsage().heapUsed;
+                },
+                getFileSize: function (path) {
+                    try {
+                        var stat = statSync(path);
+                        if (stat === null || stat === void 0 ? void 0 : stat.isFile()) {
+                            return stat.size;
+                        }
+                    }
+                    catch ( /*ignore*/_a) { /*ignore*/ }
+                    return 0;
+                },
+                exit: function (exitCode) {
+                    disableCPUProfiler(function () { return process.exit(exitCode); });
+                },
+                enableCPUProfiler: enableCPUProfiler,
+                disableCPUProfiler: disableCPUProfiler,
+                cpuProfilingEnabled: function () { return !!activeSession || ts.contains(process.execArgv, "--cpu-prof") || ts.contains(process.execArgv, "--prof"); },
+                realpath: realpath,
+                debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
+                tryEnableSourceMapsForHost: function () {
+                    try {
+                        require("source-map-support").install();
+                    }
+                    catch (_a) {
+                        // Could not enable source maps.
+                    }
+                },
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                clearScreen: function () {
+                    process.stdout.write("\x1Bc");
+                },
+                setBlocking: function () {
+                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
+                        process.stdout._handle.setBlocking(true);
+                    }
+                },
+                bufferFrom: bufferFrom,
+                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
+                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
+                require: function (baseDir, moduleName) {
+                    try {
+                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
+                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
+                    }
+                    catch (error) {
+                        return { module: undefined, modulePath: undefined, error: error };
+                    }
+                }
+            };
+            return nodeSystem;
+            /**
+             * `throwIfNoEntry` was added so recently that it's not in the node types.
+             * This helper encapsulates the mitigating usage of `any`.
+             * See https://github.com/nodejs/node/pull/33716
+             */
+            function statSync(path) {
+                // throwIfNoEntry will be ignored by older versions of node
+                return _fs.statSync(path, { throwIfNoEntry: false });
+            }
+            /**
+             * Uses the builtin inspector APIs to capture a CPU profile
+             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
+             */
+            function enableCPUProfiler(path, cb) {
+                if (activeSession) {
+                    cb();
+                    return false;
+                }
+                var inspector = require("inspector");
+                if (!inspector || !inspector.Session) {
+                    cb();
+                    return false;
+                }
+                var session = new inspector.Session();
+                session.connect();
+                session.post("Profiler.enable", function () {
+                    session.post("Profiler.start", function () {
+                        activeSession = session;
+                        profilePath = path;
+                        cb();
+                    });
+                });
+                return true;
+            }
+            /**
+             * Strips non-TS paths from the profile, so users with private projects shouldn't
+             * need to worry about leaking paths by submitting a cpu profile to us
+             */
+            function cleanupPaths(profile) {
+                var externalFileCounter = 0;
+                var remappedPaths = new ts.Map();
+                var normalizedDir = ts.normalizeSlashes(__dirname);
+                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
+                var fileUrlRoot = "file://".concat(ts.getRootLength(normalizedDir) === 1 ? "" : "/").concat(normalizedDir);
+                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    if (node.callFrame.url) {
+                        var url = ts.normalizeSlashes(node.callFrame.url);
+                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
+                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
+                        }
+                        else if (!nativePattern.test(url)) {
+                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external".concat(externalFileCounter, ".js"))).get(url);
+                            externalFileCounter++;
+                        }
+                    }
+                }
+                return profile;
+            }
+            function disableCPUProfiler(cb) {
+                if (activeSession && activeSession !== "stopping") {
+                    var s_1 = activeSession;
+                    activeSession.post("Profiler.stop", function (err, _a) {
+                        var _b;
+                        var profile = _a.profile;
+                        if (!err) {
+                            try {
+                                if ((_b = statSync(profilePath)) === null || _b === void 0 ? void 0 : _b.isDirectory()) {
+                                    profilePath = _path.join(profilePath, "".concat((new Date()).toISOString().replace(/:/g, "-"), "+P").concat(process.pid, ".cpuprofile"));
+                                }
+                            }
+                            catch (_c) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            try {
+                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
+                            }
+                            catch (_d) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
+                        }
+                        activeSession = undefined;
+                        s_1.disconnect();
+                        cb();
+                    });
+                    activeSession = "stopping";
+                    return true;
+                }
+                else {
+                    cb();
+                    return false;
+                }
+            }
+            function bufferFrom(input, encoding) {
+                // See https://github.com/Microsoft/TypeScript/issues/25652
+                return Buffer.from && Buffer.from !== Int8Array.from
+                    ? Buffer.from(input, encoding)
+                    : new Buffer(input, encoding);
+            }
+            function isFileSystemCaseSensitive() {
+                // win32\win64 are case insensitive platforms
+                if (platform === "win32" || platform === "win64") {
+                    return false;
+                }
+                // If this file exists under a different case, we must be case-insensitve.
+                return !fileExists(swapCase(__filename));
+            }
+            /** Convert all lowercase chars to uppercase, and vice-versa */
+            function swapCase(s) {
+                return s.replace(/\w/g, function (ch) {
+                    var up = ch.toUpperCase();
+                    return ch === up ? ch.toLowerCase() : up;
+                });
+            }
+            function fsWatchFileWorker(fileName, callback, pollingInterval) {
+                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
+                var eventKind;
+                return {
+                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
+                };
+                function fileChanged(curr, prev) {
+                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
+                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
+                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
+                    if (+curr.mtime === 0) {
+                        if (isPreviouslyDeleted) {
+                            // Already deleted file, no need to callback again
+                            return;
+                        }
+                        eventKind = FileWatcherEventKind.Deleted;
+                    }
+                    else if (isPreviouslyDeleted) {
+                        eventKind = FileWatcherEventKind.Created;
+                    }
+                    // If there is no change in modified time, ignore the event
+                    else if (+curr.mtime === +prev.mtime) {
+                        return;
+                    }
+                    else {
+                        // File changed
+                        eventKind = FileWatcherEventKind.Changed;
+                    }
+                    callback(fileName, eventKind);
+                }
+            }
+            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
+                var options;
+                var lastDirectoryPartWithDirectorySeparator;
+                var lastDirectoryPart;
+                if (isLinuxOrMacOs) {
+                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
+                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
+                }
+                /** Watcher for the file system entry depending on whether it is missing or present */
+                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                    watchMissingFileSystemEntry() :
+                    watchPresentFileSystemEntry();
+                return {
+                    close: function () {
+                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
+                        watcher.close();
+                        watcher = undefined;
+                    }
+                };
+                /**
+                 * Invoke the callback with rename and update the watcher if not closed
+                 * @param createWatcher
+                 */
+                function invokeCallbackAndUpdateWatcher(createWatcher) {
+                    ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing watcher to ").concat(createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing", "FileSystemEntryWatcher"));
+                    // Call the callback for current directory
+                    callback("rename", "");
+                    // If watcher is not closed, update it
+                    if (watcher) {
+                        watcher.close();
+                        watcher = createWatcher();
+                    }
+                }
+                /**
+                 * Watch the file or directory that is currently present
+                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
+                 */
+                function watchPresentFileSystemEntry() {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    if (options === undefined) {
+                        if (fsSupportsRecursiveFsWatch) {
+                            options = { persistent: true, recursive: !!recursive };
+                        }
+                        else {
+                            options = { persistent: true };
+                        }
+                    }
+                    if (hitSystemWatcherLimit) {
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Defaulting to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                    try {
+                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
+                            callbackChangingToMissingFileSystemEntry :
+                            callback);
+                        // Watch the missing file or directory or error
+                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
+                        return presentWatcher;
+                    }
+                    catch (e) {
+                        // Catch the exception and use polling instead
+                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                        // so instead of throwing error, use fs.watchFile
+                        hitSystemWatcherLimit || (hitSystemWatcherLimit = e.code === "ENOSPC");
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                }
+                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
+                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
+                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
+                    return event === "rename" &&
+                        (!relativeName ||
+                            relativeName === lastDirectoryPart ||
+                            (relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) !== -1 && relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length)) &&
+                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
+                        callback(event, relativeName);
+                }
+                /**
+                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
+                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                 */
+                function watchPresentFileSystemEntryWithFsWatchFile() {
+                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
+                }
+                /**
+                 * Watch the file or directory that is missing
+                 * and switch to existing file or directory when the missing filesystem entry is created
+                 */
+                function watchMissingFileSystemEntry() {
+                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
+                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
+                            // Call the callback for current file or directory
+                            // For now it could be callback for the inner directory creation,
+                            // but just return current directory, better than current no-op
+                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
+                        }
+                    }, fallbackPollingInterval, fallbackOptions);
+                }
+            }
+            function readFileWorker(fileName, _encoding) {
+                var buffer;
+                try {
+                    buffer = _fs.readFileSync(fileName);
+                }
+                catch (e) {
+                    return undefined;
+                }
+                var len = buffer.length;
+                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
+                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
+                    // flip all byte pairs and treat as little endian.
+                    len &= ~1; // Round down to a multiple of 2
+                    for (var i = 0; i < len; i += 2) {
+                        var temp = buffer[i];
+                        buffer[i] = buffer[i + 1];
+                        buffer[i + 1] = temp;
+                    }
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
+                    // Little endian UTF-16 byte order mark detected
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
+                    // UTF-8 byte order mark detected
+                    return buffer.toString("utf8", 3);
+                }
+                // Default is UTF-8 with no byte order mark
+                return buffer.toString("utf8");
+            }
+            function readFile(fileName, _encoding) {
+                ts.perfLogger.logStartReadFile(fileName);
+                var file = readFileWorker(fileName, _encoding);
+                ts.perfLogger.logStopReadFile();
+                return file;
+            }
+            function writeFile(fileName, data, writeByteOrderMark) {
+                ts.perfLogger.logEvent("WriteFile: " + fileName);
+                // If a BOM is required, emit one
+                if (writeByteOrderMark) {
+                    data = byteOrderMarkIndicator + data;
+                }
+                var fd;
+                try {
+                    fd = _fs.openSync(fileName, "w");
+                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
+                }
+                finally {
+                    if (fd !== undefined) {
+                        _fs.closeSync(fd);
+                    }
+                }
+            }
+            function getAccessibleFileSystemEntries(path) {
+                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
+                try {
+                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
+                    var files = [];
+                    var directories = [];
+                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                        var dirent = entries_1[_i];
+                        // withFileTypes is not supported before Node 10.10.
+                        var entry = typeof dirent === "string" ? dirent : dirent.name;
+                        // This is necessary because on some file system node fails to exclude
+                        // "." and "..". See https://github.com/nodejs/node/issues/4002
+                        if (entry === "." || entry === "..") {
+                            continue;
+                        }
+                        var stat = void 0;
+                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
+                            var name = ts.combinePaths(path, entry);
+                            try {
+                                stat = statSync(name);
+                                if (!stat) {
+                                    continue;
+                                }
+                            }
+                            catch (e) {
+                                continue;
+                            }
+                        }
+                        else {
+                            stat = dirent;
+                        }
+                        if (stat.isFile()) {
+                            files.push(entry);
+                        }
+                        else if (stat.isDirectory()) {
+                            directories.push(entry);
+                        }
+                    }
+                    files.sort();
+                    directories.sort();
+                    return { files: files, directories: directories };
+                }
+                catch (e) {
+                    return ts.emptyFileSystemEntries;
+                }
+            }
+            function readDirectory(path, extensions, excludes, includes, depth) {
+                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
+            }
+            function fileSystemEntryExists(path, entryKind) {
+                // Since the error thrown by fs.statSync isn't used, we can avoid collecting a stack trace to improve
+                // the CPU time performance.
+                var originalStackTraceLimit = Error.stackTraceLimit;
+                Error.stackTraceLimit = 0;
+                try {
+                    var stat = statSync(path);
+                    if (!stat) {
+                        return false;
+                    }
+                    switch (entryKind) {
+                        case 0 /* File */: return stat.isFile();
+                        case 1 /* Directory */: return stat.isDirectory();
+                        default: return false;
+                    }
+                }
+                catch (e) {
+                    return false;
+                }
+                finally {
+                    Error.stackTraceLimit = originalStackTraceLimit;
+                }
+            }
+            function fileExists(path) {
+                return fileSystemEntryExists(path, 0 /* File */);
+            }
+            function directoryExists(path) {
+                return fileSystemEntryExists(path, 1 /* Directory */);
+            }
+            function getDirectories(path) {
+                return getAccessibleFileSystemEntries(path).directories.slice();
+            }
+            function realpath(path) {
+                try {
+                    return realpathSync(path);
+                }
+                catch (_a) {
+                    return path;
+                }
+            }
+            function getModifiedTime(path) {
+                var _a;
+                try {
+                    return (_a = statSync(path)) === null || _a === void 0 ? void 0 : _a.mtime;
+                }
+                catch (e) {
+                    return undefined;
+                }
+            }
+            function setModifiedTime(path, time) {
+                try {
+                    _fs.utimesSync(path, time, time);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function deleteFile(path) {
+                try {
+                    return _fs.unlinkSync(path);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function createSHA256Hash(data) {
+                var hash = _crypto.createHash("sha256");
+                hash.update(data);
+                return hash.digest("hex");
+            }
+        }
+        var sys;
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
+            // process and process.nextTick checks if current environment is node-like
+            // process.browser check excludes webpack and browserify
+            sys = getNodeSystem();
+        }
+        if (sys) {
+            // patch writefile to create folder before writing the file
+            patchWriteFileEnsuringDirectory(sys);
+        }
+        return sys;
+    })();
     /*@internal*/
     function setSys(s) {
         ts.sys = s;
@@ -162604,7 +163188,7 @@ if (typeof process === "undefined" || process.browser) {
     globalThis.toolsVersion = ts.versionMajorMinor;
 }
 if (typeof module !== "undefined" && module.exports) {
-    /* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */
+    module.exports = ts;
 }
 var ts;
 (function (ts) {
@@ -163529,6 +164113,7 @@ var ts;
 
 
 
+
 // MONACOCHANGE
 // Defining the entire module name because r.js has an issue and cannot bundle this file
 // correctly with an anonymous define call

+ 1 - 3
src/language/typescript/lib/typescriptServices.d.ts

@@ -7594,6 +7594,4 @@ declare namespace ts {
     const isIdentifierOrPrivateIdentifier: (node: Node) => node is MemberName;
 }
 
-// MONACOCHANGE
-export = ts;
-// END MONACOCHANGE
+export = ts;

+ 609 - 24
src/language/typescript/lib/typescriptServices.js

@@ -1,6 +1,11 @@
 //
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
+
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation. All rights reserved.
 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
@@ -17,7 +22,7 @@ and limitations under the License.
 ***************************************************************************** */
 
 "use strict";
-var __spreadArray = function (to, from, pack) {
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
     if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
         if (ar || !(i in from)) {
             if (!ar) ar = Array.prototype.slice.call(from, 0, i);
@@ -26,7 +31,7 @@ var __spreadArray = function (to, from, pack) {
     }
     return to.concat(ar || Array.prototype.slice.call(from));
 };
-var __assign = function () {
+var __assign = (this && this.__assign) || function () {
     __assign = Object.assign || function(t) {
         for (var s, i = 1, n = arguments.length; i < n; i++) {
             s = arguments[i];
@@ -37,11 +42,11 @@ var __assign = function () {
     };
     return __assign.apply(this, arguments);
 };
-var __makeTemplateObject = function (cooked, raw) {
+var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
     if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
     return cooked;
 };
-var __generator = function (thisArg, body) {
+var __generator = (this && this.__generator) || function (thisArg, body) {
     var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
     return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
     function verb(n) { return function (v) { return step([n, v]); }; }
@@ -68,7 +73,7 @@ var __generator = function (thisArg, body) {
         if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
     }
 };
-var __rest = function (s, e) {
+var __rest = (this && this.__rest) || function (s, e) {
     var t = {};
     for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
         t[p] = s[p];
@@ -79,7 +84,7 @@ var __rest = function (s, e) {
         }
     return t;
 };
-var __extends = (function () {
+var __extends = (this && this.__extends) || (function () {
     var extendStatics = function (d, b) {
         extendStatics = Object.setPrototypeOf ||
             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
@@ -2554,9 +2559,7 @@ var ts;
             return true;
         }
         function fail(message, stackCrawlMark) {
-            // MONACOCHANGE
-            // debugger;
-            // END MONACOCHANGE
+            debugger;
             var e = new Error(message ? "Debug Failure. ".concat(message) : "Debug Failure.");
             if (Error.captureStackTrace) {
                 Error.captureStackTrace(e, stackCrawlMark || fail);
@@ -3058,9 +3061,7 @@ var ts;
             try {
                 if (ts.sys && ts.sys.require) {
                     var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
-                    // MONACOCHANGE
-                    var result = undefined;
-                    // END MONACOCHANGE
+                    var result = ts.sys.require(basePath, "./compiler-debug");
                     if (!result.error) {
                         result.module.init(ts);
                         extendedDebugModule = result.module;
@@ -3512,10 +3513,10 @@ var ts;
         }
     }
     function tryGetNodePerformanceHooks() {
-        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && /* MONACOCHANGE */false/* END MONACOCHANGE */) {
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && typeof require === "function") {
             try {
                 var performance_1;
-                var _a /* MONACOCHANGE */= {}/* END MONACOCHANGE */, nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
+                var _a = require("perf_hooks"), nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
                 if (hasRequiredAPI(nodePerformance_1, PerformanceObserver_1)) {
                     performance_1 = nodePerformance_1;
                     // There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not
@@ -3746,9 +3747,7 @@ var ts;
         var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
         // require() will throw an exception if the module is not found
         // It may also return undefined if not installed properly
-        // MONACOCHANGE
-        etwModule = undefined;
-        // END MONACOCHANGE
+        etwModule = require(etwModulePath);
     }
     catch (e) {
         etwModule = undefined;
@@ -3777,9 +3776,7 @@ var ts;
             ts.Debug.assert(!ts.tracing, "Tracing already started");
             if (fs === undefined) {
                 try {
-                    // MONACOCHANGE
-                    fs = undefined;
-                    // END MONACOCHANGE
+                    fs = require("fs");
                 }
                 catch (e) {
                     throw new Error("tracing requires having fs\n(original error: ".concat(e.message || e, ")"));
@@ -7463,9 +7460,596 @@ var ts;
     ts.getNodeMajorVersion = getNodeMajorVersion;
     // TODO: GH#18217 this is used as if it's certainly defined in many places.
     // eslint-disable-next-line prefer-const
-    // MONACOCHANGE
-    ts.sys = undefined;
-    // END MONACOCHANGE
+    ts.sys = (function () {
+        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
+        // byte order mark from the specified encoding. Using any other byte order mark does
+        // not actually work.
+        var byteOrderMarkIndicator = "\uFEFF";
+        function getNodeSystem() {
+            var _a;
+            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
+            var _fs = require("fs");
+            var _path = require("path");
+            var _os = require("os");
+            // crypto can be absent on reduced node installations
+            var _crypto;
+            try {
+                _crypto = require("crypto");
+            }
+            catch (_b) {
+                _crypto = undefined;
+            }
+            var activeSession;
+            var profilePath = "./profile.cpuprofile";
+            var hitSystemWatcherLimit = false;
+            var Buffer = require("buffer").Buffer;
+            var nodeVersion = getNodeMajorVersion();
+            var isNode4OrLater = nodeVersion >= 4;
+            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
+            var platform = _os.platform();
+            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
+            var realpathSync = (_a = _fs.realpathSync.native) !== null && _a !== void 0 ? _a : _fs.realpathSync;
+            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
+            var getCurrentDirectory = ts.memoize(function () { return process.cwd(); });
+            var _c = createSystemWatchFunctions({
+                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
+                getModifiedTime: getModifiedTime,
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                fsWatch: fsWatch,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                getCurrentDirectory: getCurrentDirectory,
+                fileExists: fileExists,
+                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
+                directoryExists: directoryExists,
+                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
+                realpath: realpath,
+                tscWatchFile: process.env.TSC_WATCHFILE,
+                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
+                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
+                defaultWatchFileKind: function () { var _a, _b; return (_b = (_a = sys).defaultWatchFileKind) === null || _b === void 0 ? void 0 : _b.call(_a); },
+            }), watchFile = _c.watchFile, watchDirectory = _c.watchDirectory;
+            var nodeSystem = {
+                args: process.argv.slice(2),
+                newLine: _os.EOL,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                write: function (s) {
+                    process.stdout.write(s);
+                },
+                getWidthOfTerminal: function () {
+                    return process.stdout.columns;
+                },
+                writeOutputIsTTY: function () {
+                    return process.stdout.isTTY;
+                },
+                readFile: readFile,
+                writeFile: writeFile,
+                watchFile: watchFile,
+                watchDirectory: watchDirectory,
+                resolvePath: function (path) { return _path.resolve(path); },
+                fileExists: fileExists,
+                directoryExists: directoryExists,
+                createDirectory: function (directoryName) {
+                    if (!nodeSystem.directoryExists(directoryName)) {
+                        // Wrapped in a try-catch to prevent crashing if we are in a race
+                        // with another copy of ourselves to create the same directory
+                        try {
+                            _fs.mkdirSync(directoryName);
+                        }
+                        catch (e) {
+                            if (e.code !== "EEXIST") {
+                                // Failed for some other reason (access denied?); still throw
+                                throw e;
+                            }
+                        }
+                    }
+                },
+                getExecutingFilePath: function () {
+                    return __filename;
+                },
+                getCurrentDirectory: getCurrentDirectory,
+                getDirectories: getDirectories,
+                getEnvironmentVariable: function (name) {
+                    return process.env[name] || "";
+                },
+                readDirectory: readDirectory,
+                getModifiedTime: getModifiedTime,
+                setModifiedTime: setModifiedTime,
+                deleteFile: deleteFile,
+                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
+                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
+                getMemoryUsage: function () {
+                    if (global.gc) {
+                        global.gc();
+                    }
+                    return process.memoryUsage().heapUsed;
+                },
+                getFileSize: function (path) {
+                    try {
+                        var stat = statSync(path);
+                        if (stat === null || stat === void 0 ? void 0 : stat.isFile()) {
+                            return stat.size;
+                        }
+                    }
+                    catch ( /*ignore*/_a) { /*ignore*/ }
+                    return 0;
+                },
+                exit: function (exitCode) {
+                    disableCPUProfiler(function () { return process.exit(exitCode); });
+                },
+                enableCPUProfiler: enableCPUProfiler,
+                disableCPUProfiler: disableCPUProfiler,
+                cpuProfilingEnabled: function () { return !!activeSession || ts.contains(process.execArgv, "--cpu-prof") || ts.contains(process.execArgv, "--prof"); },
+                realpath: realpath,
+                debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
+                tryEnableSourceMapsForHost: function () {
+                    try {
+                        require("source-map-support").install();
+                    }
+                    catch (_a) {
+                        // Could not enable source maps.
+                    }
+                },
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                clearScreen: function () {
+                    process.stdout.write("\x1Bc");
+                },
+                setBlocking: function () {
+                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
+                        process.stdout._handle.setBlocking(true);
+                    }
+                },
+                bufferFrom: bufferFrom,
+                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
+                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
+                require: function (baseDir, moduleName) {
+                    try {
+                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
+                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
+                    }
+                    catch (error) {
+                        return { module: undefined, modulePath: undefined, error: error };
+                    }
+                }
+            };
+            return nodeSystem;
+            /**
+             * `throwIfNoEntry` was added so recently that it's not in the node types.
+             * This helper encapsulates the mitigating usage of `any`.
+             * See https://github.com/nodejs/node/pull/33716
+             */
+            function statSync(path) {
+                // throwIfNoEntry will be ignored by older versions of node
+                return _fs.statSync(path, { throwIfNoEntry: false });
+            }
+            /**
+             * Uses the builtin inspector APIs to capture a CPU profile
+             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
+             */
+            function enableCPUProfiler(path, cb) {
+                if (activeSession) {
+                    cb();
+                    return false;
+                }
+                var inspector = require("inspector");
+                if (!inspector || !inspector.Session) {
+                    cb();
+                    return false;
+                }
+                var session = new inspector.Session();
+                session.connect();
+                session.post("Profiler.enable", function () {
+                    session.post("Profiler.start", function () {
+                        activeSession = session;
+                        profilePath = path;
+                        cb();
+                    });
+                });
+                return true;
+            }
+            /**
+             * Strips non-TS paths from the profile, so users with private projects shouldn't
+             * need to worry about leaking paths by submitting a cpu profile to us
+             */
+            function cleanupPaths(profile) {
+                var externalFileCounter = 0;
+                var remappedPaths = new ts.Map();
+                var normalizedDir = ts.normalizeSlashes(__dirname);
+                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
+                var fileUrlRoot = "file://".concat(ts.getRootLength(normalizedDir) === 1 ? "" : "/").concat(normalizedDir);
+                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    if (node.callFrame.url) {
+                        var url = ts.normalizeSlashes(node.callFrame.url);
+                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
+                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
+                        }
+                        else if (!nativePattern.test(url)) {
+                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external".concat(externalFileCounter, ".js"))).get(url);
+                            externalFileCounter++;
+                        }
+                    }
+                }
+                return profile;
+            }
+            function disableCPUProfiler(cb) {
+                if (activeSession && activeSession !== "stopping") {
+                    var s_1 = activeSession;
+                    activeSession.post("Profiler.stop", function (err, _a) {
+                        var _b;
+                        var profile = _a.profile;
+                        if (!err) {
+                            try {
+                                if ((_b = statSync(profilePath)) === null || _b === void 0 ? void 0 : _b.isDirectory()) {
+                                    profilePath = _path.join(profilePath, "".concat((new Date()).toISOString().replace(/:/g, "-"), "+P").concat(process.pid, ".cpuprofile"));
+                                }
+                            }
+                            catch (_c) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            try {
+                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
+                            }
+                            catch (_d) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
+                        }
+                        activeSession = undefined;
+                        s_1.disconnect();
+                        cb();
+                    });
+                    activeSession = "stopping";
+                    return true;
+                }
+                else {
+                    cb();
+                    return false;
+                }
+            }
+            function bufferFrom(input, encoding) {
+                // See https://github.com/Microsoft/TypeScript/issues/25652
+                return Buffer.from && Buffer.from !== Int8Array.from
+                    ? Buffer.from(input, encoding)
+                    : new Buffer(input, encoding);
+            }
+            function isFileSystemCaseSensitive() {
+                // win32\win64 are case insensitive platforms
+                if (platform === "win32" || platform === "win64") {
+                    return false;
+                }
+                // If this file exists under a different case, we must be case-insensitve.
+                return !fileExists(swapCase(__filename));
+            }
+            /** Convert all lowercase chars to uppercase, and vice-versa */
+            function swapCase(s) {
+                return s.replace(/\w/g, function (ch) {
+                    var up = ch.toUpperCase();
+                    return ch === up ? ch.toLowerCase() : up;
+                });
+            }
+            function fsWatchFileWorker(fileName, callback, pollingInterval) {
+                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
+                var eventKind;
+                return {
+                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
+                };
+                function fileChanged(curr, prev) {
+                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
+                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
+                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
+                    if (+curr.mtime === 0) {
+                        if (isPreviouslyDeleted) {
+                            // Already deleted file, no need to callback again
+                            return;
+                        }
+                        eventKind = FileWatcherEventKind.Deleted;
+                    }
+                    else if (isPreviouslyDeleted) {
+                        eventKind = FileWatcherEventKind.Created;
+                    }
+                    // If there is no change in modified time, ignore the event
+                    else if (+curr.mtime === +prev.mtime) {
+                        return;
+                    }
+                    else {
+                        // File changed
+                        eventKind = FileWatcherEventKind.Changed;
+                    }
+                    callback(fileName, eventKind);
+                }
+            }
+            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
+                var options;
+                var lastDirectoryPartWithDirectorySeparator;
+                var lastDirectoryPart;
+                if (isLinuxOrMacOs) {
+                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
+                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
+                }
+                /** Watcher for the file system entry depending on whether it is missing or present */
+                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                    watchMissingFileSystemEntry() :
+                    watchPresentFileSystemEntry();
+                return {
+                    close: function () {
+                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
+                        watcher.close();
+                        watcher = undefined;
+                    }
+                };
+                /**
+                 * Invoke the callback with rename and update the watcher if not closed
+                 * @param createWatcher
+                 */
+                function invokeCallbackAndUpdateWatcher(createWatcher) {
+                    ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing watcher to ").concat(createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing", "FileSystemEntryWatcher"));
+                    // Call the callback for current directory
+                    callback("rename", "");
+                    // If watcher is not closed, update it
+                    if (watcher) {
+                        watcher.close();
+                        watcher = createWatcher();
+                    }
+                }
+                /**
+                 * Watch the file or directory that is currently present
+                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
+                 */
+                function watchPresentFileSystemEntry() {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    if (options === undefined) {
+                        if (fsSupportsRecursiveFsWatch) {
+                            options = { persistent: true, recursive: !!recursive };
+                        }
+                        else {
+                            options = { persistent: true };
+                        }
+                    }
+                    if (hitSystemWatcherLimit) {
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Defaulting to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                    try {
+                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
+                            callbackChangingToMissingFileSystemEntry :
+                            callback);
+                        // Watch the missing file or directory or error
+                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
+                        return presentWatcher;
+                    }
+                    catch (e) {
+                        // Catch the exception and use polling instead
+                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                        // so instead of throwing error, use fs.watchFile
+                        hitSystemWatcherLimit || (hitSystemWatcherLimit = e.code === "ENOSPC");
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                }
+                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
+                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
+                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
+                    return event === "rename" &&
+                        (!relativeName ||
+                            relativeName === lastDirectoryPart ||
+                            (relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) !== -1 && relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length)) &&
+                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
+                        callback(event, relativeName);
+                }
+                /**
+                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
+                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                 */
+                function watchPresentFileSystemEntryWithFsWatchFile() {
+                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
+                }
+                /**
+                 * Watch the file or directory that is missing
+                 * and switch to existing file or directory when the missing filesystem entry is created
+                 */
+                function watchMissingFileSystemEntry() {
+                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
+                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
+                            // Call the callback for current file or directory
+                            // For now it could be callback for the inner directory creation,
+                            // but just return current directory, better than current no-op
+                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
+                        }
+                    }, fallbackPollingInterval, fallbackOptions);
+                }
+            }
+            function readFileWorker(fileName, _encoding) {
+                var buffer;
+                try {
+                    buffer = _fs.readFileSync(fileName);
+                }
+                catch (e) {
+                    return undefined;
+                }
+                var len = buffer.length;
+                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
+                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
+                    // flip all byte pairs and treat as little endian.
+                    len &= ~1; // Round down to a multiple of 2
+                    for (var i = 0; i < len; i += 2) {
+                        var temp = buffer[i];
+                        buffer[i] = buffer[i + 1];
+                        buffer[i + 1] = temp;
+                    }
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
+                    // Little endian UTF-16 byte order mark detected
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
+                    // UTF-8 byte order mark detected
+                    return buffer.toString("utf8", 3);
+                }
+                // Default is UTF-8 with no byte order mark
+                return buffer.toString("utf8");
+            }
+            function readFile(fileName, _encoding) {
+                ts.perfLogger.logStartReadFile(fileName);
+                var file = readFileWorker(fileName, _encoding);
+                ts.perfLogger.logStopReadFile();
+                return file;
+            }
+            function writeFile(fileName, data, writeByteOrderMark) {
+                ts.perfLogger.logEvent("WriteFile: " + fileName);
+                // If a BOM is required, emit one
+                if (writeByteOrderMark) {
+                    data = byteOrderMarkIndicator + data;
+                }
+                var fd;
+                try {
+                    fd = _fs.openSync(fileName, "w");
+                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
+                }
+                finally {
+                    if (fd !== undefined) {
+                        _fs.closeSync(fd);
+                    }
+                }
+            }
+            function getAccessibleFileSystemEntries(path) {
+                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
+                try {
+                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
+                    var files = [];
+                    var directories = [];
+                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                        var dirent = entries_1[_i];
+                        // withFileTypes is not supported before Node 10.10.
+                        var entry = typeof dirent === "string" ? dirent : dirent.name;
+                        // This is necessary because on some file system node fails to exclude
+                        // "." and "..". See https://github.com/nodejs/node/issues/4002
+                        if (entry === "." || entry === "..") {
+                            continue;
+                        }
+                        var stat = void 0;
+                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
+                            var name = ts.combinePaths(path, entry);
+                            try {
+                                stat = statSync(name);
+                                if (!stat) {
+                                    continue;
+                                }
+                            }
+                            catch (e) {
+                                continue;
+                            }
+                        }
+                        else {
+                            stat = dirent;
+                        }
+                        if (stat.isFile()) {
+                            files.push(entry);
+                        }
+                        else if (stat.isDirectory()) {
+                            directories.push(entry);
+                        }
+                    }
+                    files.sort();
+                    directories.sort();
+                    return { files: files, directories: directories };
+                }
+                catch (e) {
+                    return ts.emptyFileSystemEntries;
+                }
+            }
+            function readDirectory(path, extensions, excludes, includes, depth) {
+                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
+            }
+            function fileSystemEntryExists(path, entryKind) {
+                // Since the error thrown by fs.statSync isn't used, we can avoid collecting a stack trace to improve
+                // the CPU time performance.
+                var originalStackTraceLimit = Error.stackTraceLimit;
+                Error.stackTraceLimit = 0;
+                try {
+                    var stat = statSync(path);
+                    if (!stat) {
+                        return false;
+                    }
+                    switch (entryKind) {
+                        case 0 /* File */: return stat.isFile();
+                        case 1 /* Directory */: return stat.isDirectory();
+                        default: return false;
+                    }
+                }
+                catch (e) {
+                    return false;
+                }
+                finally {
+                    Error.stackTraceLimit = originalStackTraceLimit;
+                }
+            }
+            function fileExists(path) {
+                return fileSystemEntryExists(path, 0 /* File */);
+            }
+            function directoryExists(path) {
+                return fileSystemEntryExists(path, 1 /* Directory */);
+            }
+            function getDirectories(path) {
+                return getAccessibleFileSystemEntries(path).directories.slice();
+            }
+            function realpath(path) {
+                try {
+                    return realpathSync(path);
+                }
+                catch (_a) {
+                    return path;
+                }
+            }
+            function getModifiedTime(path) {
+                var _a;
+                try {
+                    return (_a = statSync(path)) === null || _a === void 0 ? void 0 : _a.mtime;
+                }
+                catch (e) {
+                    return undefined;
+                }
+            }
+            function setModifiedTime(path, time) {
+                try {
+                    _fs.utimesSync(path, time, time);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function deleteFile(path) {
+                try {
+                    return _fs.unlinkSync(path);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function createSHA256Hash(data) {
+                var hash = _crypto.createHash("sha256");
+                hash.update(data);
+                return hash.digest("hex");
+            }
+        }
+        var sys;
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
+            // process and process.nextTick checks if current environment is node-like
+            // process.browser check excludes webpack and browserify
+            sys = getNodeSystem();
+        }
+        if (sys) {
+            // patch writefile to create folder before writing the file
+            patchWriteFileEnsuringDirectory(sys);
+        }
+        return sys;
+    })();
     /*@internal*/
     function setSys(s) {
         ts.sys = s;
@@ -162604,7 +163188,7 @@ if (typeof process === "undefined" || process.browser) {
     globalThis.toolsVersion = ts.versionMajorMinor;
 }
 if (typeof module !== "undefined" && module.exports) {
-    /* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */
+    module.exports = ts;
 }
 var ts;
 (function (ts) {
@@ -163529,6 +164113,7 @@ var ts;
 
 
 
+
 // MONACOCHANGE
 export var createClassifier = ts.createClassifier;
 export var createLanguageService = ts.createLanguageService;

+ 103 - 3
src/language/typescript/monaco.contribution.ts

@@ -226,6 +226,73 @@ interface OutputFile {
 	text: string;
 }
 
+export interface ModeConfiguration {
+	/**
+	 * Defines whether the built-in completionItemProvider is enabled.
+	 */
+	readonly completionItems?: boolean;
+
+	/**
+	 * Defines whether the built-in hoverProvider is enabled.
+	 */
+	readonly hovers?: boolean;
+
+	/**
+	 * Defines whether the built-in documentSymbolProvider is enabled.
+	 */
+	readonly documentSymbols?: boolean;
+
+	/**
+	 * Defines whether the built-in definitions provider is enabled.
+	 */
+	readonly definitions?: boolean;
+
+	/**
+	 * Defines whether the built-in references provider is enabled.
+	 */
+	readonly references?: boolean;
+
+	/**
+	 * Defines whether the built-in references provider is enabled.
+	 */
+	readonly documentHighlights?: boolean;
+
+	/**
+	 * Defines whether the built-in rename provider is enabled.
+	 */
+	readonly rename?: boolean;
+
+	/**
+	 * Defines whether the built-in diagnostic provider is enabled.
+	 */
+	readonly diagnostics?: boolean;
+
+	/**
+	 * Defines whether the built-in document formatting range edit provider is enabled.
+	 */
+	readonly documentRangeFormattingEdits?: boolean;
+
+	/**
+	 * Defines whether the built-in signature help provider is enabled.
+	 */
+	readonly signatureHelp?: boolean;
+
+	/**
+	 * Defines whether the built-in onType formatting edit provider is enabled.
+	 */
+	readonly onTypeFormattingEdits?: boolean;
+
+	/**
+	 * Defines whether the built-in code actions provider is enabled.
+	 */
+	readonly codeActions?: boolean;
+
+	/**
+	 * Defines whether the built-in inlay hints provider is enabled.
+	 */
+	readonly inlayHints?: boolean;
+}
+
 export interface LanguageServiceDefaults {
 	/**
 	 * Event fired when compiler options or diagnostics options are changed.
@@ -241,6 +308,9 @@ export interface LanguageServiceDefaults {
 
 	readonly inlayHintsOptions: InlayHintsOptions;
 
+	readonly modeConfiguration: ModeConfiguration;
+	setModeConfiguration(modeConfiguration: ModeConfiguration): void;
+
 	/**
 	 * Get the current extra libs registered with the language service.
 	 */
@@ -491,12 +561,14 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 	private _workerOptions!: WorkerOptions;
 	private _onDidExtraLibsChangeTimeout: number;
 	private _inlayHintsOptions!: InlayHintsOptions;
+	private _modeConfiguration!: ModeConfiguration;
 
 	constructor(
 		compilerOptions: CompilerOptions,
 		diagnosticsOptions: DiagnosticsOptions,
 		workerOptions: WorkerOptions,
-		inlayHintsOptions: InlayHintsOptions
+		inlayHintsOptions: InlayHintsOptions,
+		modeConfiguration: ModeConfiguration
 	) {
 		this._extraLibs = Object.create(null);
 		this._removedExtraLibs = Object.create(null);
@@ -505,6 +577,7 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 		this.setDiagnosticsOptions(diagnosticsOptions);
 		this.setWorkerOptions(workerOptions);
 		this.setInlayHintsOptions(inlayHintsOptions);
+		this.setModeConfiguration(modeConfiguration);
 		this._onDidExtraLibsChangeTimeout = -1;
 	}
 
@@ -516,6 +589,10 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 		return this._onDidExtraLibsChange.event;
 	}
 
+	get modeConfiguration(): ModeConfiguration {
+		return this._modeConfiguration;
+	}
+
 	get workerOptions(): WorkerOptions {
 		return this._workerOptions;
 	}
@@ -650,22 +727,45 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 	getEagerModelSync() {
 		return this._eagerModelSync;
 	}
+
+	setModeConfiguration(modeConfiguration: ModeConfiguration): void {
+		this._modeConfiguration = modeConfiguration || Object.create(null);
+		this._onDidChange.fire(undefined);
+	}
 }
 
 export const typescriptVersion: string = tsversion;
 
+const modeConfigurationDefault: Required<ModeConfiguration> = {
+	completionItems: true,
+	hovers: true,
+	documentSymbols: true,
+	definitions: true,
+	references: true,
+	documentHighlights: true,
+	rename: true,
+	diagnostics: true,
+	documentRangeFormattingEdits: true,
+	signatureHelp: true,
+	onTypeFormattingEdits: true,
+	codeActions: true,
+	inlayHints: true
+};
+
 export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
 	{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
 	{ noSemanticValidation: false, noSyntaxValidation: false, onlyVisible: false },
 	{},
-	{}
+	{},
+	modeConfigurationDefault
 );
 
 export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
 	{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
 	{ noSemanticValidation: true, noSyntaxValidation: false, onlyVisible: false },
 	{},
-	{}
+	{},
+	modeConfigurationDefault
 );
 
 export const getTypeScriptWorker = (): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> => {

+ 119 - 32
src/language/typescript/tsMode.ts

@@ -7,7 +7,7 @@ import { WorkerManager } from './workerManager';
 import type { TypeScriptWorker } from './tsWorker';
 import { LanguageServiceDefaults } from './monaco.contribution';
 import * as languageFeatures from './languageFeatures';
-import { languages, Uri } from '../../fillers/monaco-editor-core';
+import { languages, IDisposable, Uri } from '../../fillers/monaco-editor-core';
 
 let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
 let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
@@ -44,46 +44,133 @@ function setupMode(
 	defaults: LanguageServiceDefaults,
 	modeId: string
 ): (...uris: Uri[]) => Promise<TypeScriptWorker> {
+	const disposables: IDisposable[] = [];
+	const providers: IDisposable[] = [];
+
 	const client = new WorkerManager(modeId, defaults);
+	disposables.push(client);
+
 	const worker = (...uris: Uri[]): Promise<TypeScriptWorker> => {
 		return client.getLanguageServiceWorker(...uris);
 	};
 
 	const libFiles = new languageFeatures.LibFiles(worker);
 
-	languages.registerCompletionItemProvider(modeId, new languageFeatures.SuggestAdapter(worker));
-	languages.registerSignatureHelpProvider(
-		modeId,
-		new languageFeatures.SignatureHelpAdapter(worker)
-	);
-	languages.registerHoverProvider(modeId, new languageFeatures.QuickInfoAdapter(worker));
-	languages.registerDocumentHighlightProvider(
-		modeId,
-		new languageFeatures.OccurrencesAdapter(worker)
-	);
-	languages.registerDefinitionProvider(
-		modeId,
-		new languageFeatures.DefinitionAdapter(libFiles, worker)
-	);
-	languages.registerReferenceProvider(
-		modeId,
-		new languageFeatures.ReferenceAdapter(libFiles, worker)
-	);
-	languages.registerDocumentSymbolProvider(modeId, new languageFeatures.OutlineAdapter(worker));
-	languages.registerDocumentRangeFormattingEditProvider(
-		modeId,
-		new languageFeatures.FormatAdapter(worker)
-	);
-	languages.registerOnTypeFormattingEditProvider(
-		modeId,
-		new languageFeatures.FormatOnTypeAdapter(worker)
-	);
-	languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
-	languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(libFiles, worker));
-	languages.registerInlayHintsProvider(modeId, new languageFeatures.InlayHintsAdapter(worker));
-	new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker);
+	function registerProviders(): void {
+		const { modeConfiguration } = defaults;
+
+		disposeAll(providers);
+
+		if (modeConfiguration.completionItems) {
+			providers.push(
+				languages.registerCompletionItemProvider(
+					modeId,
+					new languageFeatures.SuggestAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.signatureHelp) {
+			providers.push(
+				languages.registerSignatureHelpProvider(
+					modeId,
+					new languageFeatures.SignatureHelpAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.hovers) {
+			providers.push(
+				languages.registerHoverProvider(modeId, new languageFeatures.QuickInfoAdapter(worker))
+			);
+		}
+		if (modeConfiguration.documentHighlights) {
+			providers.push(
+				languages.registerDocumentHighlightProvider(
+					modeId,
+					new languageFeatures.OccurrencesAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.definitions) {
+			providers.push(
+				languages.registerDefinitionProvider(
+					modeId,
+					new languageFeatures.DefinitionAdapter(libFiles, worker)
+				)
+			);
+		}
+		if (modeConfiguration.references) {
+			providers.push(
+				languages.registerReferenceProvider(
+					modeId,
+					new languageFeatures.ReferenceAdapter(libFiles, worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentSymbols) {
+			providers.push(
+				languages.registerDocumentSymbolProvider(
+					modeId,
+					new languageFeatures.OutlineAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.rename) {
+			providers.push(
+				languages.registerRenameProvider(
+					modeId,
+					new languageFeatures.RenameAdapter(libFiles, worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentRangeFormattingEdits) {
+			providers.push(
+				languages.registerDocumentRangeFormattingEditProvider(
+					modeId,
+					new languageFeatures.FormatAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.onTypeFormattingEdits) {
+			providers.push(
+				languages.registerOnTypeFormattingEditProvider(
+					modeId,
+					new languageFeatures.FormatOnTypeAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.codeActions) {
+			providers.push(
+				languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker))
+			);
+		}
+		if (modeConfiguration.inlayHints) {
+			providers.push(
+				languages.registerInlayHintsProvider(modeId, new languageFeatures.InlayHintsAdapter(worker))
+			);
+		}
+		if (modeConfiguration.diagnostics) {
+			providers.push(new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker));
+		}
+	}
+
+	registerProviders();
+
+	disposables.push(asDisposable(providers));
+
+	//return asDisposable(disposables);
+
 	return worker;
 }
 
+function asDisposable(disposables: IDisposable[]): IDisposable {
+	return { dispose: () => disposeAll(disposables) };
+}
+
+function disposeAll(disposables: IDisposable[]) {
+	while (disposables.length) {
+		disposables.pop()!.dispose();
+	}
+}
+
 export { WorkerManager } from './workerManager';
 export * from './languageFeatures';

+ 2 - 2
src/language/typescript/tsWorker.ts

@@ -63,7 +63,7 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
 
 	getScriptFileNames(): string[] {
 		const allModels = this._ctx.getMirrorModels().map((model) => model.uri);
-		const models = allModels.filter((uri) => !fileNameIsLib(uri)).map((uri) => uri.toString(true));
+		const models = allModels.filter((uri) => !fileNameIsLib(uri)).map((uri) => uri.toString());
 		return models.concat(Object.keys(this._extraLibs));
 	}
 
@@ -487,7 +487,7 @@ export function create(ctx: worker.IWorkerContext, createData: ICreateData): Typ
 				'Monaco is not using webworkers for background tasks, and that is needed to support the customWorkerPath flag'
 			);
 		} else {
-			importScripts(createData.customWorkerPath);
+			self.importScripts(createData.customWorkerPath);
 
 			const workerFactoryFunc: CustomTSWebWorkerFactory | undefined = self.customTSWorkerFactory;
 			if (!workerFactoryFunc) {

+ 2 - 2
test/smoke/amd.html → test/smoke/amd/index.html

@@ -5,11 +5,11 @@
 	</head>
 	<body>
 		<div id="editor-container" style="position: absolute; width: 500px; height: 400px"></div>
-		<script src="../../release/dev/vs/loader.js"></script>
+		<script src="../../../release/dev/vs/loader.js"></script>
 		<script>
 			require.config({
 				paths: {
-					vs: '../../release/dev/vs'
+					vs: '../../../release/dev/vs'
 				}
 			});
 			require(['vs/editor/editor.main'], () => {

+ 6 - 1
test/smoke/common.js

@@ -3,4 +3,9 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-exports.PORT = 8563;
+/* keeping TS happy */
+exports.__nothing = undefined;
+
+/** @typedef {'chromium'|'firefox'|'webkit'} BrowserKind */
+/** @typedef {'amd'|'webpack'|'esbuild'|'vite'|'parcel'} PackagerKind */
+/** @typedef {{browser:BrowserKind; packager:PackagerKind; debugTests:boolean; port:number;}} TestInfo */

+ 0 - 0
test/smoke/esbuild/esbuild.html → test/smoke/esbuild/index.html


+ 5 - 0
test/smoke/esbuild/index.js

@@ -1,3 +1,8 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
 import * as monaco from '../../../release/esm/vs/editor/editor.main.js';
 
 self.MonacoEnvironment = {

+ 1 - 1
test/smoke/package-esbuild.ts

@@ -7,7 +7,7 @@ import * as esbuild from 'esbuild';
 import * as path from 'path';
 import { removeDir } from '../../build/fs';
 
-removeDir('test/smoke/esbuild/out', (entry) => /esbuild.html$/.test(entry));
+removeDir('test/smoke/esbuild/out');
 
 const workerEntryPoints = [
 	'vs/language/json/json.worker.js',

+ 19 - 0
test/smoke/package-vite.ts

@@ -0,0 +1,19 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as vite from 'vite';
+import * as path from 'path';
+
+async function main() {
+	await vite.build({
+		root: path.resolve(__dirname, './vite/'),
+		base: '/test/smoke/vite/dist/',
+		build: {
+			minify: false
+		}
+	});
+}
+
+main();

+ 56 - 0
test/smoke/package-webpack.ts

@@ -0,0 +1,56 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import webpack from 'webpack';
+import MonacoWebpackPlugin from '../../webpack-plugin/out/index.js';
+import * as path from 'path';
+
+const REPO_ROOT = path.join(__dirname, '../../');
+const CROSS_ORIGIN_ASSETS = process.argv.includes('--cross-origin');
+
+webpack(
+	{
+		mode: 'development',
+		entry: './index.js',
+		context: path.join(__dirname, 'webpack'),
+		output: {
+			path: path.resolve(REPO_ROOT, 'test/smoke/webpack/out'),
+			filename: 'app.js',
+			publicPath: CROSS_ORIGIN_ASSETS
+				? 'http://localhost:8088/monaco-editor/test/smoke/webpack/out/'
+				: undefined
+		},
+		resolve: {
+			alias: {
+				'monaco-editor': path.resolve(REPO_ROOT, 'release')
+			}
+		},
+		module: {
+			rules: [
+				{
+					test: /\.css$/,
+					use: ['style-loader', 'css-loader']
+				},
+				{
+					test: /\.ttf$/,
+					use: ['file-loader']
+				}
+			]
+		},
+		plugins: [<any>new MonacoWebpackPlugin({
+				monacoEditorPath: path.resolve(REPO_ROOT, 'release')
+			})]
+	},
+	(err: Error | undefined, stats: webpack.Stats | undefined) => {
+		if (err) {
+			console.error(err);
+			process.exit(1);
+		}
+		if (stats && stats.hasErrors()) {
+			console.log(stats.compilation.errors);
+			process.exit(1);
+		}
+	}
+);

+ 11 - 0
test/smoke/parcel/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+	</head>
+	<body>
+		<div id="editor-container" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
+
+		<script type="module" src="index.js"></script>
+	</body>
+</html>

+ 35 - 0
test/smoke/parcel/index.js

@@ -0,0 +1,35 @@
+import * as monaco from '../../../release/esm/vs/editor/editor.main.js';
+
+self.MonacoEnvironment = {
+	getWorker: function (moduleId, label) {
+		if (label === 'json') {
+			return new Worker(
+				new URL('../../../release/esm/vs/language/json/json.worker.js', import.meta.url),
+				{ type: 'module' }
+			);
+		}
+		if (label === 'css' || label === 'scss' || label === 'less') {
+			return new Worker(
+				new URL('../../../release/esm/vs/language/css/css.worker.js', import.meta.url),
+				{ type: 'module' }
+			);
+		}
+		if (label === 'html' || label === 'handlebars' || label === 'razor') {
+			return new Worker(
+				new URL('../../../release/esm/vs/language/html/html.worker.js', import.meta.url),
+				{ type: 'module' }
+			);
+		}
+		if (label === 'typescript' || label === 'javascript') {
+			return new Worker(
+				new URL('../../../release/esm/vs/language/typescript/ts.worker.js', import.meta.url),
+				{ type: 'module' }
+			);
+		}
+		return new Worker(new URL('../../../release/esm/vs/editor/editor.worker.js', import.meta.url), {
+			type: 'module'
+		});
+	}
+};
+
+window.monacoAPI = monaco;

+ 6 - 0
test/smoke/parcel/package.json

@@ -0,0 +1,6 @@
+{
+	"name": "parcel-smoketest",
+	"scripts": {
+		"package-for-smoketest-parcel": "parcel build ./index.html --cache-dir ./.cache --public-url /test/smoke/parcel/dist/ --no-optimize"
+	}
+}

+ 22 - 12
test/smoke/runner.js

@@ -9,10 +9,14 @@ const yaserver = require('yaserver');
 const http = require('http');
 const cp = require('child_process');
 const path = require('path');
-const { PORT } = require('./common');
-const DEBUG_TESTS = process.argv.includes('--debug-tests');
 
+/** @typedef {import('./common').BrowserKind} BrowserKind */
+/** @typedef {import('./common').PackagerKind} PackagerKind */
+/** @typedef {import('./common').TestInfo} TestInfo */
+
+const DEBUG_TESTS = process.argv.includes('--debug-tests');
 const REPO_ROOT = path.join(__dirname, '../../');
+const PORT = 8563;
 
 yaserver
 	.createServer({
@@ -37,25 +41,31 @@ yaserver
 async function runTests() {
 	// uncomment to shortcircuit and run a specific combo
 	// await runTest('webpack', 'chromium'); return;
+	/** @type {PackagerKind[]} */
+	const testTypes = ['amd', 'webpack', 'esbuild', 'vite', 'parcel'];
 
-	for (const type of ['amd', 'webpack' /*, 'esbuild'*/]) {
+	for (const type of testTypes) {
 		await runTest(type, 'chromium');
 		await runTest(type, 'firefox');
-		// await runTest(type, 'webkit');
+		await runTest(type, 'webkit');
 	}
 }
 
 /**
- * @param {string} type
- * @param {'chromium'|'firefox'|'webkit'} browser
+ * @param {PackagerKind} packager
+ * @param {BrowserKind} browser
  * @returns
  */
-function runTest(type, browser) {
+function runTest(packager, browser) {
 	return new Promise((resolve, reject) => {
-		const env = { BROWSER: browser, TESTS_TYPE: type, ...process.env };
-		if (DEBUG_TESTS) {
-			env['DEBUG_TESTS'] = 'true';
-		}
+		/** @type TestInfo */
+		const testInfo = {
+			browser,
+			packager,
+			debugTests: DEBUG_TESTS,
+			port: PORT
+		};
+		const env = { MONACO_TEST_INFO: JSON.stringify(testInfo), ...process.env };
 		const proc = cp.spawn(
 			'node',
 			[
@@ -74,7 +84,7 @@ function runTest(type, browser) {
 		proc.on('error', reject);
 		proc.on('exit', (code) => {
 			if (code === 0) {
-				resolve();
+				resolve(undefined);
 			} else {
 				reject(code);
 			}

+ 64 - 41
test/smoke/smoke.test.js

@@ -7,20 +7,24 @@
 
 const playwright = require('playwright');
 const { assert } = require('chai');
-const { PORT } = require('./common');
 
-const browserType = process.env.BROWSER || 'chromium';
-const DEBUG_TESTS = Boolean(process.env.DEBUG_TESTS || false);
-const TESTS_TYPE = process.env.TESTS_TYPE || 'amd';
+/** @typedef {import('./common').BrowserKind} BrowserKind */
+/** @typedef {import('./common').PackagerKind} PackagerKind */
+/** @typedef {import('./common').TestInfo} TestInfo */
 
-const URL =
-	TESTS_TYPE === 'amd'
-		? `http://127.0.0.1:${PORT}/test/smoke/amd.html`
-		: TESTS_TYPE === 'webpack'
-		? `http://127.0.0.1:${PORT}/test/smoke/webpack/webpack.html`
-		: `http://127.0.0.1:${PORT}/test/smoke/esbuild/esbuild.html`;
+/** @type TestInfo */
+const testInfo = JSON.parse(process.env.MONACO_TEST_INFO || '');
 
-suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
+const URLS = {
+	amd: `http://127.0.0.1:${testInfo.port}/test/smoke/amd/index.html`,
+	webpack: `http://127.0.0.1:${testInfo.port}/test/smoke/webpack/index.html`,
+	esbuild: `http://127.0.0.1:${testInfo.port}/test/smoke/esbuild/index.html`,
+	vite: `http://127.0.0.1:${testInfo.port}/test/smoke/vite/dist/index.html`,
+	parcel: `http://127.0.0.1:${testInfo.port}/test/smoke/parcel/dist/index.html`
+};
+const URL = URLS[testInfo.packager];
+
+suite(`Smoke Test '${testInfo.packager}' on '${testInfo.browser}'`, () => {
 	/** @type {playwright.Browser} */
 	let browser;
 
@@ -28,10 +32,10 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 	let page;
 
 	suiteSetup(async () => {
-		browser = await playwright[browserType].launch({
-			headless: !DEBUG_TESTS,
-			devtools: DEBUG_TESTS && browserType === 'chromium'
-			// slowMo: DEBUG_TESTS ? 2000 : 0
+		browser = await playwright[testInfo.browser].launch({
+			headless: !testInfo.debugTests,
+			devtools: testInfo.debugTests && testInfo.browser === 'chromium'
+			// slowMo: testInfo.debugTests ? 2000 : 0
 		});
 	});
 
@@ -54,7 +58,9 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 			pageErrors.push(e);
 		});
 		const response = await page.goto(URL);
-		assert.ok(!!response);
+		if (!response) {
+			assert.fail('Failed to load page');
+		}
 		assert.strictEqual(response.status(), 200);
 	});
 
@@ -89,7 +95,7 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 
 	/**
 	 * @param {string} commandId
-	 * @param {any} args
+	 * @param {any} [args]
 	 * @returns Promise<void>
 	 */
 	async function triggerEditorCommand(commandId, args) {
@@ -102,11 +108,11 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 		await page.evaluate(`window.ed.focus();`);
 	}
 
-	test('`monacoAPI` is exposed as global', async () => {
+	test('`monacoAPI` is exposed as global', async function () {
 		assert.strictEqual(await page.evaluate(`typeof monacoAPI`), 'object');
 	});
 
-	test('should be able to create plaintext editor', async () => {
+	test('should be able to create plaintext editor', async function () {
 		await createEditor('hello world', 'plaintext');
 
 		// type a link in it
@@ -117,45 +123,60 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 		await page.waitForSelector('.detected-link');
 	});
 
-	test('css smoke test', async () => {
+	test('css smoke test', async function () {
 		await createEditor('.sel1 { background: red; }\\n.sel2 {}', 'css');
 
 		// check that a squiggle appears, which indicates that the language service is up and running
 		await page.waitForSelector('.squiggly-warning');
 	});
 
-	test('html smoke test', async () => {
+	test('html smoke test', async function () {
 		await createEditor('<title>hi</title>', 'html');
 
-		// trigger hover
-		await focusEditor();
-		await setEditorPosition(1, 3);
-		await page.keyboard.press('F1');
-		await page.keyboard.type('Show Hover');
-		await page.keyboard.press('Enter');
-
-		// check that a hover explaining the `<title>` element appears, which indicates that the language service is up and running
-		await page.waitForSelector(`text=The title element represents the document's title or name`);
+		// we need to try this a couple of times because the web worker might not be ready yet
+		for (let attempt = 1; attempt <= 2; attempt++) {
+			// trigger hover
+			await focusEditor();
+			await setEditorPosition(1, 3);
+			await page.keyboard.press('F1');
+			await page.keyboard.type('Show Hover');
+			await page.keyboard.press('Enter');
+
+			// check that a hover explaining the `<title>` element appears, which indicates that the language service is up and running
+			try {
+				await page.waitForSelector(
+					`text=The title element represents the document's title or name`,
+					{ timeout: 5000 }
+				);
+			} catch (err) {}
+		}
 	});
 
-	test('json smoke test', async () => {
+	test('json smoke test', async function () {
 		await createEditor('{}', 'json');
 
-		// trigger suggestions
-		await focusEditor();
-		await setEditorPosition(1, 2);
-		await triggerEditorCommand('editor.action.triggerSuggest');
-
-		// check that a suggestion item for `$schema` appears, which indicates that the language service is up and running
-		await page.waitForSelector(`text=$schema`);
+		// we need to try this a couple of times because the web worker might not be ready yet
+		for (let attempt = 1; attempt <= 2; attempt++) {
+			// trigger suggestions
+			await focusEditor();
+			await setEditorPosition(1, 2);
+			await triggerEditorCommand('editor.action.triggerSuggest');
+
+			// check that a suggestion item for `$schema` appears, which indicates that the language service is up and running
+			try {
+				await page.waitForSelector(`text=$schema`, { timeout: 5000 });
+			} catch (err) {}
+		}
 	});
 
-	test('typescript smoke test', async () => {
+	test('typescript smoke test', async function () {
 		await createEditor('window.add', 'typescript');
 
 		// check that a squiggle appears, which indicates that the language service is up and running
 		await page.waitForSelector('.squiggly-error');
 
+		// at this point we know that the web worker is healthy, so we can trigger suggestions
+
 		// trigger suggestions
 		await focusEditor();
 		await setEditorPosition(1, 11);
@@ -167,9 +188,11 @@ suite(`Smoke Test '${TESTS_TYPE}' on '${browserType}'`, () => {
 		// find the TypeScript worker
 		const tsWorker = page.workers().find((worker) => {
 			const url = worker.url();
-			return /ts\.worker\.js$/.test(url) || /workerMain.js#typescript$/.test(url);
+			return /ts\.worker(\.[a-f0-9]+)?\.js$/.test(url) || /workerMain.js#typescript$/.test(url);
 		});
-		assert.ok(!!tsWorker);
+		if (!tsWorker) {
+			assert.fail('Could not find TypeScript worker');
+		}
 
 		// check that the TypeScript worker exposes `ts` as a global
 		assert.strictEqual(await tsWorker.evaluate(`typeof ts`), 'object');

+ 10 - 0
test/smoke/vite/index.html

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+	</head>
+	<body>
+		<div id="editor-container" style="position: absolute; width: 500px; height: 400px"></div>
+		<script type="module" src="index.js"></script>
+	</body>
+</html>

+ 31 - 0
test/smoke/vite/index.js

@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as monaco from '../../../release/esm/vs/editor/editor.main';
+import editorWorker from '../../../release/esm/vs/editor/editor.worker?worker';
+import jsonWorker from '../../../release/esm/vs/language/json/json.worker?worker';
+import cssWorker from '../../../release/esm/vs/language/css/css.worker?worker';
+import htmlWorker from '../../../release/esm/vs/language/html/html.worker?worker';
+import tsWorker from '../../../release/esm/vs/language/typescript/ts.worker?worker';
+
+self.MonacoEnvironment = {
+	getWorker(moduleId, label) {
+		if (label === 'json') {
+			return new jsonWorker();
+		}
+		if (label === 'css' || label === 'scss' || label === 'less') {
+			return new cssWorker();
+		}
+		if (label === 'html' || label === 'handlebars' || label === 'razor') {
+			return new htmlWorker();
+		}
+		if (label === 'typescript' || label === 'javascript') {
+			return new tsWorker();
+		}
+		return new editorWorker();
+	}
+};
+
+window.monacoAPI = monaco;

+ 0 - 0
test/smoke/webpack/webpack.html → test/smoke/webpack/index.html


+ 0 - 0
webpack-plugin/smoketest/index.js → test/smoke/webpack/index.js


+ 2 - 0
test/unit/all.js

@@ -21,6 +21,7 @@ global.self = global;
 global.document.queryCommandSupported = function () {
 	return false;
 };
+global.UIEvent = tmp.window.UIEvent;
 
 global.window = {
 	location: {},
@@ -58,5 +59,6 @@ requirejs(
 	},
 	function (err) {
 		console.log(err);
+		process.exit(1);
 	}
 );

+ 3 - 0
test/unit/setup.js

@@ -9,6 +9,9 @@ define('vs/nls', [], {
 		return {
 			localize: function () {
 				return 'NO_LOCALIZATION_FOR_YOU';
+			},
+			getConfiguredDefaultLocale: function () {
+				return undefined;
 			}
 		};
 	},

+ 12 - 12
webpack-plugin/package-lock.json

@@ -939,9 +939,9 @@
 			"dev": true
 		},
 		"node_modules/json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"bin": {
 				"json5": "lib/cli.js"
 			},
@@ -968,9 +968,9 @@
 			}
 		},
 		"node_modules/loader-utils": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
-			"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+			"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
 			"dependencies": {
 				"big.js": "^5.2.2",
 				"emojis-list": "^3.0.0",
@@ -2531,9 +2531,9 @@
 			"dev": true
 		},
 		"json5": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
-			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
 		},
 		"kind-of": {
 			"version": "6.0.3",
@@ -2548,9 +2548,9 @@
 			"dev": true
 		},
 		"loader-utils": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
-			"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+			"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
 			"requires": {
 				"big.js": "^5.2.2",
 				"emojis-list": "^3.0.0",

+ 0 - 2
webpack-plugin/package.json

@@ -5,8 +5,6 @@
 	"main": "out/index.js",
 	"typings": "./out/index.d.ts",
 	"scripts": {
-		"package-for-smoketest": "node ./node_modules/webpack/bin/webpack.js --config smoketest/webpack.config.js --progress",
-		"smoketest-cross-origin": "node ./node_modules/webpack/bin/webpack.js --config smoketest/webpack-cross-origin.config.js --progress",
 		"watch": "tsc -w -p tsconfig.json",
 		"compile": "tsc -p tsconfig.json",
 		"import-editor": "node ./scripts/import-editor.js",

+ 0 - 39
webpack-plugin/smoketest/webpack-cross-origin.config.js

@@ -1,39 +0,0 @@
-const MonacoWebpackPlugin = require('../out/index.js');
-const path = require('path');
-
-const ASSET_PATH = 'http://localhost:8088/monaco-editor/test/smoke/webpack/out/';
-
-const REPO_ROOT = path.join(__dirname, '../../');
-
-module.exports = {
-	mode: 'development',
-	entry: './index.js',
-	context: __dirname,
-	output: {
-		path: path.resolve(REPO_ROOT, 'test/smoke/webpack/out'),
-		filename: 'app.js',
-		publicPath: ASSET_PATH
-	},
-	resolve: {
-		alias: {
-			'monaco-editor': path.resolve(REPO_ROOT, 'release')
-		}
-	},
-	module: {
-		rules: [
-			{
-				test: /\.css$/,
-				use: ['style-loader', 'css-loader']
-			},
-			{
-				test: /\.ttf$/,
-				use: ['file-loader']
-			}
-		]
-	},
-	plugins: [
-		new MonacoWebpackPlugin({
-			monacoEditorPath: path.resolve(REPO_ROOT, 'release')
-		})
-	]
-};

+ 0 - 36
webpack-plugin/smoketest/webpack.config.js

@@ -1,36 +0,0 @@
-const MonacoWebpackPlugin = require('../out/index.js');
-const path = require('path');
-
-const REPO_ROOT = path.join(__dirname, '../../');
-
-module.exports = {
-	mode: 'development',
-	entry: './index.js',
-	context: __dirname,
-	output: {
-		path: path.resolve(REPO_ROOT, 'test/smoke/webpack/out'),
-		filename: 'app.js'
-	},
-	resolve: {
-		alias: {
-			'monaco-editor': path.resolve(REPO_ROOT, 'release')
-		}
-	},
-	module: {
-		rules: [
-			{
-				test: /\.css$/,
-				use: ['style-loader', 'css-loader']
-			},
-			{
-				test: /\.ttf$/,
-				use: ['file-loader']
-			}
-		]
-	},
-	plugins: [
-		new MonacoWebpackPlugin({
-			monacoEditorPath: path.resolve(REPO_ROOT, 'release')
-		})
-	]
-};

+ 182 - 42
website/playground/monaco.d.ts.txt

@@ -705,6 +705,10 @@ declare namespace monaco {
          * Create a new empty range using this range's start position.
          */
         collapseToStart(): Range;
+        /**
+         * Moves the range by the given amount of lines.
+         */
+        delta(lineCount: number): Range;
         /**
          * Create a new empty range using this range's start position.
          */
@@ -926,6 +930,50 @@ declare namespace monaco.editor {
 
     export function createDiffNavigator(diffEditor: IStandaloneDiffEditor, opts?: IDiffNavigatorOptions): IDiffNavigator;
 
+    /**
+     * Description of a command contribution
+     */
+    export interface ICommandDescriptor {
+        /**
+         * An unique identifier of the contributed command.
+         */
+        id: string;
+        /**
+         * Callback that will be executed when the command is triggered.
+         */
+        run: ICommandHandler;
+    }
+
+    /**
+     * Add a command.
+     */
+    export function addCommand(descriptor: ICommandDescriptor): IDisposable;
+
+    /**
+     * Add an action to all editors.
+     */
+    export function addEditorAction(descriptor: IActionDescriptor): IDisposable;
+
+    /**
+     * A keybinding rule.
+     */
+    export interface IKeybindingRule {
+        keybinding: number;
+        command?: string | null;
+        commandArgs?: any;
+        when?: string | null;
+    }
+
+    /**
+     * Add a keybinding rule.
+     */
+    export function addKeybindingRule(rule: IKeybindingRule): IDisposable;
+
+    /**
+     * Add keybinding rules.
+     */
+    export function addKeybindingRules(rules: IKeybindingRule[]): IDisposable;
+
     /**
      * Create a new editor model.
      * You can specify the language that should be set for this model or let the language be inferred from the `uri`.
@@ -1489,6 +1537,11 @@ declare namespace monaco.editor {
          */
         className?: string | null;
         blockClassName?: string | null;
+        /**
+         * Indicates if this block should be rendered after the last line.
+         * In this case, the range must be empty and set to the last line.
+         */
+        blockIsAfterEnd?: boolean | null;
         /**
          * Message to be rendered when hovering over the glyph margin decoration.
          */
@@ -1501,6 +1554,10 @@ declare namespace monaco.editor {
          * Should the decoration expand to encompass a whole line.
          */
         isWholeLine?: boolean;
+        /**
+         * Always render the decoration (even when the range it encompasses is collapsed).
+         */
+        showIfCollapsed?: boolean;
         /**
          * Specifies the stack order of a decoration.
          * A decoration with greater stack order is always in front of a decoration with
@@ -1743,6 +1800,15 @@ declare namespace monaco.editor {
         GrowsOnlyWhenTypingAfter = 3
     }
 
+    /**
+     * Text snapshot that works like an iterator.
+     * Will try to return chunks of roughly ~64KB size.
+     * Will return null when finished.
+     */
+    export interface ITextSnapshot {
+        read(): string | null;
+    }
+
     /**
      * A model.
      */
@@ -1774,7 +1840,7 @@ declare namespace monaco.editor {
         /**
          * Replace the entire text buffer value contained in this model.
          */
-        setValue(newValue: string): void;
+        setValue(newValue: string | ITextSnapshot): void;
         /**
          * Get the text stored in this model.
          * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`.
@@ -1782,6 +1848,12 @@ declare namespace monaco.editor {
          * @return The text.
          */
         getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string;
+        /**
+         * Get the text stored in this model.
+         * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed.
+         * @return The text snapshot (it is safe to consume it asynchronously).
+         */
+        createSnapshot(preserveBOM?: boolean): ITextSnapshot;
         /**
          * Get the length of the text stored in this model.
          */
@@ -2000,7 +2072,7 @@ declare namespace monaco.editor {
          * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).
          * @return An array with the decorations
          */
-        getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[];
+        getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[];
         /**
          * Gets all the decorations as an array.
          * @param ownerId If set, it will ignore decorations belonging to other owners.
@@ -2616,6 +2688,10 @@ declare namespace monaco.editor {
          * New language
          */
         readonly newLanguage: string;
+        /**
+         * Source of the call that caused the event.
+         */
+        readonly source: string;
     }
 
     /**
@@ -2936,6 +3012,10 @@ declare namespace monaco.editor {
          * Control the behavior and rendering of the scrollbars.
          */
         scrollbar?: IEditorScrollbarOptions;
+        /**
+         * Control the behavior of sticky scroll options
+         */
+        stickyScroll?: IEditorStickyScrollOptions;
         /**
          * Control the behavior and rendering of the minimap.
          */
@@ -3025,8 +3105,7 @@ declare namespace monaco.editor {
          */
         smoothScrolling?: boolean;
         /**
-         * Enable that the editor will install an interval to check if its container dom node size has changed.
-         * Enabling this might have a severe performance impact.
+         * Enable that the editor will install a ResizeObserver to check if its container dom node size has changed.
          * Defaults to false.
          */
         automaticLayout?: boolean;
@@ -3403,6 +3482,10 @@ declare namespace monaco.editor {
          * Controls strikethrough deprecated variables.
          */
         showDeprecated?: boolean;
+        /**
+         * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
+         */
+        matchOnWordStartOnly?: boolean;
         /**
          * Control the behavior and rendering of the inline hints.
          */
@@ -3425,11 +3508,11 @@ declare namespace monaco.editor {
         */
         bracketPairColorization?: IBracketPairColorizationOptions;
         /**
-         * Enables dropping into the editor from an external source.
+         * Controls dropping into the editor from an external source.
          *
-         * This shows a preview of the drop location and triggers an `onDropIntoEditor` event.
+         * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event.
          */
-        enableDropIntoEditor?: boolean;
+        dropIntoEditor?: IDropIntoEditorOptions;
     }
 
     export interface IDiffEditorBaseOptions {
@@ -3487,6 +3570,10 @@ declare namespace monaco.editor {
          * Control the wrapping of the diff editor.
          */
         diffWordWrap?: 'off' | 'on' | 'inherit';
+        /**
+         * Diff Algorithm
+        */
+        diffAlgorithm?: 'smart' | 'experimental';
     }
 
     /**
@@ -3794,6 +3881,17 @@ declare namespace monaco.editor {
         enabled?: boolean;
     }
 
+    export interface IEditorStickyScrollOptions {
+        /**
+         * Enable the sticky scroll
+         */
+        enabled?: boolean;
+        /**
+         * Maximum number of sticky lines to show
+         */
+        maxLineCount?: number;
+    }
+
     /**
      * Configuration options for editor inlayHints
      */
@@ -4175,6 +4273,10 @@ declare namespace monaco.editor {
          * Show deprecated-suggestions.
          */
         showDeprecated?: boolean;
+        /**
+         * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
+         */
+        matchOnWordStartOnly?: boolean;
         /**
          * Show field-suggestions.
          */
@@ -4306,6 +4408,17 @@ declare namespace monaco.editor {
         readonly wrappingColumn: number;
     }
 
+    /**
+     * Configuration options for editor drop into behavior
+     */
+    export interface IDropIntoEditorOptions {
+        /**
+         * Enable the dropping into editor.
+         * Defaults to true.
+         */
+        enabled?: boolean;
+    }
+
     export enum EditorOption {
         acceptSuggestionOnCommitCharacter = 0,
         acceptSuggestionOnEnter = 1,
@@ -4339,7 +4452,7 @@ declare namespace monaco.editor {
         disableMonospaceOptimizations = 29,
         domReadOnly = 30,
         dragAndDrop = 31,
-        enableDropIntoEditor = 32,
+        dropIntoEditor = 32,
         emptySelectionClipboard = 33,
         extraEditorClassName = 34,
         fastScrollSensitivity = 35,
@@ -4412,35 +4525,36 @@ declare namespace monaco.editor {
         snippetSuggestions = 102,
         smartSelect = 103,
         smoothScrolling = 104,
-        stickyTabStops = 105,
-        stopRenderingLineAfter = 106,
-        suggest = 107,
-        suggestFontSize = 108,
-        suggestLineHeight = 109,
-        suggestOnTriggerCharacters = 110,
-        suggestSelection = 111,
-        tabCompletion = 112,
-        tabIndex = 113,
-        unicodeHighlighting = 114,
-        unusualLineTerminators = 115,
-        useShadowDOM = 116,
-        useTabStops = 117,
-        wordSeparators = 118,
-        wordWrap = 119,
-        wordWrapBreakAfterCharacters = 120,
-        wordWrapBreakBeforeCharacters = 121,
-        wordWrapColumn = 122,
-        wordWrapOverride1 = 123,
-        wordWrapOverride2 = 124,
-        wrappingIndent = 125,
-        wrappingStrategy = 126,
-        showDeprecated = 127,
-        inlayHints = 128,
-        editorClassName = 129,
-        pixelRatio = 130,
-        tabFocusMode = 131,
-        layoutInfo = 132,
-        wrappingInfo = 133
+        stickyScroll = 105,
+        stickyTabStops = 106,
+        stopRenderingLineAfter = 107,
+        suggest = 108,
+        suggestFontSize = 109,
+        suggestLineHeight = 110,
+        suggestOnTriggerCharacters = 111,
+        suggestSelection = 112,
+        tabCompletion = 113,
+        tabIndex = 114,
+        unicodeHighlighting = 115,
+        unusualLineTerminators = 116,
+        useShadowDOM = 117,
+        useTabStops = 118,
+        wordSeparators = 119,
+        wordWrap = 120,
+        wordWrapBreakAfterCharacters = 121,
+        wordWrapBreakBeforeCharacters = 122,
+        wordWrapColumn = 123,
+        wordWrapOverride1 = 124,
+        wordWrapOverride2 = 125,
+        wrappingIndent = 126,
+        wrappingStrategy = 127,
+        showDeprecated = 128,
+        inlayHints = 129,
+        editorClassName = 130,
+        pixelRatio = 131,
+        tabFocusMode = 132,
+        layoutInfo = 133,
+        wrappingInfo = 134
     }
 
     export const EditorOptions: {
@@ -4478,7 +4592,8 @@ declare namespace monaco.editor {
         domReadOnly: IEditorOption<EditorOption.domReadOnly, boolean>;
         dragAndDrop: IEditorOption<EditorOption.dragAndDrop, boolean>;
         emptySelectionClipboard: IEditorOption<EditorOption.emptySelectionClipboard, boolean>;
-        enableDropIntoEditor: IEditorOption<EditorOption.enableDropIntoEditor, boolean>;
+        dropIntoEditor: IEditorOption<EditorOption.dropIntoEditor, Readonly<Required<IDropIntoEditorOptions>>>;
+        stickyScroll: IEditorOption<EditorOption.stickyScroll, Readonly<Required<IEditorStickyScrollOptions>>>;
         extraEditorClassName: IEditorOption<EditorOption.extraEditorClassName, string>;
         fastScrollSensitivity: IEditorOption<EditorOption.fastScrollSensitivity, number>;
         find: IEditorOption<EditorOption.find, Readonly<Required<IEditorFindOptions>>>;
@@ -4984,6 +5099,8 @@ declare namespace monaco.editor {
 
     export interface IMouseTargetOutsideEditor extends IBaseMouseTarget {
         readonly type: MouseTargetType.OUTSIDE_EDITOR;
+        readonly outsidePosition: 'above' | 'below' | 'left' | 'right';
+        readonly outsideDistance: number;
     }
 
     /**
@@ -5278,7 +5395,7 @@ declare namespace monaco.editor {
          * @id Unique identifier of the contribution.
          * @return The action or null if action not found.
          */
-        getAction(id: string): IEditorAction;
+        getAction(id: string): IEditorAction | null;
         /**
          * Execute a command on the editor.
          * The edits will land on the undo-redo stack, but no "undo stop" will be pushed.
@@ -5335,9 +5452,13 @@ declare namespace monaco.editor {
          */
         getVisibleRanges(): Range[];
         /**
-         * Get the vertical position (top offset) for the line w.r.t. to the first line.
+         * Get the vertical position (top offset) for the line's top w.r.t. to the first line.
          */
         getTopForLineNumber(lineNumber: number): number;
+        /**
+         * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line.
+         */
+        getBottomForLineNumber(lineNumber: number): number;
         /**
          * Get the vertical position (top offset) for the position w.r.t. to the first line.
          */
@@ -5436,6 +5557,11 @@ declare namespace monaco.editor {
          * @event
          */
         readonly onDidUpdateDiff: IEvent<void>;
+        /**
+         * An event emitted when the diff model is changed (i.e. the diff editor shows new content).
+         * @event
+         */
+        readonly onDidChangeModel: IEvent<void>;
         /**
          * Saves current view state of the editor in a serializable object.
          */
@@ -5838,6 +5964,10 @@ declare namespace monaco.languages {
          * Requested kind of actions to return.
          */
         readonly only?: string;
+        /**
+         * The reason why code actions were requested.
+         */
+        readonly trigger: CodeActionTriggerType;
     }
 
     /**
@@ -5868,6 +5998,10 @@ declare namespace monaco.languages {
          * such as `["quickfix.removeLine", "source.fixAll" ...]`.
          */
         readonly providedCodeActionKinds?: readonly string[];
+        readonly documentation?: ReadonlyArray<{
+            readonly kind: string;
+            readonly command: Command;
+        }>;
     }
 
     /**
@@ -6440,6 +6574,11 @@ declare namespace monaco.languages {
         disabled?: string;
     }
 
+    export enum CodeActionTriggerType {
+        Invoke = 1,
+        Auto = 2
+    }
+
     export interface CodeActionList extends IDisposable {
         readonly actions: ReadonlyArray<CodeAction>;
     }
@@ -6776,11 +6915,11 @@ declare namespace monaco.languages {
         provideDocumentSymbols(model: editor.ITextModel, token: CancellationToken): ProviderResult<DocumentSymbol[]>;
     }
 
-    export type TextEdit = {
+    export interface TextEdit {
         range: IRange;
         text: string;
         eol?: editor.EndOfLineSequence;
-    };
+    }
 
     /**
      * Interface used to format a model
@@ -7018,6 +7157,7 @@ declare namespace monaco.languages {
         folder?: boolean;
         skipTrashBin?: boolean;
         maxSize?: number;
+        contentsBase64?: string;
     }
 
     export interface IWorkspaceFileEdit {

+ 6 - 6
website/playground/new-samples/extending-language-services/color-provider-example/sample.js

@@ -34,27 +34,27 @@ monaco.languages.registerColorProvider('colorLanguage', {
 				color: { red: 1, blue: 0, green: 0, alpha: 1 },
 				range: {
 					startLineNumber: 1,
-					startColumn: 0,
+					startColumn: 1,
 					endLineNumber: 1,
-					endColumn: 0
+					endColumn: 4
 				}
 			},
 			{
 				color: { red: 0, blue: 1, green: 0, alpha: 1 },
 				range: {
 					startLineNumber: 2,
-					startColumn: 0,
+					startColumn: 1,
 					endLineNumber: 2,
-					endColumn: 0
+					endColumn: 5
 				}
 			},
 			{
 				color: { red: 0, blue: 0, green: 1, alpha: 1 },
 				range: {
 					startLineNumber: 3,
-					startColumn: 0,
+					startColumn: 1,
 					endLineNumber: 3,
-					endColumn: 0
+					endColumn: 6
 				}
 			}
 		];

+ 181 - 41
website/typedoc/monaco.d.ts

@@ -705,6 +705,10 @@ declare namespace monaco {
          * Create a new empty range using this range's start position.
          */
         collapseToStart(): Range;
+        /**
+         * Moves the range by the given amount of lines.
+         */
+        delta(lineCount: number): Range;
         /**
          * Create a new empty range using this range's start position.
          */
@@ -926,6 +930,50 @@ declare namespace monaco.editor {
 
     export function createDiffNavigator(diffEditor: IStandaloneDiffEditor, opts?: IDiffNavigatorOptions): IDiffNavigator;
 
+    /**
+     * Description of a command contribution
+     */
+    export interface ICommandDescriptor {
+        /**
+         * An unique identifier of the contributed command.
+         */
+        id: string;
+        /**
+         * Callback that will be executed when the command is triggered.
+         */
+        run: ICommandHandler;
+    }
+
+    /**
+     * Add a command.
+     */
+    export function addCommand(descriptor: ICommandDescriptor): IDisposable;
+
+    /**
+     * Add an action to all editors.
+     */
+    export function addEditorAction(descriptor: IActionDescriptor): IDisposable;
+
+    /**
+     * A keybinding rule.
+     */
+    export interface IKeybindingRule {
+        keybinding: number;
+        command?: string | null;
+        commandArgs?: any;
+        when?: string | null;
+    }
+
+    /**
+     * Add a keybinding rule.
+     */
+    export function addKeybindingRule(rule: IKeybindingRule): IDisposable;
+
+    /**
+     * Add keybinding rules.
+     */
+    export function addKeybindingRules(rules: IKeybindingRule[]): IDisposable;
+
     /**
      * Create a new editor model.
      * You can specify the language that should be set for this model or let the language be inferred from the `uri`.
@@ -1489,6 +1537,11 @@ declare namespace monaco.editor {
          */
         className?: string | null;
         blockClassName?: string | null;
+        /**
+         * Indicates if this block should be rendered after the last line.
+         * In this case, the range must be empty and set to the last line.
+         */
+        blockIsAfterEnd?: boolean | null;
         /**
          * Message to be rendered when hovering over the glyph margin decoration.
          */
@@ -1501,6 +1554,10 @@ declare namespace monaco.editor {
          * Should the decoration expand to encompass a whole line.
          */
         isWholeLine?: boolean;
+        /**
+         * Always render the decoration (even when the range it encompasses is collapsed).
+         */
+        showIfCollapsed?: boolean;
         /**
          * Specifies the stack order of a decoration.
          * A decoration with greater stack order is always in front of a decoration with
@@ -1743,6 +1800,15 @@ declare namespace monaco.editor {
         GrowsOnlyWhenTypingAfter = 3
     }
 
+    /**
+     * Text snapshot that works like an iterator.
+     * Will try to return chunks of roughly ~64KB size.
+     * Will return null when finished.
+     */
+    export interface ITextSnapshot {
+        read(): string | null;
+    }
+
     /**
      * A model.
      */
@@ -1774,7 +1840,7 @@ declare namespace monaco.editor {
         /**
          * Replace the entire text buffer value contained in this model.
          */
-        setValue(newValue: string): void;
+        setValue(newValue: string | ITextSnapshot): void;
         /**
          * Get the text stored in this model.
          * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`.
@@ -1782,6 +1848,12 @@ declare namespace monaco.editor {
          * @return The text.
          */
         getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string;
+        /**
+         * Get the text stored in this model.
+         * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed.
+         * @return The text snapshot (it is safe to consume it asynchronously).
+         */
+        createSnapshot(preserveBOM?: boolean): ITextSnapshot;
         /**
          * Get the length of the text stored in this model.
          */
@@ -2000,7 +2072,7 @@ declare namespace monaco.editor {
          * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).
          * @return An array with the decorations
          */
-        getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[];
+        getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[];
         /**
          * Gets all the decorations as an array.
          * @param ownerId If set, it will ignore decorations belonging to other owners.
@@ -2616,6 +2688,10 @@ declare namespace monaco.editor {
          * New language
          */
         readonly newLanguage: string;
+        /**
+         * Source of the call that caused the event.
+         */
+        readonly source: string;
     }
 
     /**
@@ -2936,6 +3012,10 @@ declare namespace monaco.editor {
          * Control the behavior and rendering of the scrollbars.
          */
         scrollbar?: IEditorScrollbarOptions;
+        /**
+         * Control the behavior of sticky scroll options
+         */
+        stickyScroll?: IEditorStickyScrollOptions;
         /**
          * Control the behavior and rendering of the minimap.
          */
@@ -3026,7 +3106,6 @@ declare namespace monaco.editor {
         smoothScrolling?: boolean;
         /**
          * Enable that the editor will install a ResizeObserver to check if its container dom node size has changed.
-         * Enabling this might have a severe performance impact.
          * Defaults to false.
          */
         automaticLayout?: boolean;
@@ -3403,6 +3482,10 @@ declare namespace monaco.editor {
          * Controls strikethrough deprecated variables.
          */
         showDeprecated?: boolean;
+        /**
+         * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
+         */
+        matchOnWordStartOnly?: boolean;
         /**
          * Control the behavior and rendering of the inline hints.
          */
@@ -3425,11 +3508,11 @@ declare namespace monaco.editor {
         */
         bracketPairColorization?: IBracketPairColorizationOptions;
         /**
-         * Enables dropping into the editor from an external source.
+         * Controls dropping into the editor from an external source.
          *
-         * This shows a preview of the drop location and triggers an `onDropIntoEditor` event.
+         * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event.
          */
-        enableDropIntoEditor?: boolean;
+        dropIntoEditor?: IDropIntoEditorOptions;
     }
 
     export interface IDiffEditorBaseOptions {
@@ -3487,6 +3570,10 @@ declare namespace monaco.editor {
          * Control the wrapping of the diff editor.
          */
         diffWordWrap?: 'off' | 'on' | 'inherit';
+        /**
+         * Diff Algorithm
+        */
+        diffAlgorithm?: 'smart' | 'experimental';
     }
 
     /**
@@ -3794,6 +3881,17 @@ declare namespace monaco.editor {
         enabled?: boolean;
     }
 
+    export interface IEditorStickyScrollOptions {
+        /**
+         * Enable the sticky scroll
+         */
+        enabled?: boolean;
+        /**
+         * Maximum number of sticky lines to show
+         */
+        maxLineCount?: number;
+    }
+
     /**
      * Configuration options for editor inlayHints
      */
@@ -4175,6 +4273,10 @@ declare namespace monaco.editor {
          * Show deprecated-suggestions.
          */
         showDeprecated?: boolean;
+        /**
+         * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
+         */
+        matchOnWordStartOnly?: boolean;
         /**
          * Show field-suggestions.
          */
@@ -4306,6 +4408,17 @@ declare namespace monaco.editor {
         readonly wrappingColumn: number;
     }
 
+    /**
+     * Configuration options for editor drop into behavior
+     */
+    export interface IDropIntoEditorOptions {
+        /**
+         * Enable the dropping into editor.
+         * Defaults to true.
+         */
+        enabled?: boolean;
+    }
+
     export enum EditorOption {
         acceptSuggestionOnCommitCharacter = 0,
         acceptSuggestionOnEnter = 1,
@@ -4339,7 +4452,7 @@ declare namespace monaco.editor {
         disableMonospaceOptimizations = 29,
         domReadOnly = 30,
         dragAndDrop = 31,
-        enableDropIntoEditor = 32,
+        dropIntoEditor = 32,
         emptySelectionClipboard = 33,
         extraEditorClassName = 34,
         fastScrollSensitivity = 35,
@@ -4412,35 +4525,36 @@ declare namespace monaco.editor {
         snippetSuggestions = 102,
         smartSelect = 103,
         smoothScrolling = 104,
-        stickyTabStops = 105,
-        stopRenderingLineAfter = 106,
-        suggest = 107,
-        suggestFontSize = 108,
-        suggestLineHeight = 109,
-        suggestOnTriggerCharacters = 110,
-        suggestSelection = 111,
-        tabCompletion = 112,
-        tabIndex = 113,
-        unicodeHighlighting = 114,
-        unusualLineTerminators = 115,
-        useShadowDOM = 116,
-        useTabStops = 117,
-        wordSeparators = 118,
-        wordWrap = 119,
-        wordWrapBreakAfterCharacters = 120,
-        wordWrapBreakBeforeCharacters = 121,
-        wordWrapColumn = 122,
-        wordWrapOverride1 = 123,
-        wordWrapOverride2 = 124,
-        wrappingIndent = 125,
-        wrappingStrategy = 126,
-        showDeprecated = 127,
-        inlayHints = 128,
-        editorClassName = 129,
-        pixelRatio = 130,
-        tabFocusMode = 131,
-        layoutInfo = 132,
-        wrappingInfo = 133
+        stickyScroll = 105,
+        stickyTabStops = 106,
+        stopRenderingLineAfter = 107,
+        suggest = 108,
+        suggestFontSize = 109,
+        suggestLineHeight = 110,
+        suggestOnTriggerCharacters = 111,
+        suggestSelection = 112,
+        tabCompletion = 113,
+        tabIndex = 114,
+        unicodeHighlighting = 115,
+        unusualLineTerminators = 116,
+        useShadowDOM = 117,
+        useTabStops = 118,
+        wordSeparators = 119,
+        wordWrap = 120,
+        wordWrapBreakAfterCharacters = 121,
+        wordWrapBreakBeforeCharacters = 122,
+        wordWrapColumn = 123,
+        wordWrapOverride1 = 124,
+        wordWrapOverride2 = 125,
+        wrappingIndent = 126,
+        wrappingStrategy = 127,
+        showDeprecated = 128,
+        inlayHints = 129,
+        editorClassName = 130,
+        pixelRatio = 131,
+        tabFocusMode = 132,
+        layoutInfo = 133,
+        wrappingInfo = 134
     }
 
     export const EditorOptions: {
@@ -4478,7 +4592,8 @@ declare namespace monaco.editor {
         domReadOnly: IEditorOption<EditorOption.domReadOnly, boolean>;
         dragAndDrop: IEditorOption<EditorOption.dragAndDrop, boolean>;
         emptySelectionClipboard: IEditorOption<EditorOption.emptySelectionClipboard, boolean>;
-        enableDropIntoEditor: IEditorOption<EditorOption.enableDropIntoEditor, boolean>;
+        dropIntoEditor: IEditorOption<EditorOption.dropIntoEditor, Readonly<Required<IDropIntoEditorOptions>>>;
+        stickyScroll: IEditorOption<EditorOption.stickyScroll, Readonly<Required<IEditorStickyScrollOptions>>>;
         extraEditorClassName: IEditorOption<EditorOption.extraEditorClassName, string>;
         fastScrollSensitivity: IEditorOption<EditorOption.fastScrollSensitivity, number>;
         find: IEditorOption<EditorOption.find, Readonly<Required<IEditorFindOptions>>>;
@@ -4984,6 +5099,8 @@ declare namespace monaco.editor {
 
     export interface IMouseTargetOutsideEditor extends IBaseMouseTarget {
         readonly type: MouseTargetType.OUTSIDE_EDITOR;
+        readonly outsidePosition: 'above' | 'below' | 'left' | 'right';
+        readonly outsideDistance: number;
     }
 
     /**
@@ -5278,7 +5395,7 @@ declare namespace monaco.editor {
          * @id Unique identifier of the contribution.
          * @return The action or null if action not found.
          */
-        getAction(id: string): IEditorAction;
+        getAction(id: string): IEditorAction | null;
         /**
          * Execute a command on the editor.
          * The edits will land on the undo-redo stack, but no "undo stop" will be pushed.
@@ -5335,9 +5452,13 @@ declare namespace monaco.editor {
          */
         getVisibleRanges(): Range[];
         /**
-         * Get the vertical position (top offset) for the line w.r.t. to the first line.
+         * Get the vertical position (top offset) for the line's top w.r.t. to the first line.
          */
         getTopForLineNumber(lineNumber: number): number;
+        /**
+         * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line.
+         */
+        getBottomForLineNumber(lineNumber: number): number;
         /**
          * Get the vertical position (top offset) for the position w.r.t. to the first line.
          */
@@ -5436,6 +5557,11 @@ declare namespace monaco.editor {
          * @event
          */
         readonly onDidUpdateDiff: IEvent<void>;
+        /**
+         * An event emitted when the diff model is changed (i.e. the diff editor shows new content).
+         * @event
+         */
+        readonly onDidChangeModel: IEvent<void>;
         /**
          * Saves current view state of the editor in a serializable object.
          */
@@ -5838,6 +5964,10 @@ declare namespace monaco.languages {
          * Requested kind of actions to return.
          */
         readonly only?: string;
+        /**
+         * The reason why code actions were requested.
+         */
+        readonly trigger: CodeActionTriggerType;
     }
 
     /**
@@ -5868,6 +5998,10 @@ declare namespace monaco.languages {
          * such as `["quickfix.removeLine", "source.fixAll" ...]`.
          */
         readonly providedCodeActionKinds?: readonly string[];
+        readonly documentation?: ReadonlyArray<{
+            readonly kind: string;
+            readonly command: Command;
+        }>;
     }
 
     /**
@@ -6440,6 +6574,11 @@ declare namespace monaco.languages {
         disabled?: string;
     }
 
+    export enum CodeActionTriggerType {
+        Invoke = 1,
+        Auto = 2
+    }
+
     export interface CodeActionList extends IDisposable {
         readonly actions: ReadonlyArray<CodeAction>;
     }
@@ -6776,11 +6915,11 @@ declare namespace monaco.languages {
         provideDocumentSymbols(model: editor.ITextModel, token: CancellationToken): ProviderResult<DocumentSymbol[]>;
     }
 
-    export type TextEdit = {
+    export interface TextEdit {
         range: IRange;
         text: string;
         eol?: editor.EndOfLineSequence;
-    };
+    }
 
     /**
      * Interface used to format a model
@@ -7018,6 +7157,7 @@ declare namespace monaco.languages {
         folder?: boolean;
         skipTrashBin?: boolean;
         maxSize?: number;
+        contentsBase64?: string;
     }
 
     export interface IWorkspaceFileEdit {

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