diff --git a/.gitattributes b/.gitattributes
index 427eeebd7..d6095a2da 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -35,3 +35,4 @@ docs/licenses/monaco-editor/typescript/** -text whitespace=-trailing-space,cr-at
refactor/baselines/site-vendor/monaco-languages/** -text whitespace=-trailing-space,cr-at-eol
refactor/baselines/site-vendor/monaco-language-notices/** -text whitespace=-trailing-space,cr-at-eol
docs/licenses/monaco-editor/language-services/** -text whitespace=-trailing-space,cr-at-eol
+refactor/baselines/site-vendor/monaco-modes/** -text whitespace=-trailing-space,cr-at-eol
diff --git a/package.json b/package.json
index da73d04d9..dcb418955 100644
--- a/package.json
+++ b/package.json
@@ -166,7 +166,8 @@
"check:console": "node scripts/build-console.mjs --check",
"test:site-console": "node --test test/site-console.test.js",
"verify:monaco-typescript-source": "node scripts/site-vendor/monaco/reproduce-typescript.ts",
- "verify:monaco-language-sources": "node scripts/site-vendor/monaco/reproduce-languages.ts"
+ "verify:monaco-language-sources": "node scripts/site-vendor/monaco/reproduce-languages.ts",
+ "verify:monaco-mode-sources": "node scripts/site-vendor/monaco/reproduce-modes.ts"
},
"browserslist": "last 1 Chrome version",
"devDependencies": {
diff --git a/refactor/baselines/monaco-language-notices.json b/refactor/baselines/monaco-language-notices.json
index 63015c424..a03fdae0a 100644
--- a/refactor/baselines/monaco-language-notices.json
+++ b/refactor/baselines/monaco-language-notices.json
@@ -10,7 +10,8 @@
"tarball": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"archive": "jsonc-parser-3.0.0",
"assets": [
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/jsonc-parser/LICENSE.md"
@@ -76,7 +77,10 @@
"assets": [
"docs/assets/js/vs/language/css/cssWorker.js",
"docs/assets/js/vs/language/html/htmlWorker.js",
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/css/cssMode.js",
+ "docs/assets/js/vs/language/html/htmlMode.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/vscode-languageserver-types/License.txt"
@@ -104,7 +108,8 @@
"tarball": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"archive": "jsonc-parser-3.0.0",
"assets": [
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/jsonc-parser/LICENSE.md",
@@ -175,7 +180,10 @@
"assets": [
"docs/assets/js/vs/language/css/cssWorker.js",
"docs/assets/js/vs/language/html/htmlWorker.js",
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/css/cssMode.js",
+ "docs/assets/js/vs/language/html/htmlMode.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/vscode-languageserver-types/License.txt",
@@ -318,5 +326,6 @@
"target": "docs/licenses/monaco-editor/language-services/ATTRIBUTION.md",
"sha256": "432cca135809edabcd9ccedd05576138b64b167445999005a6e1550132391d98"
}
- ]
+ ],
+ "modeSourceRecord": "refactor/baselines/monaco-modes-provenance.json"
}
diff --git a/refactor/baselines/monaco-modes-provenance.json b/refactor/baselines/monaco-modes-provenance.json
new file mode 100644
index 000000000..2aa277ed7
--- /dev/null
+++ b/refactor/baselines/monaco-modes-provenance.json
@@ -0,0 +1,450 @@
+{
+ "schemaVersion": 1,
+ "task": "SITE-07",
+ "commit": "5a7ba61be909ae9e4889768a3453ebb0dec392e2",
+ "scope": "All four language mode bundles; exact module/helper and minified output coverage, not a complete upstream typecheck.",
+ "archives": [
+ {
+ "name": "monaco-editor",
+ "version": "0.30.1",
+ "tarball": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.30.1.tgz",
+ "integrity": "sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg==",
+ "sha256": "d7872ab742036036eca48cd54e43d751bede56742f0689bcf4049bcf701468c7"
+ },
+ {
+ "name": "typescript",
+ "version": "4.4.4",
+ "tarball": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "sha256": "7524841bbf63777fef1fe6e1a826026b1dd4849f54f5affa481502faab2cdb16"
+ },
+ {
+ "name": "terser",
+ "version": "5.9.0",
+ "tarball": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz",
+ "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==",
+ "sha256": "2ca0d9c4731b6ebd3b86ed1a7b735f685f98636ee5a067ae9e27e83246069619"
+ },
+ {
+ "name": "source-map",
+ "version": "0.7.3",
+ "tarball": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "sha256": "ad69b787ba774733c3e4f0eb20403df7b1fa466252d453533dbcc6a5ad15833e"
+ },
+ {
+ "name": "jsonc-parser",
+ "version": "3.0.0",
+ "tarball": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
+ "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
+ "sha256": "807c53e781c6c6181165f6214db5f6892742041338d9891ce3c335cf3bc25da8"
+ },
+ {
+ "name": "vscode-languageserver-types",
+ "version": "3.16.0",
+ "tarball": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
+ "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
+ "sha256": "eb934ea5eda6fd6b5d21ae8706922be1179501c30350260e07998e76c6946a2c"
+ }
+ ],
+ "remotes": [
+ {
+ "source": "refactor/baselines/site-vendor/monaco-typescript/package-lock.json.txt",
+ "sha256": "84c66bfe8ae95b2226ca289279133999356e64137db7ba001817737fa1ac8cf8",
+ "gitBlobSha": "9f647e9fc82150a5d06a9c02dc781d2dbe902ed6",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/package-lock.json?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-css-scripts-bundle.js.txt",
+ "sha256": "2a9dbfbd62b6106835ac69d930e4e1024000196154d0fd98e7a42bfab9977751",
+ "gitBlobSha": "49709bc5efb3f5e81c2797fa771b0576f86c71fb",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-css/scripts/bundle.js?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-css-src-tsconfig.json.txt",
+ "sha256": "d5739d74d37ae0ff0d8b55f19b1116433bae9b0f8a81c8b410bd587e11bc7694",
+ "gitBlobSha": "707f714dd2869a2e1fe3c5a679cf1eb116f0f542",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-css/src/tsconfig.json?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-html-scripts-bundle.js.txt",
+ "sha256": "9a101e8926d384a880bdfc13ae72559f72d1b4e8b1d7dd755a6a999ca6383718",
+ "gitBlobSha": "d5932edf6307028d76be68e76fcaf08ec2768a58",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-html/scripts/bundle.js?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-html-src-tsconfig.json.txt",
+ "sha256": "d5739d74d37ae0ff0d8b55f19b1116433bae9b0f8a81c8b410bd587e11bc7694",
+ "gitBlobSha": "707f714dd2869a2e1fe3c5a679cf1eb116f0f542",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-html/src/tsconfig.json?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-json-scripts-bundle.js.txt",
+ "sha256": "1326211da917b321808ae29987c666226028ad276af3e1d376cd7d0ed3902fd6",
+ "gitBlobSha": "cb54926f4a3fb00d16824d2be6c6e51b3a6524ec",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/scripts/bundle.js?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-languages/monaco-json-src-tsconfig.json.txt",
+ "sha256": "d5739d74d37ae0ff0d8b55f19b1116433bae9b0f8a81c8b410bd587e11bc7694",
+ "gitBlobSha": "707f714dd2869a2e1fe3c5a679cf1eb116f0f542",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/src/tsconfig.json?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-typescript/bundle.js.txt",
+ "sha256": "1f418cf3a1c27d9c466ce315ebb185451e47e70847e3fb53f383aae2bb5250d9",
+ "gitBlobSha": "2478682d11c9122debd33d6a7339183b16238799",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/scripts/bundle.js?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsconfig.json.txt",
+ "sha256": "0db526f0bf18e6022981cde7257af00875f4c2027d4f2a5e88221f6541f80452",
+ "gitBlobSha": "001f587e6dd21981e63aff2bebdfd8a6a79a74eb",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/src/tsconfig.json?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-workerManager.ts.txt",
+ "sha256": "8705e3989d308a42c23f5f9d3ea422fcb11315787c1e937cd8f9539ce9c49504",
+ "gitBlobSha": "335396d5d17303bca55cf8f043762501e6a55d4a",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-css/src/workerManager.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-languageFeatures.ts.txt",
+ "sha256": "0f2f6b94992a614c930dc3c2516cd875c77424f05bb9ad730e123fbc6ac1e7da",
+ "gitBlobSha": "462521c8aa98a1527b00c2510b5f00c8570716ae",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-css/src/languageFeatures.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-cssMode.ts.txt",
+ "sha256": "24af822e60188a50129779164aef98415355a3e7aa29e2cb200987b0fa7c4fbe",
+ "gitBlobSha": "ec3ea26039c2df9889a0769b9cbfe38bb14c2a10",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-css/src/cssMode.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-workerManager.ts.txt",
+ "sha256": "c46c7286896e5c8eff4f0eb8dbcee0d114486419314c861d52dafcd5b7fef0f9",
+ "gitBlobSha": "5122168b53c9ef913d76e9cd9baf1b6f6c9e30a5",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-html/src/workerManager.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-languageFeatures.ts.txt",
+ "sha256": "f444cec1b734bfc64d2941291ffc172e6e9326b0f4112c53660fe4e07064e9eb",
+ "gitBlobSha": "2d6ec03408b5dc1f96b58aced67240521af4bc2b",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-html/src/languageFeatures.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-htmlMode.ts.txt",
+ "sha256": "a48c1bc729ea7a609bbd5bf122a37c7960437763498c58828f4a69424e28d495",
+ "gitBlobSha": "95b560cb358b16920eb204b5ab4d362b3a59de49",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-html/src/htmlMode.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-workerManager.ts.txt",
+ "sha256": "88f875df4f3358d1759e7c60efeed6033a3490f7e6a51f6ad89b96d97aceb75c",
+ "gitBlobSha": "6c32e001806ee072a11b0a763a2ff8b3178d2da5",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/src/workerManager.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-languageFeatures.ts.txt",
+ "sha256": "4b0e8d14b8c6553e078173217e6fcd7c50b5d56b1718cad6f37733db90998da8",
+ "gitBlobSha": "cc6391a0b00a922503c799a3181848c5c9540371",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/src/languageFeatures.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-tokenization.ts.txt",
+ "sha256": "14cab1d17770916632f94955a5cd14664d7fe02facc8ce3c9354e515c22ffec1",
+ "gitBlobSha": "aa9bd5a447d9fbe78b685d5765bdf2f02e5445c0",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/src/tokenization.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-jsonMode.ts.txt",
+ "sha256": "7e098ac320154c14b9f026df9189b06c1433e71171e6c6c6b1d9f0ce5406a684",
+ "gitBlobSha": "7d66f6a0e1b14951b81c43cb3486ac0a7862aa79",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-json/src/jsonMode.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-workerManager.ts.txt",
+ "sha256": "a0d0f19f8b8819e6a38144dd1a30cd27763eeca1f2ac94501f76dba46a73e43f",
+ "gitBlobSha": "6e70ae025f568ab8468d0c86ada8e0e70ec58ea5",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/src/workerManager.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-lib-lib.index.ts.txt",
+ "sha256": "722036bc714d9c5e1b06e419dd96400d0f59eec13a20bec44a0403bca50b6383",
+ "gitBlobSha": "a501460f03cbd6a88b45bfee44a9ab6ef595db4f",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/src/lib/lib.index.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-languageFeatures.ts.txt",
+ "sha256": "4be07e7664d0127a7339e70b81b4dd783479c40f3020bf83de24c9beb8ab1580",
+ "gitBlobSha": "2dba4a863fca7f516b7009e2a09d41c78c48f262",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/src/languageFeatures.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ },
+ {
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsMode.ts.txt",
+ "sha256": "2be7c0ef70f9c0d819680057e87b041f3ba34b1d4f60801f5058bfd4fc12232d",
+ "gitBlobSha": "9ebf59cf6bcc66b93c2e728644fb6eba695bbe6a",
+ "apiUrl": "https://api.github.com/repos/microsoft/monaco-editor/contents/monaco-typescript/src/tsMode.ts?ref=5a7ba61be909ae9e4889768a3453ebb0dec392e2"
+ }
+ ],
+ "compilerMembers": [
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/typescript.js",
+ "sha256": "69fde5346b9468255c32d8d0bff32842445822528b25da1a323ec1c076979384"
+ },
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/lib.es5.d.ts",
+ "sha256": "aa9fb4c70f369237c2f45f9d969c9a59e0eae9a192962eb48581fe864aa609db"
+ },
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/lib.dom.d.ts",
+ "sha256": "e54c8715a4954cfdc66cd69489f2b725c09ebf37492dbd91cff0a1688b1159e8"
+ },
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/lib.es2015.collection.d.ts",
+ "sha256": "43fb1d932e4966a39a41b464a12a81899d9ae5f2c829063f5571b6b87e6d2f9c"
+ },
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/lib.es2015.promise.d.ts",
+ "sha256": "2bb4b3927299434052b37851a47bf5c39764f2ba88a888a107b32262e9292b7c"
+ },
+ {
+ "archive": "typescript-4.4.4",
+ "member": "package/lib/lib.es2015.iterable.d.ts",
+ "sha256": "2c8c5ee58f30e7c944e04ab1fb5506fdbb4dd507c9efa6972cf4b91cec90c503"
+ },
+ {
+ "archive": "terser-5.9.0",
+ "member": "package/dist/bundle.min.js",
+ "sha256": "b8b44743a529c5bd1cf8d6676f040c3c9bed29c7c114e5a26dde5e0fb2125838"
+ }
+ ],
+ "declaration": {
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/main.d.ts",
+ "sha256": "5c65cfde6c6384c36d66bdbe76316d4fa274183c63258cb75b922306e845171f"
+ },
+ "npmModules": [
+ {
+ "id": "vscode-languageserver-types/main",
+ "archive": "vscode-languageserver-types-3.16.0",
+ "member": "package/lib/umd/main.js",
+ "sha256": "bc54d0255c6527858d4b2a6c9fd366dd5bdc08d627aa6a81ebb52b27fe1bb17d"
+ },
+ {
+ "id": "jsonc-parser/impl/scanner",
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/impl/scanner.js",
+ "sha256": "1de9d507a6fc3cbe314fe77d4129db5d0d717b453d6340dc822869f6be6f01ef"
+ },
+ {
+ "id": "jsonc-parser/impl/format",
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/impl/format.js",
+ "sha256": "0a6e9addcaba963b19bdc28a9e563affe7ecfa9d710bbbf88a798e134b8c2d9e"
+ },
+ {
+ "id": "jsonc-parser/impl/parser",
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/impl/parser.js",
+ "sha256": "0bcb61b4cddc09380ae45a8bb74d97162a46733dd87bada5590579f91abc2a62"
+ },
+ {
+ "id": "jsonc-parser/impl/edit",
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/impl/edit.js",
+ "sha256": "be5cbec07265803c812a888d8aeaf18f69c77c827a120486ef38515d6225008d"
+ },
+ {
+ "id": "jsonc-parser/main",
+ "archive": "jsonc-parser-3.0.0",
+ "member": "package/lib/umd/main.js",
+ "sha256": "09e425ed64c68688277ed7ef8e0b627700134e4e2290aa36b175530b658245aa"
+ }
+ ],
+ "aliases": [
+ {
+ "id": "jsonc-parser",
+ "main": "main"
+ },
+ {
+ "id": "vscode-languageserver-types",
+ "main": "main"
+ }
+ ],
+ "files": [
+ {
+ "language": "css",
+ "name": "cssMode",
+ "development": {
+ "archive": "monaco-editor-0.30.1",
+ "member": "package/dev/vs/language/css/cssMode.js",
+ "sha256": "a541bd23805055fda946f0b462a56cfe1f9ff1ec3cf8c63aa5dd1f56a86a9001"
+ },
+ "target": {
+ "path": "docs/assets/js/vs/language/css/cssMode.js",
+ "sha256": "c0f3a99395d07b421ef75f6eb78389c6ef29477f6a05556f9b94e2bb918dd6c1"
+ },
+ "ids": [
+ "vs/language/css/workerManager",
+ "vscode-languageserver-types/main",
+ "vscode-languageserver-types",
+ "vs/language/css/languageFeatures",
+ "vs/language/css/cssMode"
+ ],
+ "modules": [
+ {
+ "id": "vs/language/css/workerManager",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-workerManager.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/css/languageFeatures",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-languageFeatures.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/css/cssMode",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-css-src-cssMode.ts.txt",
+ "resolveJsonc": false
+ }
+ ],
+ "config": "refactor/baselines/site-vendor/monaco-languages/monaco-css-src-tsconfig.json.txt"
+ },
+ {
+ "language": "html",
+ "name": "htmlMode",
+ "development": {
+ "archive": "monaco-editor-0.30.1",
+ "member": "package/dev/vs/language/html/htmlMode.js",
+ "sha256": "d5f1df4fcfb72023f0a35ccc339ba35c08ffa9d5677361246d4e8bcd49c912a5"
+ },
+ "target": {
+ "path": "docs/assets/js/vs/language/html/htmlMode.js",
+ "sha256": "91f7b295ddc3b0b679c669b84865f3ace79fdd30bfcd814f2960c06f3e24d600"
+ },
+ "ids": [
+ "vs/language/html/workerManager",
+ "vscode-languageserver-types/main",
+ "vscode-languageserver-types",
+ "vs/language/html/languageFeatures",
+ "vs/language/html/htmlMode"
+ ],
+ "modules": [
+ {
+ "id": "vs/language/html/workerManager",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-workerManager.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/html/languageFeatures",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-languageFeatures.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/html/htmlMode",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-html-src-htmlMode.ts.txt",
+ "resolveJsonc": false
+ }
+ ],
+ "config": "refactor/baselines/site-vendor/monaco-languages/monaco-html-src-tsconfig.json.txt"
+ },
+ {
+ "language": "json",
+ "name": "jsonMode",
+ "development": {
+ "archive": "monaco-editor-0.30.1",
+ "member": "package/dev/vs/language/json/jsonMode.js",
+ "sha256": "75451dc400862d52cf48e3da7d1810f3fbb6958ec00a98fc1745ca101b968ee0"
+ },
+ "target": {
+ "path": "docs/assets/js/vs/language/json/jsonMode.js",
+ "sha256": "9abacb664dcd8564f28ef004465da0f4b3c551b2741424bf42e61c0a26e61adb"
+ },
+ "ids": [
+ "vs/language/json/workerManager",
+ "vscode-languageserver-types/main",
+ "vscode-languageserver-types",
+ "vs/language/json/languageFeatures",
+ "jsonc-parser/impl/scanner",
+ "jsonc-parser/impl/format",
+ "jsonc-parser/impl/parser",
+ "jsonc-parser/impl/edit",
+ "jsonc-parser/main",
+ "jsonc-parser",
+ "vs/language/json/tokenization",
+ "vs/language/json/jsonMode"
+ ],
+ "modules": [
+ {
+ "id": "vs/language/json/workerManager",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-workerManager.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/json/languageFeatures",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-languageFeatures.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/json/tokenization",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-tokenization.ts.txt",
+ "resolveJsonc": true
+ },
+ {
+ "id": "vs/language/json/jsonMode",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-json-src-jsonMode.ts.txt",
+ "resolveJsonc": false
+ }
+ ],
+ "config": "refactor/baselines/site-vendor/monaco-languages/monaco-json-src-tsconfig.json.txt"
+ },
+ {
+ "language": "typescript",
+ "name": "tsMode",
+ "development": {
+ "archive": "monaco-editor-0.30.1",
+ "member": "package/dev/vs/language/typescript/tsMode.js",
+ "sha256": "6e360cea797f62d8547a55a6a9f9e51075580ee299e500920c46636a30bd09ef"
+ },
+ "target": {
+ "path": "docs/assets/js/vs/language/typescript/tsMode.js",
+ "sha256": "35d94edaf7982c8b59c95cda38c5ebffcf93479ee91a5c9820b9bf60719351c2"
+ },
+ "ids": [
+ "vs/language/typescript/workerManager",
+ "vs/language/typescript/lib/lib.index",
+ "vs/language/typescript/languageFeatures",
+ "vs/language/typescript/tsMode"
+ ],
+ "modules": [
+ {
+ "id": "vs/language/typescript/workerManager",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-workerManager.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/typescript/lib/lib.index",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-lib-lib.index.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/typescript/languageFeatures",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-languageFeatures.ts.txt",
+ "resolveJsonc": false
+ },
+ {
+ "id": "vs/language/typescript/tsMode",
+ "source": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsMode.ts.txt",
+ "resolveJsonc": false
+ }
+ ],
+ "config": "refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsconfig.json.txt"
+ }
+ ]
+}
diff --git a/refactor/baselines/monaco-modes-validation.json b/refactor/baselines/monaco-modes-validation.json
new file mode 100644
index 000000000..257855f25
--- /dev/null
+++ b/refactor/baselines/monaco-modes-validation.json
@@ -0,0 +1,464 @@
+{
+ "schemaVersion": 1,
+ "task": "SITE-07",
+ "status": "checkpoint-incomplete",
+ "recordedAt": "2026-09-15T01:41:29.392Z",
+ "baseCommit": "99c208aeee331eec2d9ffa9bb15a608fdc17a840",
+ "node": "v24.21.0",
+ "yarn": "1.22.22",
+ "fingerprints": {
+ "sourceRecord": "e360eff36f2d424dd8f6dfcc65a68c9c527216f8bf1dda7635cc8bc52524782a",
+ "noticeRecord": "2bb8c11e6fa5f971a7abf89516dde88abe0d29e1e5e417566505d6f8c7f756da",
+ "manifest": "20c856848f0801d4f6fd66d5b86a37c81bb0b374bf7062b7363602dcc2921971",
+ "runtimeChanges": "No Monaco runtime or notice text changes"
+ },
+ "reproduction": {
+ "result": {
+ "archives": 6,
+ "gitSources": 23,
+ "ownModules": 14,
+ "npmModules": 6,
+ "aliases": 2,
+ "modes": [
+ {
+ "language": "css",
+ "modules": 5,
+ "exactSources": true,
+ "exactOutput": true,
+ "sha256": "c0f3a99395d07b421ef75f6eb78389c6ef29477f6a05556f9b94e2bb918dd6c1"
+ },
+ {
+ "language": "html",
+ "modules": 5,
+ "exactSources": true,
+ "exactOutput": true,
+ "sha256": "91f7b295ddc3b0b679c669b84865f3ace79fdd30bfcd814f2960c06f3e24d600"
+ },
+ {
+ "language": "json",
+ "modules": 12,
+ "exactSources": true,
+ "exactOutput": true,
+ "sha256": "9abacb664dcd8564f28ef004465da0f4b3c551b2741424bf42e61c0a26e61adb"
+ },
+ {
+ "language": "typescript",
+ "modules": 4,
+ "exactSources": true,
+ "exactOutput": true,
+ "sha256": "35d94edaf7982c8b59c95cda38c5ebffcf93479ee91a5c9820b9bf60719351c2"
+ }
+ ],
+ "coreAndBasicLanguagesReviewed": false
+ },
+ "offlineLog": "refactor/.cache/monaco-modes-offline.log",
+ "firstFetch": {
+ "exitCode": 1,
+ "error": "getaddrinfo ENOTFOUND registry.npmjs.org",
+ "log": "refactor/.cache/monaco-modes-fetch.log"
+ },
+ "retryFetch": {
+ "exitCode": 0,
+ "log": "refactor/.cache/monaco-modes-fetch-retry.log"
+ },
+ "workerRegression": {
+ "result": {
+ "archives": 11,
+ "gitSources": 13,
+ "npmModules": 91,
+ "aliases": 8,
+ "workers": [
+ {
+ "language": "css",
+ "modules": 48,
+ "exactSources": true,
+ "exactWorker": true,
+ "sha256": "073e09f9301dcf147e40ef675e3f18d8cc29de9f49673ec8d17711569144552d"
+ },
+ {
+ "language": "html",
+ "modules": 38,
+ "exactSources": true,
+ "exactWorker": true,
+ "sha256": "0b14f0af7ae7ab85732574fb384496dae3e85d28f953188cc842eec468a8a457"
+ },
+ {
+ "language": "json",
+ "modules": 33,
+ "exactSources": true,
+ "exactWorker": true,
+ "sha256": "0eb929c56d44afddb3030c011913010311ce34e5eadb1129a3ce9cbafd4c771d"
+ }
+ ],
+ "notices": 12,
+ "licenseReviewComplete": false,
+ "otherMonacoComponentsReviewed": false
+ },
+ "log": "refactor/.cache/monaco-modes-worker-regression.log"
+ }
+ },
+ "unit": {
+ "passed": 15,
+ "log": "refactor/.cache/monaco-modes-unit.log"
+ },
+ "browser": {
+ "report": "refactor/.cache/browser/report.json",
+ "sha256": "491703cee7accd59f58b154dec0f5841b4195cbe60ee9fe3d64b47efb0fb8b14",
+ "tests": [
+ {
+ "project": "chromium",
+ "title": "docs Monaco mode registrations update editor diagnostics and formatting across languages",
+ "status": "passed",
+ "retry": 0,
+ "browser": "153.0.8010.12",
+ "errors": [],
+ "consoleErrors": [],
+ "failedRequests": [],
+ "results": {
+ "evidence": [
+ {
+ "language": "css",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-css",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-css",
+ "_fsPath": null
+ },
+ "owner": "css",
+ "code": "css-propertyvalueexpected",
+ "severity": 8,
+ "message": "property value expected",
+ "source": "css",
+ "startLineNumber": 1,
+ "startColumn": 12,
+ "endLineNumber": 1,
+ "endColumn": 13
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-json",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-json",
+ "_fsPath": null
+ },
+ "owner": "json",
+ "code": "516",
+ "severity": 8,
+ "message": "Value expected",
+ "source": "json",
+ "startLineNumber": 1,
+ "startColumn": 10,
+ "endLineNumber": 1,
+ "endColumn": 11
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "formatted": "{\r\n \"value\": 1\r\n}"
+ },
+ {
+ "language": "typescript",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-typescript",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-typescript",
+ "_fsPath": null
+ },
+ "owner": "typescript",
+ "code": "2322",
+ "severity": 8,
+ "message": "Type 'string' is not assignable to type 'number'.",
+ "startLineNumber": 1,
+ "startColumn": 7,
+ "endLineNumber": 1,
+ "endColumn": 12,
+ "relatedInformation": [],
+ "tags": []
+ }
+ ]
+ },
+ {
+ "language": "html",
+ "formatted": "
"
+ }
+ ],
+ "loadedModes": [
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/css/cssMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/json/jsonMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/typescript/tsMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/html/htmlMode.js",
+ "status": 200
+ }
+ ]
+ }
+ },
+ {
+ "project": "firefox",
+ "title": "docs Monaco mode registrations update editor diagnostics and formatting across languages",
+ "status": "passed",
+ "retry": 0,
+ "browser": "155.0",
+ "errors": [],
+ "consoleErrors": [],
+ "failedRequests": [],
+ "results": {
+ "evidence": [
+ {
+ "language": "css",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-css",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-css",
+ "_fsPath": null
+ },
+ "owner": "css",
+ "code": "css-propertyvalueexpected",
+ "severity": 8,
+ "message": "property value expected",
+ "source": "css",
+ "startLineNumber": 1,
+ "startColumn": 12,
+ "endLineNumber": 1,
+ "endColumn": 13
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-json",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-json",
+ "_fsPath": null
+ },
+ "owner": "json",
+ "code": "516",
+ "severity": 8,
+ "message": "Value expected",
+ "source": "json",
+ "startLineNumber": 1,
+ "startColumn": 10,
+ "endLineNumber": 1,
+ "endColumn": 11
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "formatted": "{\r\n \"value\": 1\r\n}"
+ },
+ {
+ "language": "typescript",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-typescript",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-typescript",
+ "_fsPath": null
+ },
+ "owner": "typescript",
+ "code": "2322",
+ "severity": 8,
+ "message": "Type 'string' is not assignable to type 'number'.",
+ "startLineNumber": 1,
+ "startColumn": 7,
+ "endLineNumber": 1,
+ "endColumn": 12,
+ "relatedInformation": [],
+ "tags": []
+ }
+ ]
+ },
+ {
+ "language": "html",
+ "formatted": ""
+ }
+ ],
+ "loadedModes": [
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/css/cssMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/json/jsonMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/typescript/tsMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/html/htmlMode.js",
+ "status": 200
+ }
+ ]
+ }
+ },
+ {
+ "project": "webkit",
+ "title": "docs Monaco mode registrations update editor diagnostics and formatting across languages",
+ "status": "passed",
+ "retry": 0,
+ "browser": "26.6",
+ "errors": [],
+ "consoleErrors": [],
+ "failedRequests": [],
+ "results": {
+ "evidence": [
+ {
+ "language": "css",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-css",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-css",
+ "_fsPath": null
+ },
+ "owner": "css",
+ "code": "css-propertyvalueexpected",
+ "severity": 8,
+ "message": "property value expected",
+ "source": "css",
+ "startLineNumber": 1,
+ "startColumn": 12,
+ "endLineNumber": 1,
+ "endColumn": 13
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-json",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-json",
+ "_fsPath": null
+ },
+ "owner": "json",
+ "code": "516",
+ "severity": 8,
+ "message": "Value expected",
+ "source": "json",
+ "startLineNumber": 1,
+ "startColumn": 10,
+ "endLineNumber": 1,
+ "endColumn": 11
+ }
+ ]
+ },
+ {
+ "language": "json",
+ "formatted": "{\n \"value\": 1\n}"
+ },
+ {
+ "language": "typescript",
+ "markers": [
+ {
+ "resource": {
+ "scheme": "file",
+ "authority": "",
+ "path": "/mode-probe-typescript",
+ "query": "",
+ "fragment": "",
+ "_formatted": "file:///mode-probe-typescript",
+ "_fsPath": null
+ },
+ "owner": "typescript",
+ "code": "2322",
+ "severity": 8,
+ "message": "Type 'string' is not assignable to type 'number'.",
+ "startLineNumber": 1,
+ "startColumn": 7,
+ "endLineNumber": 1,
+ "endColumn": 12,
+ "relatedInformation": [],
+ "tags": []
+ }
+ ]
+ },
+ {
+ "language": "html",
+ "formatted": ""
+ }
+ ],
+ "loadedModes": [
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/css/cssMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/json/jsonMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/typescript/tsMode.js",
+ "status": 200
+ },
+ {
+ "url": "http://127.0.0.1:8084/assets/js/vs/language/html/htmlMode.js",
+ "status": 200
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "limitations": [
+ "Exact source emission is not a complete upstream semantic typecheck.",
+ "Editor core/basic-language and remaining embedded origin review remain open.",
+ "No playback, device, external SDK, remote CI or publication verification in this checkpoint.",
+ "Thumbnail compatibility choice remains pending and its defaults unchanged."
+ ]
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-cssMode.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-cssMode.ts.txt
new file mode 100644
index 000000000..ec3ea2603
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-cssMode.ts.txt
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { WorkerManager } from './workerManager';
+import type { CSSWorker } from './cssWorker';
+import { LanguageServiceDefaults } from './monaco.contribution';
+import * as languageFeatures from './languageFeatures';
+import { Uri, IDisposable, languages } from './fillers/monaco-editor-core';
+
+export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
+ const disposables: IDisposable[] = [];
+ const providers: IDisposable[] = [];
+
+ const client = new WorkerManager(defaults);
+ disposables.push(client);
+
+ const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise => {
+ return client.getLanguageServiceWorker(...uris);
+ };
+
+ function registerProviders(): void {
+ const { languageId, modeConfiguration } = defaults;
+
+ disposeAll(providers);
+
+ if (modeConfiguration.completionItems) {
+ providers.push(
+ languages.registerCompletionItemProvider(
+ languageId,
+ new languageFeatures.CompletionAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.hovers) {
+ providers.push(
+ languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))
+ );
+ }
+ if (modeConfiguration.documentHighlights) {
+ providers.push(
+ languages.registerDocumentHighlightProvider(
+ languageId,
+ new languageFeatures.DocumentHighlightAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.definitions) {
+ providers.push(
+ languages.registerDefinitionProvider(
+ languageId,
+ new languageFeatures.DefinitionAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.references) {
+ providers.push(
+ languages.registerReferenceProvider(
+ languageId,
+ new languageFeatures.ReferenceAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.documentSymbols) {
+ providers.push(
+ languages.registerDocumentSymbolProvider(
+ languageId,
+ new languageFeatures.DocumentSymbolAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.rename) {
+ providers.push(
+ languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker))
+ );
+ }
+ if (modeConfiguration.colors) {
+ providers.push(
+ languages.registerColorProvider(
+ languageId,
+ new languageFeatures.DocumentColorAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.foldingRanges) {
+ providers.push(
+ languages.registerFoldingRangeProvider(
+ languageId,
+ new languageFeatures.FoldingRangeAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.diagnostics) {
+ providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults));
+ }
+ if (modeConfiguration.selectionRanges) {
+ providers.push(
+ languages.registerSelectionRangeProvider(
+ languageId,
+ new languageFeatures.SelectionRangeAdapter(worker)
+ )
+ );
+ }
+ }
+
+ registerProviders();
+
+ disposables.push(asDisposable(providers));
+
+ return asDisposable(disposables);
+}
+
+function asDisposable(disposables: IDisposable[]): IDisposable {
+ return { dispose: () => disposeAll(disposables) };
+}
+
+function disposeAll(disposables: IDisposable[]) {
+ while (disposables.length) {
+ disposables.pop().dispose();
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-languageFeatures.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-languageFeatures.ts.txt
new file mode 100644
index 000000000..462521c8a
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-languageFeatures.ts.txt
@@ -0,0 +1,725 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { CSSWorker } from './cssWorker';
+import * as lsTypes from 'vscode-languageserver-types';
+import {
+ languages,
+ editor,
+ IMarkdownString,
+ Uri,
+ Position,
+ IRange,
+ Range,
+ CancellationToken,
+ IDisposable,
+ MarkerSeverity
+} from './fillers/monaco-editor-core';
+import { TextEdit } from 'vscode-css-languageservice';
+import { InsertReplaceEdit } from 'vscode-languageserver-types';
+
+export interface WorkerAccessor {
+ (first: Uri, ...more: Uri[]): Promise;
+}
+
+// --- diagnostics --- ---
+
+export class DiagnosticsAdapter {
+ private _disposables: IDisposable[] = [];
+ private _listener: { [uri: string]: IDisposable } = Object.create(null);
+
+ constructor(
+ private _languageId: string,
+ private _worker: WorkerAccessor,
+ defaults: LanguageServiceDefaults
+ ) {
+ const onModelAdd = (model: editor.IModel): void => {
+ let modeId = model.getLanguageId();
+ if (modeId !== this._languageId) {
+ return;
+ }
+
+ let handle: number;
+ this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
+ window.clearTimeout(handle);
+ handle = window.setTimeout(() => this._doValidate(model.uri, modeId), 500);
+ });
+
+ this._doValidate(model.uri, modeId);
+ };
+
+ const onModelRemoved = (model: editor.IModel): void => {
+ editor.setModelMarkers(model, this._languageId, []);
+
+ let uriStr = model.uri.toString();
+ let listener = this._listener[uriStr];
+ if (listener) {
+ listener.dispose();
+ delete this._listener[uriStr];
+ }
+ };
+
+ this._disposables.push(editor.onDidCreateModel(onModelAdd));
+ this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
+ this._disposables.push(
+ editor.onDidChangeModelLanguage((event) => {
+ onModelRemoved(event.model);
+ onModelAdd(event.model);
+ })
+ );
+
+ defaults.onDidChange((_) => {
+ editor.getModels().forEach((model) => {
+ if (model.getLanguageId() === this._languageId) {
+ onModelRemoved(model);
+ onModelAdd(model);
+ }
+ });
+ });
+
+ this._disposables.push({
+ dispose: () => {
+ for (let key in this._listener) {
+ this._listener[key].dispose();
+ }
+ }
+ });
+
+ editor.getModels().forEach(onModelAdd);
+ }
+
+ public dispose(): void {
+ this._disposables.forEach((d) => d && d.dispose());
+ this._disposables = [];
+ }
+
+ private _doValidate(resource: Uri, languageId: string): void {
+ this._worker(resource)
+ .then((worker) => {
+ return worker.doValidation(resource.toString());
+ })
+ .then((diagnostics) => {
+ const markers = diagnostics.map((d) => toDiagnostics(resource, d));
+ let model = editor.getModel(resource);
+ if (model && model.getLanguageId() === languageId) {
+ editor.setModelMarkers(model, languageId, markers);
+ }
+ })
+ .then(undefined, (err) => {
+ console.error(err);
+ });
+ }
+}
+
+function toSeverity(lsSeverity: number): MarkerSeverity {
+ switch (lsSeverity) {
+ case lsTypes.DiagnosticSeverity.Error:
+ return MarkerSeverity.Error;
+ case lsTypes.DiagnosticSeverity.Warning:
+ return MarkerSeverity.Warning;
+ case lsTypes.DiagnosticSeverity.Information:
+ return MarkerSeverity.Info;
+ case lsTypes.DiagnosticSeverity.Hint:
+ return MarkerSeverity.Hint;
+ default:
+ return MarkerSeverity.Info;
+ }
+}
+
+function toDiagnostics(resource: Uri, diag: lsTypes.Diagnostic): editor.IMarkerData {
+ let code = typeof diag.code === 'number' ? String(diag.code) : diag.code;
+
+ return {
+ severity: toSeverity(diag.severity),
+ startLineNumber: diag.range.start.line + 1,
+ startColumn: diag.range.start.character + 1,
+ endLineNumber: diag.range.end.line + 1,
+ endColumn: diag.range.end.character + 1,
+ message: diag.message,
+ code: code,
+ source: diag.source
+ };
+}
+
+// --- completion ------
+
+function fromPosition(position: Position): lsTypes.Position {
+ if (!position) {
+ return void 0;
+ }
+ return { character: position.column - 1, line: position.lineNumber - 1 };
+}
+
+function fromRange(range: IRange): lsTypes.Range {
+ if (!range) {
+ return void 0;
+ }
+ return {
+ start: {
+ line: range.startLineNumber - 1,
+ character: range.startColumn - 1
+ },
+ end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
+ };
+}
+
+function toRange(range: lsTypes.Range): Range {
+ if (!range) {
+ return void 0;
+ }
+ return new Range(
+ range.start.line + 1,
+ range.start.character + 1,
+ range.end.line + 1,
+ range.end.character + 1
+ );
+}
+
+function isInsertReplaceEdit(edit: TextEdit | InsertReplaceEdit): edit is InsertReplaceEdit {
+ return (
+ typeof (edit).insert !== 'undefined' &&
+ typeof (edit).replace !== 'undefined'
+ );
+}
+
+function toCompletionItemKind(kind: number): languages.CompletionItemKind {
+ let mItemKind = languages.CompletionItemKind;
+
+ switch (kind) {
+ case lsTypes.CompletionItemKind.Text:
+ return mItemKind.Text;
+ case lsTypes.CompletionItemKind.Method:
+ return mItemKind.Method;
+ case lsTypes.CompletionItemKind.Function:
+ return mItemKind.Function;
+ case lsTypes.CompletionItemKind.Constructor:
+ return mItemKind.Constructor;
+ case lsTypes.CompletionItemKind.Field:
+ return mItemKind.Field;
+ case lsTypes.CompletionItemKind.Variable:
+ return mItemKind.Variable;
+ case lsTypes.CompletionItemKind.Class:
+ return mItemKind.Class;
+ case lsTypes.CompletionItemKind.Interface:
+ return mItemKind.Interface;
+ case lsTypes.CompletionItemKind.Module:
+ return mItemKind.Module;
+ case lsTypes.CompletionItemKind.Property:
+ return mItemKind.Property;
+ case lsTypes.CompletionItemKind.Unit:
+ return mItemKind.Unit;
+ case lsTypes.CompletionItemKind.Value:
+ return mItemKind.Value;
+ case lsTypes.CompletionItemKind.Enum:
+ return mItemKind.Enum;
+ case lsTypes.CompletionItemKind.Keyword:
+ return mItemKind.Keyword;
+ case lsTypes.CompletionItemKind.Snippet:
+ return mItemKind.Snippet;
+ case lsTypes.CompletionItemKind.Color:
+ return mItemKind.Color;
+ case lsTypes.CompletionItemKind.File:
+ return mItemKind.File;
+ case lsTypes.CompletionItemKind.Reference:
+ return mItemKind.Reference;
+ }
+ return mItemKind.Property;
+}
+
+function toTextEdit(textEdit: lsTypes.TextEdit): editor.ISingleEditOperation {
+ if (!textEdit) {
+ return void 0;
+ }
+ return {
+ range: toRange(textEdit.range),
+ text: textEdit.newText
+ };
+}
+
+function toCommand(c: lsTypes.Command | undefined): languages.Command {
+ return c && c.command === 'editor.action.triggerSuggest'
+ ? { id: c.command, title: c.title, arguments: c.arguments }
+ : undefined;
+}
+
+export class CompletionAdapter implements languages.CompletionItemProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public get triggerCharacters(): string[] {
+ return ['/', '-', ':'];
+ }
+
+ provideCompletionItems(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ context: languages.CompletionContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doComplete(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ const wordInfo = model.getWordUntilPosition(position);
+ const wordRange = new Range(
+ position.lineNumber,
+ wordInfo.startColumn,
+ position.lineNumber,
+ wordInfo.endColumn
+ );
+
+ let items: languages.CompletionItem[] = info.items.map((entry) => {
+ let item: languages.CompletionItem = {
+ label: entry.label,
+ insertText: entry.insertText || entry.label,
+ sortText: entry.sortText,
+ filterText: entry.filterText,
+ documentation: entry.documentation,
+ detail: entry.detail,
+ command: toCommand(entry.command),
+ range: wordRange,
+ kind: toCompletionItemKind(entry.kind)
+ };
+ if (entry.textEdit) {
+ if (isInsertReplaceEdit(entry.textEdit)) {
+ item.range = {
+ insert: toRange(entry.textEdit.insert),
+ replace: toRange(entry.textEdit.replace)
+ };
+ } else {
+ item.range = toRange(entry.textEdit.range);
+ }
+ item.insertText = entry.textEdit.newText;
+ }
+ if (entry.additionalTextEdits) {
+ item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit);
+ }
+ if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
+ item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
+ }
+ return item;
+ });
+
+ return {
+ isIncomplete: info.isIncomplete,
+ suggestions: items
+ };
+ });
+ }
+}
+
+function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
+ return (
+ thing && typeof thing === 'object' && typeof (thing).kind === 'string'
+ );
+}
+
+function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString {
+ if (typeof entry === 'string') {
+ return {
+ value: entry
+ };
+ }
+ if (isMarkupContent(entry)) {
+ if (entry.kind === 'plaintext') {
+ return {
+ value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
+ };
+ }
+ return {
+ value: entry.value
+ };
+ }
+
+ return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
+}
+
+function toMarkedStringArray(
+ contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[]
+): IMarkdownString[] {
+ if (!contents) {
+ return void 0;
+ }
+ if (Array.isArray(contents)) {
+ return contents.map(toMarkdownString);
+ }
+ return [toMarkdownString(contents)];
+}
+
+// --- hover ------
+
+export class HoverAdapter implements languages.HoverProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideHover(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ let resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doHover(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ return {
+ range: toRange(info.range),
+ contents: toMarkedStringArray(info.contents)
+ };
+ });
+ }
+}
+
+// --- document highlights ------
+
+function toDocumentHighlightKind(kind: number): languages.DocumentHighlightKind {
+ switch (kind) {
+ case lsTypes.DocumentHighlightKind.Read:
+ return languages.DocumentHighlightKind.Read;
+ case lsTypes.DocumentHighlightKind.Write:
+ return languages.DocumentHighlightKind.Write;
+ case lsTypes.DocumentHighlightKind.Text:
+ return languages.DocumentHighlightKind.Text;
+ }
+ return languages.DocumentHighlightKind.Text;
+}
+
+export class DocumentHighlightAdapter implements languages.DocumentHighlightProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentHighlights(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.findDocumentHighlights(resource.toString(), fromPosition(position));
+ })
+ .then((entries) => {
+ if (!entries) {
+ return;
+ }
+ return entries.map((entry) => {
+ return {
+ range: toRange(entry.range),
+ kind: toDocumentHighlightKind(entry.kind)
+ };
+ });
+ });
+ }
+}
+
+// --- definition ------
+
+function toLocation(location: lsTypes.Location): languages.Location {
+ return {
+ uri: Uri.parse(location.uri),
+ range: toRange(location.range)
+ };
+}
+
+export class DefinitionAdapter {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDefinition(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.findDefinition(resource.toString(), fromPosition(position));
+ })
+ .then((definition) => {
+ if (!definition) {
+ return;
+ }
+ return [toLocation(definition)];
+ });
+ }
+}
+
+// --- references ------
+
+export class ReferenceAdapter implements languages.ReferenceProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideReferences(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ context: languages.ReferenceContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.findReferences(resource.toString(), fromPosition(position));
+ })
+ .then((entries) => {
+ if (!entries) {
+ return;
+ }
+ return entries.map(toLocation);
+ });
+ }
+}
+
+// --- rename ------
+
+function toWorkspaceEdit(edit: lsTypes.WorkspaceEdit): languages.WorkspaceEdit {
+ if (!edit || !edit.changes) {
+ return void 0;
+ }
+ let resourceEdits: languages.WorkspaceTextEdit[] = [];
+ for (let uri in edit.changes) {
+ const _uri = Uri.parse(uri);
+ // let edits: languages.TextEdit[] = [];
+ for (let e of edit.changes[uri]) {
+ resourceEdits.push({
+ resource: _uri,
+ edit: {
+ range: toRange(e.range),
+ text: e.newText
+ }
+ });
+ }
+ }
+ return {
+ edits: resourceEdits
+ };
+}
+
+export class RenameAdapter implements languages.RenameProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideRenameEdits(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ newName: string,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doRename(resource.toString(), fromPosition(position), newName);
+ })
+ .then((edit) => {
+ return toWorkspaceEdit(edit);
+ });
+ }
+}
+
+// --- document symbols ------
+
+function toSymbolKind(kind: lsTypes.SymbolKind): languages.SymbolKind {
+ let mKind = languages.SymbolKind;
+
+ switch (kind) {
+ case lsTypes.SymbolKind.File:
+ return mKind.Array;
+ case lsTypes.SymbolKind.Module:
+ return mKind.Module;
+ case lsTypes.SymbolKind.Namespace:
+ return mKind.Namespace;
+ case lsTypes.SymbolKind.Package:
+ return mKind.Package;
+ case lsTypes.SymbolKind.Class:
+ return mKind.Class;
+ case lsTypes.SymbolKind.Method:
+ return mKind.Method;
+ case lsTypes.SymbolKind.Property:
+ return mKind.Property;
+ case lsTypes.SymbolKind.Field:
+ return mKind.Field;
+ case lsTypes.SymbolKind.Constructor:
+ return mKind.Constructor;
+ case lsTypes.SymbolKind.Enum:
+ return mKind.Enum;
+ case lsTypes.SymbolKind.Interface:
+ return mKind.Interface;
+ case lsTypes.SymbolKind.Function:
+ return mKind.Function;
+ case lsTypes.SymbolKind.Variable:
+ return mKind.Variable;
+ case lsTypes.SymbolKind.Constant:
+ return mKind.Constant;
+ case lsTypes.SymbolKind.String:
+ return mKind.String;
+ case lsTypes.SymbolKind.Number:
+ return mKind.Number;
+ case lsTypes.SymbolKind.Boolean:
+ return mKind.Boolean;
+ case lsTypes.SymbolKind.Array:
+ return mKind.Array;
+ }
+ return mKind.Function;
+}
+
+export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentSymbols(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentSymbols(resource.toString()))
+ .then((items) => {
+ if (!items) {
+ return;
+ }
+ return items.map((item) => ({
+ name: item.name,
+ detail: '',
+ containerName: item.containerName,
+ kind: toSymbolKind(item.kind),
+ tags: [],
+ range: toRange(item.location.range),
+ selectionRange: toRange(item.location.range)
+ }));
+ });
+ }
+}
+
+export class DocumentColorAdapter implements languages.DocumentColorProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentColors(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentColors(resource.toString()))
+ .then((infos) => {
+ if (!infos) {
+ return;
+ }
+ return infos.map((item) => ({
+ color: item.color,
+ range: toRange(item.range)
+ }));
+ });
+ }
+
+ public provideColorPresentations(
+ model: editor.IReadOnlyModel,
+ info: languages.IColorInformation,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) =>
+ worker.getColorPresentations(resource.toString(), info.color, fromRange(info.range))
+ )
+ .then((presentations) => {
+ if (!presentations) {
+ return;
+ }
+ return presentations.map((presentation) => {
+ let item: languages.IColorPresentation = {
+ label: presentation.label
+ };
+ if (presentation.textEdit) {
+ item.textEdit = toTextEdit(presentation.textEdit);
+ }
+ if (presentation.additionalTextEdits) {
+ item.additionalTextEdits = presentation.additionalTextEdits.map(toTextEdit);
+ }
+ return item;
+ });
+ });
+ }
+}
+
+export class FoldingRangeAdapter implements languages.FoldingRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideFoldingRanges(
+ model: editor.IReadOnlyModel,
+ context: languages.FoldingContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getFoldingRanges(resource.toString(), context))
+ .then((ranges) => {
+ if (!ranges) {
+ return;
+ }
+ return ranges.map((range) => {
+ let result: languages.FoldingRange = {
+ start: range.startLine + 1,
+ end: range.endLine + 1
+ };
+ if (typeof range.kind !== 'undefined') {
+ result.kind = toFoldingRangeKind(range.kind);
+ }
+ return result;
+ });
+ });
+ }
+}
+
+function toFoldingRangeKind(kind: lsTypes.FoldingRangeKind): languages.FoldingRangeKind {
+ switch (kind) {
+ case lsTypes.FoldingRangeKind.Comment:
+ return languages.FoldingRangeKind.Comment;
+ case lsTypes.FoldingRangeKind.Imports:
+ return languages.FoldingRangeKind.Imports;
+ case lsTypes.FoldingRangeKind.Region:
+ return languages.FoldingRangeKind.Region;
+ }
+}
+
+export class SelectionRangeAdapter implements languages.SelectionRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideSelectionRanges(
+ model: editor.IReadOnlyModel,
+ positions: Position[],
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition)))
+ .then((selectionRanges) => {
+ if (!selectionRanges) {
+ return;
+ }
+ return selectionRanges.map((selectionRange) => {
+ const result: languages.SelectionRange[] = [];
+ while (selectionRange) {
+ result.push({ range: toRange(selectionRange.range) });
+ selectionRange = selectionRange.parent;
+ }
+ return result;
+ });
+ });
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-workerManager.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-workerManager.ts.txt
new file mode 100644
index 000000000..335396d5d
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-css-src-workerManager.ts.txt
@@ -0,0 +1,87 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { CSSWorker } from './cssWorker';
+import { editor, IDisposable, Uri } from './fillers/monaco-editor-core';
+
+const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
+
+export class WorkerManager {
+ private _defaults: LanguageServiceDefaults;
+ private _idleCheckInterval: number;
+ private _lastUsedTime: number;
+ private _configChangeListener: IDisposable;
+
+ private _worker: editor.MonacoWebWorker;
+ private _client: Promise;
+
+ constructor(defaults: LanguageServiceDefaults) {
+ this._defaults = defaults;
+ this._worker = null;
+ this._idleCheckInterval = window.setInterval(() => this._checkIfIdle(), 30 * 1000);
+ this._lastUsedTime = 0;
+ this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
+ }
+
+ private _stopWorker(): void {
+ if (this._worker) {
+ this._worker.dispose();
+ this._worker = null;
+ }
+ this._client = null;
+ }
+
+ dispose(): void {
+ clearInterval(this._idleCheckInterval);
+ this._configChangeListener.dispose();
+ this._stopWorker();
+ }
+
+ private _checkIfIdle(): void {
+ if (!this._worker) {
+ return;
+ }
+ let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
+ if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
+ this._stopWorker();
+ }
+ }
+
+ private _getClient(): Promise {
+ this._lastUsedTime = Date.now();
+
+ if (!this._client) {
+ this._worker = editor.createWebWorker({
+ // module that exports the create() method and returns a `CSSWorker` instance
+ moduleId: 'vs/language/css/cssWorker',
+
+ label: this._defaults.languageId,
+
+ // passed in to the create() method
+ createData: {
+ options: this._defaults.options,
+ languageId: this._defaults.languageId
+ }
+ });
+
+ this._client = >(this._worker.getProxy());
+ }
+
+ return this._client;
+ }
+
+ getLanguageServiceWorker(...resources: Uri[]): Promise {
+ let _client: CSSWorker;
+ return this._getClient()
+ .then((client) => {
+ _client = client;
+ })
+ .then((_) => {
+ return this._worker.withSyncedResources(resources);
+ })
+ .then((_) => _client);
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-htmlMode.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-htmlMode.ts.txt
new file mode 100644
index 000000000..95b560cb3
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-htmlMode.ts.txt
@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { WorkerManager } from './workerManager';
+import type { HTMLWorker } from './htmlWorker';
+import { LanguageServiceDefaults } from './monaco.contribution';
+import * as languageFeatures from './languageFeatures';
+import { Uri, IDisposable, languages } from './fillers/monaco-editor-core';
+
+export function setupMode1(defaults: LanguageServiceDefaults): void {
+ const client = new WorkerManager(defaults);
+
+ const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise => {
+ return client.getLanguageServiceWorker(...uris);
+ };
+
+ let languageId = defaults.languageId;
+
+ // all modes
+ languages.registerCompletionItemProvider(
+ languageId,
+ new languageFeatures.CompletionAdapter(worker)
+ );
+ languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker));
+
+ languages.registerDocumentHighlightProvider(
+ languageId,
+ new languageFeatures.DocumentHighlightAdapter(worker)
+ );
+ languages.registerLinkProvider(languageId, new languageFeatures.DocumentLinkAdapter(worker));
+ languages.registerFoldingRangeProvider(
+ languageId,
+ new languageFeatures.FoldingRangeAdapter(worker)
+ );
+ languages.registerDocumentSymbolProvider(
+ languageId,
+ new languageFeatures.DocumentSymbolAdapter(worker)
+ );
+ languages.registerSelectionRangeProvider(
+ languageId,
+ new languageFeatures.SelectionRangeAdapter(worker)
+ );
+ languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker));
+
+ // only html
+ if (languageId === 'html') {
+ languages.registerDocumentFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentFormattingEditProvider(worker)
+ );
+ languages.registerDocumentRangeFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+ );
+ }
+}
+
+export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
+ const disposables: IDisposable[] = [];
+ const providers: IDisposable[] = [];
+
+ const client = new WorkerManager(defaults);
+ disposables.push(client);
+
+ const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise => {
+ return client.getLanguageServiceWorker(...uris);
+ };
+
+ function registerProviders(): void {
+ const { languageId, modeConfiguration } = defaults;
+
+ disposeAll(providers);
+
+ if (modeConfiguration.completionItems) {
+ providers.push(
+ languages.registerCompletionItemProvider(
+ languageId,
+ new languageFeatures.CompletionAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.hovers) {
+ providers.push(
+ languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))
+ );
+ }
+ if (modeConfiguration.documentHighlights) {
+ providers.push(
+ languages.registerDocumentHighlightProvider(
+ languageId,
+ new languageFeatures.DocumentHighlightAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.links) {
+ providers.push(
+ languages.registerLinkProvider(languageId, new languageFeatures.DocumentLinkAdapter(worker))
+ );
+ }
+ if (modeConfiguration.documentSymbols) {
+ providers.push(
+ languages.registerDocumentSymbolProvider(
+ languageId,
+ new languageFeatures.DocumentSymbolAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.rename) {
+ providers.push(
+ languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker))
+ );
+ }
+ if (modeConfiguration.foldingRanges) {
+ providers.push(
+ languages.registerFoldingRangeProvider(
+ languageId,
+ new languageFeatures.FoldingRangeAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.selectionRanges) {
+ providers.push(
+ languages.registerSelectionRangeProvider(
+ languageId,
+ new languageFeatures.SelectionRangeAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.documentFormattingEdits) {
+ providers.push(
+ languages.registerDocumentFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentFormattingEditProvider(worker)
+ )
+ );
+ }
+ if (modeConfiguration.documentRangeFormattingEdits) {
+ providers.push(
+ languages.registerDocumentRangeFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+ )
+ );
+ }
+ }
+
+ registerProviders();
+
+ disposables.push(asDisposable(providers));
+
+ return asDisposable(disposables);
+}
+
+function asDisposable(disposables: IDisposable[]): IDisposable {
+ return { dispose: () => disposeAll(disposables) };
+}
+
+function disposeAll(disposables: IDisposable[]) {
+ while (disposables.length) {
+ disposables.pop().dispose();
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-languageFeatures.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-languageFeatures.ts.txt
new file mode 100644
index 000000000..2d6ec0340
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-languageFeatures.ts.txt
@@ -0,0 +1,608 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import type { HTMLWorker } from './htmlWorker';
+import * as lsTypes from 'vscode-languageserver-types';
+import {
+ languages,
+ editor,
+ Uri,
+ Position,
+ Range,
+ CancellationToken,
+ IMarkdownString
+} from './fillers/monaco-editor-core';
+
+export interface WorkerAccessor {
+ (...more: Uri[]): Promise;
+}
+
+// --- completion ------
+
+function fromPosition(position: Position): lsTypes.Position {
+ if (!position) {
+ return void 0;
+ }
+ return { character: position.column - 1, line: position.lineNumber - 1 };
+}
+
+function fromRange(range: Range): lsTypes.Range {
+ if (!range) {
+ return void 0;
+ }
+ return {
+ start: fromPosition(range.getStartPosition()),
+ end: fromPosition(range.getEndPosition())
+ };
+}
+
+function toRange(range: lsTypes.Range): Range {
+ if (!range) {
+ return void 0;
+ }
+ return new Range(
+ range.start.line + 1,
+ range.start.character + 1,
+ range.end.line + 1,
+ range.end.character + 1
+ );
+}
+
+function isInsertReplaceEdit(
+ edit: lsTypes.TextEdit | lsTypes.InsertReplaceEdit
+): edit is lsTypes.InsertReplaceEdit {
+ return (
+ typeof (edit).insert !== 'undefined' &&
+ typeof (edit).replace !== 'undefined'
+ );
+}
+
+function toCompletionItemKind(kind: number): languages.CompletionItemKind {
+ const mItemKind = languages.CompletionItemKind;
+
+ switch (kind) {
+ case lsTypes.CompletionItemKind.Text:
+ return mItemKind.Text;
+ case lsTypes.CompletionItemKind.Method:
+ return mItemKind.Method;
+ case lsTypes.CompletionItemKind.Function:
+ return mItemKind.Function;
+ case lsTypes.CompletionItemKind.Constructor:
+ return mItemKind.Constructor;
+ case lsTypes.CompletionItemKind.Field:
+ return mItemKind.Field;
+ case lsTypes.CompletionItemKind.Variable:
+ return mItemKind.Variable;
+ case lsTypes.CompletionItemKind.Class:
+ return mItemKind.Class;
+ case lsTypes.CompletionItemKind.Interface:
+ return mItemKind.Interface;
+ case lsTypes.CompletionItemKind.Module:
+ return mItemKind.Module;
+ case lsTypes.CompletionItemKind.Property:
+ return mItemKind.Property;
+ case lsTypes.CompletionItemKind.Unit:
+ return mItemKind.Unit;
+ case lsTypes.CompletionItemKind.Value:
+ return mItemKind.Value;
+ case lsTypes.CompletionItemKind.Enum:
+ return mItemKind.Enum;
+ case lsTypes.CompletionItemKind.Keyword:
+ return mItemKind.Keyword;
+ case lsTypes.CompletionItemKind.Snippet:
+ return mItemKind.Snippet;
+ case lsTypes.CompletionItemKind.Color:
+ return mItemKind.Color;
+ case lsTypes.CompletionItemKind.File:
+ return mItemKind.File;
+ case lsTypes.CompletionItemKind.Reference:
+ return mItemKind.Reference;
+ }
+ return mItemKind.Property;
+}
+
+function fromCompletionItemKind(kind: languages.CompletionItemKind): lsTypes.CompletionItemKind {
+ const mItemKind = languages.CompletionItemKind;
+
+ switch (kind) {
+ case mItemKind.Text:
+ return lsTypes.CompletionItemKind.Text;
+ case mItemKind.Method:
+ return lsTypes.CompletionItemKind.Method;
+ case mItemKind.Function:
+ return lsTypes.CompletionItemKind.Function;
+ case mItemKind.Constructor:
+ return lsTypes.CompletionItemKind.Constructor;
+ case mItemKind.Field:
+ return lsTypes.CompletionItemKind.Field;
+ case mItemKind.Variable:
+ return lsTypes.CompletionItemKind.Variable;
+ case mItemKind.Class:
+ return lsTypes.CompletionItemKind.Class;
+ case mItemKind.Interface:
+ return lsTypes.CompletionItemKind.Interface;
+ case mItemKind.Module:
+ return lsTypes.CompletionItemKind.Module;
+ case mItemKind.Property:
+ return lsTypes.CompletionItemKind.Property;
+ case mItemKind.Unit:
+ return lsTypes.CompletionItemKind.Unit;
+ case mItemKind.Value:
+ return lsTypes.CompletionItemKind.Value;
+ case mItemKind.Enum:
+ return lsTypes.CompletionItemKind.Enum;
+ case mItemKind.Keyword:
+ return lsTypes.CompletionItemKind.Keyword;
+ case mItemKind.Snippet:
+ return lsTypes.CompletionItemKind.Snippet;
+ case mItemKind.Color:
+ return lsTypes.CompletionItemKind.Color;
+ case mItemKind.File:
+ return lsTypes.CompletionItemKind.File;
+ case mItemKind.Reference:
+ return lsTypes.CompletionItemKind.Reference;
+ }
+ return lsTypes.CompletionItemKind.Property;
+}
+
+function toTextEdit(textEdit: lsTypes.TextEdit): editor.ISingleEditOperation {
+ if (!textEdit) {
+ return void 0;
+ }
+ return {
+ range: toRange(textEdit.range),
+ text: textEdit.newText
+ };
+}
+
+function toCommand(c: lsTypes.Command | undefined): languages.Command {
+ return c && c.command === 'editor.action.triggerSuggest'
+ ? { id: c.command, title: c.title, arguments: c.arguments }
+ : undefined;
+}
+
+export class CompletionAdapter implements languages.CompletionItemProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public get triggerCharacters(): string[] {
+ return ['.', ':', '<', '"', '=', '/'];
+ }
+
+ provideCompletionItems(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ context: languages.CompletionContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doComplete(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ const wordInfo = model.getWordUntilPosition(position);
+ const wordRange = new Range(
+ position.lineNumber,
+ wordInfo.startColumn,
+ position.lineNumber,
+ wordInfo.endColumn
+ );
+
+ const items: languages.CompletionItem[] = info.items.map((entry) => {
+ const item: languages.CompletionItem = {
+ label: entry.label,
+ insertText: entry.insertText || entry.label,
+ sortText: entry.sortText,
+ filterText: entry.filterText,
+ documentation: entry.documentation,
+ command: toCommand(entry.command),
+ detail: entry.detail,
+ range: wordRange,
+ kind: toCompletionItemKind(entry.kind)
+ };
+ if (entry.textEdit) {
+ if (isInsertReplaceEdit(entry.textEdit)) {
+ item.range = {
+ insert: toRange(entry.textEdit.insert),
+ replace: toRange(entry.textEdit.replace)
+ };
+ } else {
+ item.range = toRange(entry.textEdit.range);
+ }
+ item.insertText = entry.textEdit.newText;
+ }
+ if (entry.additionalTextEdits) {
+ item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit);
+ }
+ if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
+ item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
+ }
+ return item;
+ });
+
+ return {
+ isIncomplete: info.isIncomplete,
+ suggestions: items
+ };
+ });
+ }
+}
+
+// --- hover ------
+
+function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
+ return (
+ thing && typeof thing === 'object' && typeof (thing).kind === 'string'
+ );
+}
+
+function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString {
+ if (typeof entry === 'string') {
+ return {
+ value: entry
+ };
+ }
+ if (isMarkupContent(entry)) {
+ if (entry.kind === 'plaintext') {
+ return {
+ value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
+ };
+ }
+ return {
+ value: entry.value
+ };
+ }
+
+ return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
+}
+
+function toMarkedStringArray(
+ contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[]
+): IMarkdownString[] {
+ if (!contents) {
+ return void 0;
+ }
+ if (Array.isArray(contents)) {
+ return contents.map(toMarkdownString);
+ }
+ return [toMarkdownString(contents)];
+}
+
+export class HoverAdapter implements languages.HoverProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideHover(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ let resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doHover(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ return {
+ range: toRange(info.range),
+ contents: toMarkedStringArray(info.contents)
+ };
+ });
+ }
+}
+
+// --- document highlights ------
+
+function toHighlighKind(kind: lsTypes.DocumentHighlightKind): languages.DocumentHighlightKind {
+ const mKind = languages.DocumentHighlightKind;
+
+ switch (kind) {
+ case lsTypes.DocumentHighlightKind.Read:
+ return mKind.Read;
+ case lsTypes.DocumentHighlightKind.Write:
+ return mKind.Write;
+ case lsTypes.DocumentHighlightKind.Text:
+ return mKind.Text;
+ }
+ return mKind.Text;
+}
+
+export class DocumentHighlightAdapter implements languages.DocumentHighlightProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentHighlights(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentHighlights(resource.toString(), fromPosition(position)))
+ .then((items) => {
+ if (!items) {
+ return;
+ }
+ return items.map((item) => ({
+ range: toRange(item.range),
+ kind: toHighlighKind(item.kind)
+ }));
+ });
+ }
+}
+
+// --- document symbols ------
+
+function toSymbolKind(kind: lsTypes.SymbolKind): languages.SymbolKind {
+ let mKind = languages.SymbolKind;
+
+ switch (kind) {
+ case lsTypes.SymbolKind.File:
+ return mKind.Array;
+ case lsTypes.SymbolKind.Module:
+ return mKind.Module;
+ case lsTypes.SymbolKind.Namespace:
+ return mKind.Namespace;
+ case lsTypes.SymbolKind.Package:
+ return mKind.Package;
+ case lsTypes.SymbolKind.Class:
+ return mKind.Class;
+ case lsTypes.SymbolKind.Method:
+ return mKind.Method;
+ case lsTypes.SymbolKind.Property:
+ return mKind.Property;
+ case lsTypes.SymbolKind.Field:
+ return mKind.Field;
+ case lsTypes.SymbolKind.Constructor:
+ return mKind.Constructor;
+ case lsTypes.SymbolKind.Enum:
+ return mKind.Enum;
+ case lsTypes.SymbolKind.Interface:
+ return mKind.Interface;
+ case lsTypes.SymbolKind.Function:
+ return mKind.Function;
+ case lsTypes.SymbolKind.Variable:
+ return mKind.Variable;
+ case lsTypes.SymbolKind.Constant:
+ return mKind.Constant;
+ case lsTypes.SymbolKind.String:
+ return mKind.String;
+ case lsTypes.SymbolKind.Number:
+ return mKind.Number;
+ case lsTypes.SymbolKind.Boolean:
+ return mKind.Boolean;
+ case lsTypes.SymbolKind.Array:
+ return mKind.Array;
+ }
+ return mKind.Function;
+}
+
+export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentSymbols(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentSymbols(resource.toString()))
+ .then((items) => {
+ if (!items) {
+ return;
+ }
+ return items.map((item) => ({
+ name: item.name,
+ detail: '',
+ containerName: item.containerName,
+ kind: toSymbolKind(item.kind),
+ tags: [],
+ range: toRange(item.location.range),
+ selectionRange: toRange(item.location.range)
+ }));
+ });
+ }
+}
+
+export class DocumentLinkAdapter implements languages.LinkProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideLinks(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentLinks(resource.toString()))
+ .then((items) => {
+ if (!items) {
+ return;
+ }
+ return {
+ links: items.map((item) => ({
+ range: toRange(item.range),
+ url: item.target
+ }))
+ };
+ });
+ }
+}
+
+function fromFormattingOptions(options: languages.FormattingOptions): lsTypes.FormattingOptions {
+ return {
+ tabSize: options.tabSize,
+ insertSpaces: options.insertSpaces
+ };
+}
+
+export class DocumentFormattingEditProvider implements languages.DocumentFormattingEditProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentFormattingEdits(
+ model: editor.IReadOnlyModel,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource).then((worker) => {
+ return worker
+ .format(resource.toString(), null, fromFormattingOptions(options))
+ .then((edits) => {
+ if (!edits || edits.length === 0) {
+ return;
+ }
+ return edits.map(toTextEdit);
+ });
+ });
+ }
+}
+
+export class DocumentRangeFormattingEditProvider
+ implements languages.DocumentRangeFormattingEditProvider
+{
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentRangeFormattingEdits(
+ model: editor.IReadOnlyModel,
+ range: Range,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource).then((worker) => {
+ return worker
+ .format(resource.toString(), fromRange(range), fromFormattingOptions(options))
+ .then((edits) => {
+ if (!edits || edits.length === 0) {
+ return;
+ }
+ return edits.map(toTextEdit);
+ });
+ });
+ }
+}
+
+export class RenameAdapter implements languages.RenameProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideRenameEdits(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ newName: string,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doRename(resource.toString(), fromPosition(position), newName);
+ })
+ .then((edit) => {
+ return toWorkspaceEdit(edit);
+ });
+ }
+}
+
+function toWorkspaceEdit(edit: lsTypes.WorkspaceEdit): languages.WorkspaceEdit {
+ if (!edit || !edit.changes) {
+ return void 0;
+ }
+ let resourceEdits: languages.WorkspaceTextEdit[] = [];
+ for (let uri in edit.changes) {
+ const _uri = Uri.parse(uri);
+ for (let e of edit.changes[uri]) {
+ resourceEdits.push({
+ resource: _uri,
+ edit: {
+ range: toRange(e.range),
+ text: e.newText
+ }
+ });
+ }
+ }
+ return {
+ edits: resourceEdits
+ };
+}
+
+export class FoldingRangeAdapter implements languages.FoldingRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideFoldingRanges(
+ model: editor.IReadOnlyModel,
+ context: languages.FoldingContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getFoldingRanges(resource.toString(), context))
+ .then((ranges) => {
+ if (!ranges) {
+ return;
+ }
+ return ranges.map((range) => {
+ const result: languages.FoldingRange = {
+ start: range.startLine + 1,
+ end: range.endLine + 1
+ };
+ if (typeof range.kind !== 'undefined') {
+ result.kind = toFoldingRangeKind(range.kind);
+ }
+ return result;
+ });
+ });
+ }
+}
+
+function toFoldingRangeKind(kind: lsTypes.FoldingRangeKind): languages.FoldingRangeKind {
+ switch (kind) {
+ case lsTypes.FoldingRangeKind.Comment:
+ return languages.FoldingRangeKind.Comment;
+ case lsTypes.FoldingRangeKind.Imports:
+ return languages.FoldingRangeKind.Imports;
+ case lsTypes.FoldingRangeKind.Region:
+ return languages.FoldingRangeKind.Region;
+ }
+}
+
+export class SelectionRangeAdapter implements languages.SelectionRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideSelectionRanges(
+ model: editor.IReadOnlyModel,
+ positions: Position[],
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition)))
+ .then((selectionRanges) => {
+ if (!selectionRanges) {
+ return;
+ }
+ return selectionRanges.map((selectionRange) => {
+ const result: languages.SelectionRange[] = [];
+ while (selectionRange) {
+ result.push({ range: toRange(selectionRange.range) });
+ selectionRange = selectionRange.parent;
+ }
+ return result;
+ });
+ });
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-workerManager.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-workerManager.ts.txt
new file mode 100644
index 000000000..5122168b5
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-html-src-workerManager.ts.txt
@@ -0,0 +1,89 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { HTMLWorker } from './htmlWorker';
+import { Uri, IDisposable, editor } from './fillers/monaco-editor-core';
+
+const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
+
+export class WorkerManager {
+ private _defaults: LanguageServiceDefaults;
+ private _idleCheckInterval: number;
+ private _lastUsedTime: number;
+ private _configChangeListener: IDisposable;
+
+ private _worker: editor.MonacoWebWorker;
+ private _client: Promise;
+
+ constructor(defaults: LanguageServiceDefaults) {
+ this._defaults = defaults;
+ this._worker = null;
+ this._idleCheckInterval = window.setInterval(() => this._checkIfIdle(), 30 * 1000);
+ this._lastUsedTime = 0;
+ this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
+ }
+
+ private _stopWorker(): void {
+ if (this._worker) {
+ this._worker.dispose();
+ this._worker = null;
+ }
+ this._client = null;
+ }
+
+ dispose(): void {
+ clearInterval(this._idleCheckInterval);
+ this._configChangeListener.dispose();
+ this._stopWorker();
+ }
+
+ private _checkIfIdle(): void {
+ if (!this._worker) {
+ return;
+ }
+ let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
+ if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
+ this._stopWorker();
+ }
+ }
+
+ private _getClient(): Promise {
+ this._lastUsedTime = Date.now();
+
+ if (!this._client) {
+ this._worker = editor.createWebWorker({
+ // module that exports the create() method and returns a `HTMLWorker` instance
+ moduleId: 'vs/language/html/htmlWorker',
+
+ // passed in to the create() method
+ createData: {
+ languageSettings: this._defaults.options,
+ languageId: this._defaults.languageId
+ },
+
+ label: this._defaults.languageId
+ });
+
+ this._client = >this._worker.getProxy();
+ }
+
+ return this._client;
+ }
+
+ getLanguageServiceWorker(...resources: Uri[]): Promise {
+ let _client: HTMLWorker;
+ return this._getClient()
+ .then((client) => {
+ _client = client;
+ })
+ .then((_) => {
+ if (this._worker) {
+ return this._worker.withSyncedResources(resources);
+ }
+ })
+ .then((_) => _client);
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-jsonMode.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-jsonMode.ts.txt
new file mode 100644
index 000000000..7d66f6a0e
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-jsonMode.ts.txt
@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { WorkerManager } from './workerManager';
+import type { JSONWorker } from './jsonWorker';
+import { LanguageServiceDefaults } from './monaco.contribution';
+import * as languageFeatures from './languageFeatures';
+import { createTokenizationSupport } from './tokenization';
+import { Uri, IDisposable, languages } from './fillers/monaco-editor-core';
+
+export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
+ const disposables: IDisposable[] = [];
+ const providers: IDisposable[] = [];
+
+ const client = new WorkerManager(defaults);
+ disposables.push(client);
+
+ const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise => {
+ return client.getLanguageServiceWorker(...uris);
+ };
+
+ function registerProviders(): void {
+ const { languageId, modeConfiguration } = defaults;
+
+ disposeAll(providers);
+
+ if (modeConfiguration.documentFormattingEdits) {
+ providers.push(
+ languages.registerDocumentFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentFormattingEditProvider(worker)
+ )
+ );
+ }
+ if (modeConfiguration.documentRangeFormattingEdits) {
+ providers.push(
+ languages.registerDocumentRangeFormattingEditProvider(
+ languageId,
+ new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+ )
+ );
+ }
+ if (modeConfiguration.completionItems) {
+ providers.push(
+ languages.registerCompletionItemProvider(
+ languageId,
+ new languageFeatures.CompletionAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.hovers) {
+ providers.push(
+ languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))
+ );
+ }
+ if (modeConfiguration.documentSymbols) {
+ providers.push(
+ languages.registerDocumentSymbolProvider(
+ languageId,
+ new languageFeatures.DocumentSymbolAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.tokens) {
+ providers.push(languages.setTokensProvider(languageId, createTokenizationSupport(true)));
+ }
+ if (modeConfiguration.colors) {
+ providers.push(
+ languages.registerColorProvider(
+ languageId,
+ new languageFeatures.DocumentColorAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.foldingRanges) {
+ providers.push(
+ languages.registerFoldingRangeProvider(
+ languageId,
+ new languageFeatures.FoldingRangeAdapter(worker)
+ )
+ );
+ }
+ if (modeConfiguration.diagnostics) {
+ providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults));
+ }
+ if (modeConfiguration.selectionRanges) {
+ providers.push(
+ languages.registerSelectionRangeProvider(
+ languageId,
+ new languageFeatures.SelectionRangeAdapter(worker)
+ )
+ );
+ }
+ }
+
+ registerProviders();
+
+ disposables.push(languages.setLanguageConfiguration(defaults.languageId, richEditConfiguration));
+
+ let modeConfiguration = defaults.modeConfiguration;
+ defaults.onDidChange((newDefaults) => {
+ if (newDefaults.modeConfiguration !== modeConfiguration) {
+ modeConfiguration = newDefaults.modeConfiguration;
+ registerProviders();
+ }
+ });
+
+ disposables.push(asDisposable(providers));
+
+ return asDisposable(disposables);
+}
+
+function asDisposable(disposables: IDisposable[]): IDisposable {
+ return { dispose: () => disposeAll(disposables) };
+}
+
+function disposeAll(disposables: IDisposable[]) {
+ while (disposables.length) {
+ disposables.pop().dispose();
+ }
+}
+
+const richEditConfiguration: languages.LanguageConfiguration = {
+ wordPattern: /(-?\d*\.\d\w*)|([^\[\{\]\}\:\"\,\s]+)/g,
+
+ comments: {
+ lineComment: '//',
+ blockComment: ['/*', '*/']
+ },
+
+ brackets: [
+ ['{', '}'],
+ ['[', ']']
+ ],
+
+ autoClosingPairs: [
+ { open: '{', close: '}', notIn: ['string'] },
+ { open: '[', close: ']', notIn: ['string'] },
+ { open: '"', close: '"', notIn: ['string'] }
+ ]
+};
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-languageFeatures.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-languageFeatures.ts.txt
new file mode 100644
index 000000000..cc6391a0b
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-languageFeatures.ts.txt
@@ -0,0 +1,716 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { JSONWorker } from './jsonWorker';
+import {
+ Uri,
+ Position,
+ Range,
+ IRange,
+ CancellationToken,
+ IDisposable,
+ editor,
+ languages,
+ MarkerSeverity,
+ IMarkdownString
+} from './fillers/monaco-editor-core';
+import * as lsTypes from 'vscode-languageserver-types';
+
+export interface WorkerAccessor {
+ (...more: Uri[]): Promise;
+}
+
+// --- diagnostics --- ---
+
+export class DiagnosticsAdapter {
+ private _disposables: IDisposable[] = [];
+ private _listener: { [uri: string]: IDisposable } = Object.create(null);
+
+ constructor(
+ private _languageId: string,
+ private _worker: WorkerAccessor,
+ defaults: LanguageServiceDefaults
+ ) {
+ const onModelAdd = (model: editor.IModel): void => {
+ let modeId = model.getLanguageId();
+ if (modeId !== this._languageId) {
+ return;
+ }
+
+ let handle: number;
+ this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
+ clearTimeout(handle);
+ handle = window.setTimeout(() => this._doValidate(model.uri, modeId), 500);
+ });
+
+ this._doValidate(model.uri, modeId);
+ };
+
+ const onModelRemoved = (model: editor.IModel): void => {
+ editor.setModelMarkers(model, this._languageId, []);
+ let uriStr = model.uri.toString();
+ let listener = this._listener[uriStr];
+ if (listener) {
+ listener.dispose();
+ delete this._listener[uriStr];
+ }
+ };
+
+ this._disposables.push(editor.onDidCreateModel(onModelAdd));
+ this._disposables.push(
+ editor.onWillDisposeModel((model) => {
+ onModelRemoved(model);
+ this._resetSchema(model.uri);
+ })
+ );
+ this._disposables.push(
+ editor.onDidChangeModelLanguage((event) => {
+ onModelRemoved(event.model);
+ onModelAdd(event.model);
+ this._resetSchema(event.model.uri);
+ })
+ );
+
+ this._disposables.push(
+ defaults.onDidChange((_) => {
+ editor.getModels().forEach((model) => {
+ if (model.getLanguageId() === this._languageId) {
+ onModelRemoved(model);
+ onModelAdd(model);
+ }
+ });
+ })
+ );
+
+ this._disposables.push({
+ dispose: () => {
+ editor.getModels().forEach(onModelRemoved);
+ for (let key in this._listener) {
+ this._listener[key].dispose();
+ }
+ }
+ });
+
+ editor.getModels().forEach(onModelAdd);
+ }
+
+ public dispose(): void {
+ this._disposables.forEach((d) => d && d.dispose());
+ this._disposables = [];
+ }
+
+ private _resetSchema(resource: Uri): void {
+ this._worker().then((worker) => {
+ worker.resetSchema(resource.toString());
+ });
+ }
+
+ private _doValidate(resource: Uri, languageId: string): void {
+ this._worker(resource)
+ .then((worker) => {
+ return worker.doValidation(resource.toString()).then((diagnostics) => {
+ const markers = diagnostics.map((d) => toDiagnostics(resource, d));
+ let model = editor.getModel(resource);
+ if (model && model.getLanguageId() === languageId) {
+ editor.setModelMarkers(model, languageId, markers);
+ }
+ });
+ })
+ .then(undefined, (err) => {
+ console.error(err);
+ });
+ }
+}
+
+function toSeverity(lsSeverity: number): MarkerSeverity {
+ switch (lsSeverity) {
+ case lsTypes.DiagnosticSeverity.Error:
+ return MarkerSeverity.Error;
+ case lsTypes.DiagnosticSeverity.Warning:
+ return MarkerSeverity.Warning;
+ case lsTypes.DiagnosticSeverity.Information:
+ return MarkerSeverity.Info;
+ case lsTypes.DiagnosticSeverity.Hint:
+ return MarkerSeverity.Hint;
+ default:
+ return MarkerSeverity.Info;
+ }
+}
+
+function toDiagnostics(resource: Uri, diag: lsTypes.Diagnostic): editor.IMarkerData {
+ let code = typeof diag.code === 'number' ? String(diag.code) : diag.code;
+
+ return {
+ severity: toSeverity(diag.severity),
+ startLineNumber: diag.range.start.line + 1,
+ startColumn: diag.range.start.character + 1,
+ endLineNumber: diag.range.end.line + 1,
+ endColumn: diag.range.end.character + 1,
+ message: diag.message,
+ code: code,
+ source: diag.source
+ };
+}
+
+// --- completion ------
+
+function fromPosition(position: Position): lsTypes.Position {
+ if (!position) {
+ return void 0;
+ }
+ return { character: position.column - 1, line: position.lineNumber - 1 };
+}
+
+function fromRange(range: IRange): lsTypes.Range {
+ if (!range) {
+ return void 0;
+ }
+ return {
+ start: {
+ line: range.startLineNumber - 1,
+ character: range.startColumn - 1
+ },
+ end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
+ };
+}
+function toRange(range: lsTypes.Range): Range {
+ if (!range) {
+ return void 0;
+ }
+ return new Range(
+ range.start.line + 1,
+ range.start.character + 1,
+ range.end.line + 1,
+ range.end.character + 1
+ );
+}
+
+interface InsertReplaceEdit {
+ /**
+ * The string to be inserted.
+ */
+ newText: string;
+ /**
+ * The range if the insert is requested
+ */
+ insert: lsTypes.Range;
+ /**
+ * The range if the replace is requested.
+ */
+ replace: lsTypes.Range;
+}
+
+function isInsertReplaceEdit(
+ edit: lsTypes.TextEdit | InsertReplaceEdit
+): edit is InsertReplaceEdit {
+ return (
+ typeof (edit).insert !== 'undefined' &&
+ typeof (edit).replace !== 'undefined'
+ );
+}
+
+function toCompletionItemKind(kind: number): languages.CompletionItemKind {
+ let mItemKind = languages.CompletionItemKind;
+
+ switch (kind) {
+ case lsTypes.CompletionItemKind.Text:
+ return mItemKind.Text;
+ case lsTypes.CompletionItemKind.Method:
+ return mItemKind.Method;
+ case lsTypes.CompletionItemKind.Function:
+ return mItemKind.Function;
+ case lsTypes.CompletionItemKind.Constructor:
+ return mItemKind.Constructor;
+ case lsTypes.CompletionItemKind.Field:
+ return mItemKind.Field;
+ case lsTypes.CompletionItemKind.Variable:
+ return mItemKind.Variable;
+ case lsTypes.CompletionItemKind.Class:
+ return mItemKind.Class;
+ case lsTypes.CompletionItemKind.Interface:
+ return mItemKind.Interface;
+ case lsTypes.CompletionItemKind.Module:
+ return mItemKind.Module;
+ case lsTypes.CompletionItemKind.Property:
+ return mItemKind.Property;
+ case lsTypes.CompletionItemKind.Unit:
+ return mItemKind.Unit;
+ case lsTypes.CompletionItemKind.Value:
+ return mItemKind.Value;
+ case lsTypes.CompletionItemKind.Enum:
+ return mItemKind.Enum;
+ case lsTypes.CompletionItemKind.Keyword:
+ return mItemKind.Keyword;
+ case lsTypes.CompletionItemKind.Snippet:
+ return mItemKind.Snippet;
+ case lsTypes.CompletionItemKind.Color:
+ return mItemKind.Color;
+ case lsTypes.CompletionItemKind.File:
+ return mItemKind.File;
+ case lsTypes.CompletionItemKind.Reference:
+ return mItemKind.Reference;
+ }
+ return mItemKind.Property;
+}
+
+function fromCompletionItemKind(kind: languages.CompletionItemKind): lsTypes.CompletionItemKind {
+ let mItemKind = languages.CompletionItemKind;
+
+ switch (kind) {
+ case mItemKind.Text:
+ return lsTypes.CompletionItemKind.Text;
+ case mItemKind.Method:
+ return lsTypes.CompletionItemKind.Method;
+ case mItemKind.Function:
+ return lsTypes.CompletionItemKind.Function;
+ case mItemKind.Constructor:
+ return lsTypes.CompletionItemKind.Constructor;
+ case mItemKind.Field:
+ return lsTypes.CompletionItemKind.Field;
+ case mItemKind.Variable:
+ return lsTypes.CompletionItemKind.Variable;
+ case mItemKind.Class:
+ return lsTypes.CompletionItemKind.Class;
+ case mItemKind.Interface:
+ return lsTypes.CompletionItemKind.Interface;
+ case mItemKind.Module:
+ return lsTypes.CompletionItemKind.Module;
+ case mItemKind.Property:
+ return lsTypes.CompletionItemKind.Property;
+ case mItemKind.Unit:
+ return lsTypes.CompletionItemKind.Unit;
+ case mItemKind.Value:
+ return lsTypes.CompletionItemKind.Value;
+ case mItemKind.Enum:
+ return lsTypes.CompletionItemKind.Enum;
+ case mItemKind.Keyword:
+ return lsTypes.CompletionItemKind.Keyword;
+ case mItemKind.Snippet:
+ return lsTypes.CompletionItemKind.Snippet;
+ case mItemKind.Color:
+ return lsTypes.CompletionItemKind.Color;
+ case mItemKind.File:
+ return lsTypes.CompletionItemKind.File;
+ case mItemKind.Reference:
+ return lsTypes.CompletionItemKind.Reference;
+ }
+ return lsTypes.CompletionItemKind.Property;
+}
+
+function toTextEdit(textEdit: lsTypes.TextEdit): editor.ISingleEditOperation {
+ if (!textEdit) {
+ return void 0;
+ }
+ return {
+ range: toRange(textEdit.range),
+ text: textEdit.newText
+ };
+}
+
+function toCommand(c: lsTypes.Command | undefined): languages.Command {
+ return c && c.command === 'editor.action.triggerSuggest'
+ ? { id: c.command, title: c.title, arguments: c.arguments }
+ : undefined;
+}
+
+export class CompletionAdapter implements languages.CompletionItemProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public get triggerCharacters(): string[] {
+ return [' ', ':', '"'];
+ }
+
+ provideCompletionItems(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ context: languages.CompletionContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doComplete(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ const wordInfo = model.getWordUntilPosition(position);
+ const wordRange = new Range(
+ position.lineNumber,
+ wordInfo.startColumn,
+ position.lineNumber,
+ wordInfo.endColumn
+ );
+
+ let items: languages.CompletionItem[] = info.items.map((entry) => {
+ let item: languages.CompletionItem = {
+ label: entry.label,
+ insertText: entry.insertText || entry.label,
+ sortText: entry.sortText,
+ filterText: entry.filterText,
+ documentation: entry.documentation,
+ detail: entry.detail,
+ command: toCommand(entry.command),
+ range: wordRange,
+ kind: toCompletionItemKind(entry.kind)
+ };
+ if (entry.textEdit) {
+ if (isInsertReplaceEdit(entry.textEdit)) {
+ item.range = {
+ insert: toRange(entry.textEdit.insert),
+ replace: toRange(entry.textEdit.replace)
+ };
+ } else {
+ item.range = toRange(entry.textEdit.range);
+ }
+ item.insertText = entry.textEdit.newText;
+ }
+ if (entry.additionalTextEdits) {
+ item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit);
+ }
+ if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
+ item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
+ }
+ return item;
+ });
+
+ return {
+ isIncomplete: info.isIncomplete,
+ suggestions: items
+ };
+ });
+ }
+}
+
+function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
+ return (
+ thing && typeof thing === 'object' && typeof (thing).kind === 'string'
+ );
+}
+
+function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString {
+ if (typeof entry === 'string') {
+ return {
+ value: entry
+ };
+ }
+ if (isMarkupContent(entry)) {
+ if (entry.kind === 'plaintext') {
+ return {
+ value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
+ };
+ }
+ return {
+ value: entry.value
+ };
+ }
+
+ return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
+}
+
+function toMarkedStringArray(
+ contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[]
+): IMarkdownString[] {
+ if (!contents) {
+ return void 0;
+ }
+ if (Array.isArray(contents)) {
+ return contents.map(toMarkdownString);
+ }
+ return [toMarkdownString(contents)];
+}
+
+// --- hover ------
+
+export class HoverAdapter implements languages.HoverProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ provideHover(
+ model: editor.IReadOnlyModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ let resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => {
+ return worker.doHover(resource.toString(), fromPosition(position));
+ })
+ .then((info) => {
+ if (!info) {
+ return;
+ }
+ return {
+ range: toRange(info.range),
+ contents: toMarkedStringArray(info.contents)
+ };
+ });
+ }
+}
+
+// --- definition ------
+
+function toLocation(location: lsTypes.Location): languages.Location {
+ return {
+ uri: Uri.parse(location.uri),
+ range: toRange(location.range)
+ };
+}
+
+// --- document symbols ------
+
+function toSymbolKind(kind: lsTypes.SymbolKind): languages.SymbolKind {
+ let mKind = languages.SymbolKind;
+
+ switch (kind) {
+ case lsTypes.SymbolKind.File:
+ return mKind.Array;
+ case lsTypes.SymbolKind.Module:
+ return mKind.Module;
+ case lsTypes.SymbolKind.Namespace:
+ return mKind.Namespace;
+ case lsTypes.SymbolKind.Package:
+ return mKind.Package;
+ case lsTypes.SymbolKind.Class:
+ return mKind.Class;
+ case lsTypes.SymbolKind.Method:
+ return mKind.Method;
+ case lsTypes.SymbolKind.Property:
+ return mKind.Property;
+ case lsTypes.SymbolKind.Field:
+ return mKind.Field;
+ case lsTypes.SymbolKind.Constructor:
+ return mKind.Constructor;
+ case lsTypes.SymbolKind.Enum:
+ return mKind.Enum;
+ case lsTypes.SymbolKind.Interface:
+ return mKind.Interface;
+ case lsTypes.SymbolKind.Function:
+ return mKind.Function;
+ case lsTypes.SymbolKind.Variable:
+ return mKind.Variable;
+ case lsTypes.SymbolKind.Constant:
+ return mKind.Constant;
+ case lsTypes.SymbolKind.String:
+ return mKind.String;
+ case lsTypes.SymbolKind.Number:
+ return mKind.Number;
+ case lsTypes.SymbolKind.Boolean:
+ return mKind.Boolean;
+ case lsTypes.SymbolKind.Array:
+ return mKind.Array;
+ }
+ return mKind.Function;
+}
+
+export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentSymbols(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentSymbols(resource.toString()))
+ .then((items) => {
+ if (!items) {
+ return;
+ }
+ return items.map((item) => ({
+ name: item.name,
+ detail: '',
+ containerName: item.containerName,
+ kind: toSymbolKind(item.kind),
+ range: toRange(item.location.range),
+ selectionRange: toRange(item.location.range),
+ tags: []
+ }));
+ });
+ }
+}
+
+function fromFormattingOptions(options: languages.FormattingOptions): lsTypes.FormattingOptions {
+ return {
+ tabSize: options.tabSize,
+ insertSpaces: options.insertSpaces
+ };
+}
+
+export class DocumentFormattingEditProvider implements languages.DocumentFormattingEditProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentFormattingEdits(
+ model: editor.IReadOnlyModel,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource).then((worker) => {
+ return worker
+ .format(resource.toString(), null, fromFormattingOptions(options))
+ .then((edits) => {
+ if (!edits || edits.length === 0) {
+ return;
+ }
+ return edits.map(toTextEdit);
+ });
+ });
+ }
+}
+
+export class DocumentRangeFormattingEditProvider
+ implements languages.DocumentRangeFormattingEditProvider
+{
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentRangeFormattingEdits(
+ model: editor.IReadOnlyModel,
+ range: Range,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource).then((worker) => {
+ return worker
+ .format(resource.toString(), fromRange(range), fromFormattingOptions(options))
+ .then((edits) => {
+ if (!edits || edits.length === 0) {
+ return;
+ }
+ return edits.map(toTextEdit);
+ });
+ });
+ }
+}
+
+export class DocumentColorAdapter implements languages.DocumentColorProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideDocumentColors(
+ model: editor.IReadOnlyModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.findDocumentColors(resource.toString()))
+ .then((infos) => {
+ if (!infos) {
+ return;
+ }
+ return infos.map((item) => ({
+ color: item.color,
+ range: toRange(item.range)
+ }));
+ });
+ }
+
+ public provideColorPresentations(
+ model: editor.IReadOnlyModel,
+ info: languages.IColorInformation,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) =>
+ worker.getColorPresentations(resource.toString(), info.color, fromRange(info.range))
+ )
+ .then((presentations) => {
+ if (!presentations) {
+ return;
+ }
+ return presentations.map((presentation) => {
+ let item: languages.IColorPresentation = {
+ label: presentation.label
+ };
+ if (presentation.textEdit) {
+ item.textEdit = toTextEdit(presentation.textEdit);
+ }
+ if (presentation.additionalTextEdits) {
+ item.additionalTextEdits = presentation.additionalTextEdits.map(toTextEdit);
+ }
+ return item;
+ });
+ });
+ }
+}
+
+export class FoldingRangeAdapter implements languages.FoldingRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideFoldingRanges(
+ model: editor.IReadOnlyModel,
+ context: languages.FoldingContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getFoldingRanges(resource.toString(), context))
+ .then((ranges) => {
+ if (!ranges) {
+ return;
+ }
+ return ranges.map((range) => {
+ let result: languages.FoldingRange = {
+ start: range.startLine + 1,
+ end: range.endLine + 1
+ };
+ if (typeof range.kind !== 'undefined') {
+ result.kind = toFoldingRangeKind(range.kind);
+ }
+ return result;
+ });
+ });
+ }
+}
+
+function toFoldingRangeKind(kind: lsTypes.FoldingRangeKind): languages.FoldingRangeKind {
+ switch (kind) {
+ case lsTypes.FoldingRangeKind.Comment:
+ return languages.FoldingRangeKind.Comment;
+ case lsTypes.FoldingRangeKind.Imports:
+ return languages.FoldingRangeKind.Imports;
+ case lsTypes.FoldingRangeKind.Region:
+ return languages.FoldingRangeKind.Region;
+ }
+ return void 0;
+}
+
+export class SelectionRangeAdapter implements languages.SelectionRangeProvider {
+ constructor(private _worker: WorkerAccessor) {}
+
+ public provideSelectionRanges(
+ model: editor.IReadOnlyModel,
+ positions: Position[],
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+
+ return this._worker(resource)
+ .then((worker) => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition)))
+ .then((selectionRanges) => {
+ if (!selectionRanges) {
+ return;
+ }
+ return selectionRanges.map((selectionRange) => {
+ const result: languages.SelectionRange[] = [];
+ while (selectionRange) {
+ result.push({ range: toRange(selectionRange.range) });
+ selectionRange = selectionRange.parent;
+ }
+ return result;
+ });
+ });
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-tokenization.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-tokenization.ts.txt
new file mode 100644
index 000000000..aa9bd5a44
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-tokenization.ts.txt
@@ -0,0 +1,245 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as json from 'jsonc-parser';
+import { languages } from './fillers/monaco-editor-core';
+
+export function createTokenizationSupport(supportComments: boolean): languages.TokensProvider {
+ return {
+ getInitialState: () => new JSONState(null, null, false, null),
+ tokenize: (line, state, offsetDelta?, stopAtOffset?) =>
+ tokenize(supportComments, line, state, offsetDelta, stopAtOffset)
+ };
+}
+
+export const TOKEN_DELIM_OBJECT = 'delimiter.bracket.json';
+export const TOKEN_DELIM_ARRAY = 'delimiter.array.json';
+export const TOKEN_DELIM_COLON = 'delimiter.colon.json';
+export const TOKEN_DELIM_COMMA = 'delimiter.comma.json';
+export const TOKEN_VALUE_BOOLEAN = 'keyword.json';
+export const TOKEN_VALUE_NULL = 'keyword.json';
+export const TOKEN_VALUE_STRING = 'string.value.json';
+export const TOKEN_VALUE_NUMBER = 'number.json';
+export const TOKEN_PROPERTY_NAME = 'string.key.json';
+export const TOKEN_COMMENT_BLOCK = 'comment.block.json';
+export const TOKEN_COMMENT_LINE = 'comment.line.json';
+
+const enum JSONParent {
+ Object = 0,
+ Array = 1
+}
+
+class ParentsStack {
+ constructor(public readonly parent: ParentsStack | null, public readonly type: JSONParent) {}
+
+ public static pop(parents: ParentsStack | null): ParentsStack | null {
+ if (parents) {
+ return parents.parent;
+ }
+ return null;
+ }
+
+ public static push(parents: ParentsStack | null, type: JSONParent): ParentsStack {
+ return new ParentsStack(parents, type);
+ }
+
+ public static equals(a: ParentsStack | null, b: ParentsStack | null): boolean {
+ if (!a && !b) {
+ return true;
+ }
+ if (!a || !b) {
+ return false;
+ }
+ while (a && b) {
+ if (a === b) {
+ return true;
+ }
+ if (a.type !== b.type) {
+ return false;
+ }
+ a = a.parent;
+ b = b.parent;
+ }
+ return true;
+ }
+}
+
+class JSONState implements languages.IState {
+ private _state: languages.IState;
+
+ public scanError: json.ScanError;
+ public lastWasColon: boolean;
+ public parents: ParentsStack | null;
+
+ constructor(
+ state: languages.IState,
+ scanError: json.ScanError,
+ lastWasColon: boolean,
+ parents: ParentsStack | null
+ ) {
+ this._state = state;
+ this.scanError = scanError;
+ this.lastWasColon = lastWasColon;
+ this.parents = parents;
+ }
+
+ public clone(): JSONState {
+ return new JSONState(this._state, this.scanError, this.lastWasColon, this.parents);
+ }
+
+ public equals(other: languages.IState): boolean {
+ if (other === this) {
+ return true;
+ }
+ if (!other || !(other instanceof JSONState)) {
+ return false;
+ }
+ return (
+ this.scanError === other.scanError &&
+ this.lastWasColon === other.lastWasColon &&
+ ParentsStack.equals(this.parents, other.parents)
+ );
+ }
+
+ public getStateData(): languages.IState {
+ return this._state;
+ }
+
+ public setStateData(state: languages.IState): void {
+ this._state = state;
+ }
+}
+
+function tokenize(
+ comments: boolean,
+ line: string,
+ state: JSONState,
+ offsetDelta: number = 0,
+ stopAtOffset?: number
+): languages.ILineTokens {
+ // handle multiline strings and block comments
+ let numberOfInsertedCharacters = 0;
+ let adjustOffset = false;
+
+ switch (state.scanError) {
+ case json.ScanError.UnexpectedEndOfString:
+ line = '"' + line;
+ numberOfInsertedCharacters = 1;
+ break;
+ case json.ScanError.UnexpectedEndOfComment:
+ line = '/*' + line;
+ numberOfInsertedCharacters = 2;
+ break;
+ }
+
+ const scanner = json.createScanner(line);
+ let lastWasColon = state.lastWasColon;
+ let parents = state.parents;
+
+ const ret: languages.ILineTokens = {
+ tokens: [],
+ endState: state.clone()
+ };
+
+ while (true) {
+ let offset = offsetDelta + scanner.getPosition();
+ let type = '';
+
+ const kind = scanner.scan();
+ if (kind === json.SyntaxKind.EOF) {
+ break;
+ }
+
+ // Check that the scanner has advanced
+ if (offset === offsetDelta + scanner.getPosition()) {
+ throw new Error(
+ 'Scanner did not advance, next 3 characters are: ' + line.substr(scanner.getPosition(), 3)
+ );
+ }
+
+ // In case we inserted /* or " character, we need to
+ // adjust the offset of all tokens (except the first)
+ if (adjustOffset) {
+ offset -= numberOfInsertedCharacters;
+ }
+ adjustOffset = numberOfInsertedCharacters > 0;
+
+ // brackets and type
+ switch (kind) {
+ case json.SyntaxKind.OpenBraceToken:
+ parents = ParentsStack.push(parents, JSONParent.Object);
+ type = TOKEN_DELIM_OBJECT;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.CloseBraceToken:
+ parents = ParentsStack.pop(parents);
+ type = TOKEN_DELIM_OBJECT;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.OpenBracketToken:
+ parents = ParentsStack.push(parents, JSONParent.Array);
+ type = TOKEN_DELIM_ARRAY;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.CloseBracketToken:
+ parents = ParentsStack.pop(parents);
+ type = TOKEN_DELIM_ARRAY;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.ColonToken:
+ type = TOKEN_DELIM_COLON;
+ lastWasColon = true;
+ break;
+ case json.SyntaxKind.CommaToken:
+ type = TOKEN_DELIM_COMMA;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.TrueKeyword:
+ case json.SyntaxKind.FalseKeyword:
+ type = TOKEN_VALUE_BOOLEAN;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.NullKeyword:
+ type = TOKEN_VALUE_NULL;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.StringLiteral:
+ const currentParent = parents ? parents.type : JSONParent.Object;
+ const inArray = currentParent === JSONParent.Array;
+ type = lastWasColon || inArray ? TOKEN_VALUE_STRING : TOKEN_PROPERTY_NAME;
+ lastWasColon = false;
+ break;
+ case json.SyntaxKind.NumericLiteral:
+ type = TOKEN_VALUE_NUMBER;
+ lastWasColon = false;
+ break;
+ }
+
+ // comments, iff enabled
+ if (comments) {
+ switch (kind) {
+ case json.SyntaxKind.LineCommentTrivia:
+ type = TOKEN_COMMENT_LINE;
+ break;
+ case json.SyntaxKind.BlockCommentTrivia:
+ type = TOKEN_COMMENT_BLOCK;
+ break;
+ }
+ }
+
+ ret.endState = new JSONState(
+ state.getStateData(),
+ scanner.getTokenError(),
+ lastWasColon,
+ parents
+ );
+ ret.tokens.push({
+ startIndex: offset,
+ scopes: type
+ });
+ }
+
+ return ret;
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-workerManager.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-workerManager.ts.txt
new file mode 100644
index 000000000..6c32e0018
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-json-src-workerManager.ts.txt
@@ -0,0 +1,88 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { JSONWorker } from './jsonWorker';
+import { IDisposable, Uri, editor } from './fillers/monaco-editor-core';
+
+const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
+
+export class WorkerManager {
+ private _defaults: LanguageServiceDefaults;
+ private _idleCheckInterval: number;
+ private _lastUsedTime: number;
+ private _configChangeListener: IDisposable;
+
+ private _worker: editor.MonacoWebWorker;
+ private _client: Promise;
+
+ constructor(defaults: LanguageServiceDefaults) {
+ this._defaults = defaults;
+ this._worker = null;
+ this._idleCheckInterval = window.setInterval(() => this._checkIfIdle(), 30 * 1000);
+ this._lastUsedTime = 0;
+ this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
+ }
+
+ private _stopWorker(): void {
+ if (this._worker) {
+ this._worker.dispose();
+ this._worker = null;
+ }
+ this._client = null;
+ }
+
+ dispose(): void {
+ clearInterval(this._idleCheckInterval);
+ this._configChangeListener.dispose();
+ this._stopWorker();
+ }
+
+ private _checkIfIdle(): void {
+ if (!this._worker) {
+ return;
+ }
+ let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
+ if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
+ this._stopWorker();
+ }
+ }
+
+ private _getClient(): Promise {
+ this._lastUsedTime = Date.now();
+
+ if (!this._client) {
+ this._worker = editor.createWebWorker({
+ // module that exports the create() method and returns a `JSONWorker` instance
+ moduleId: 'vs/language/json/jsonWorker',
+
+ label: this._defaults.languageId,
+
+ // passed in to the create() method
+ createData: {
+ languageSettings: this._defaults.diagnosticsOptions,
+ languageId: this._defaults.languageId,
+ enableSchemaRequest: this._defaults.diagnosticsOptions.enableSchemaRequest
+ }
+ });
+
+ this._client = >(this._worker.getProxy());
+ }
+
+ return this._client;
+ }
+
+ getLanguageServiceWorker(...resources: Uri[]): Promise {
+ let _client: JSONWorker;
+ return this._getClient()
+ .then((client) => {
+ _client = client;
+ })
+ .then((_) => {
+ return this._worker.withSyncedResources(resources);
+ })
+ .then((_) => _client);
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-languageFeatures.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-languageFeatures.ts.txt
new file mode 100644
index 000000000..2dba4a863
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-languageFeatures.ts.txt
@@ -0,0 +1,1265 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import {
+ Diagnostic,
+ DiagnosticRelatedInformation,
+ LanguageServiceDefaults,
+ typescriptDefaults
+} from './monaco.contribution';
+import type * as ts from './lib/typescriptServices';
+import type { TypeScriptWorker } from './tsWorker';
+import { libFileSet } from './lib/lib.index';
+import {
+ editor,
+ languages,
+ Uri,
+ Position,
+ Range,
+ CancellationToken,
+ IDisposable,
+ IRange,
+ MarkerTag,
+ MarkerSeverity
+} from './fillers/monaco-editor-core';
+
+//#region utils copied from typescript to prevent loading the entire typescriptServices ---
+
+enum IndentStyle {
+ None = 0,
+ Block = 1,
+ Smart = 2
+}
+
+export function flattenDiagnosticMessageText(
+ diag: string | ts.DiagnosticMessageChain | undefined,
+ newLine: string,
+ indent = 0
+): string {
+ if (typeof diag === 'string') {
+ return diag;
+ } else if (diag === undefined) {
+ return '';
+ }
+ let result = '';
+ if (indent) {
+ result += newLine;
+
+ for (let i = 0; i < indent; i++) {
+ result += ' ';
+ }
+ }
+ result += diag.messageText;
+ indent++;
+ if (diag.next) {
+ for (const kid of diag.next) {
+ result += flattenDiagnosticMessageText(kid, newLine, indent);
+ }
+ }
+ return result;
+}
+
+function displayPartsToString(displayParts: ts.SymbolDisplayPart[] | undefined): string {
+ if (displayParts) {
+ return displayParts.map((displayPart) => displayPart.text).join('');
+ }
+ return '';
+}
+
+//#endregion
+
+export abstract class Adapter {
+ constructor(protected _worker: (...uris: Uri[]) => Promise) {}
+
+ // protected _positionToOffset(model: editor.ITextModel, position: monaco.IPosition): number {
+ // return model.getOffsetAt(position);
+ // }
+
+ // protected _offsetToPosition(model: editor.ITextModel, offset: number): monaco.IPosition {
+ // return model.getPositionAt(offset);
+ // }
+
+ protected _textSpanToRange(model: editor.ITextModel, span: ts.TextSpan): IRange {
+ let p1 = model.getPositionAt(span.start);
+ let p2 = model.getPositionAt(span.start + span.length);
+ let { lineNumber: startLineNumber, column: startColumn } = p1;
+ let { lineNumber: endLineNumber, column: endColumn } = p2;
+ return { startLineNumber, startColumn, endLineNumber, endColumn };
+ }
+}
+
+// --- lib files
+
+export class LibFiles {
+ private _libFiles: Record;
+ private _hasFetchedLibFiles: boolean;
+ private _fetchLibFilesPromise: Promise | null;
+
+ constructor(private readonly _worker: (...uris: Uri[]) => Promise) {
+ this._libFiles = {};
+ this._hasFetchedLibFiles = false;
+ this._fetchLibFilesPromise = null;
+ }
+
+ public isLibFile(uri: Uri | null): boolean {
+ if (!uri) {
+ return false;
+ }
+ if (uri.path.indexOf('/lib.') === 0) {
+ return !!libFileSet[uri.path.slice(1)];
+ }
+ return false;
+ }
+
+ public getOrCreateModel(fileName: string): editor.ITextModel | null {
+ const uri = Uri.parse(fileName);
+ const model = editor.getModel(uri);
+ if (model) {
+ return model;
+ }
+ if (this.isLibFile(uri) && this._hasFetchedLibFiles) {
+ return editor.createModel(this._libFiles[uri.path.slice(1)], 'typescript', uri);
+ }
+ const matchedLibFile = typescriptDefaults.getExtraLibs()[fileName];
+ if (matchedLibFile) {
+ return editor.createModel(matchedLibFile.content, 'typescript', uri);
+ }
+ return null;
+ }
+
+ private _containsLibFile(uris: (Uri | null)[]): boolean {
+ for (let uri of uris) {
+ if (this.isLibFile(uri)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public async fetchLibFilesIfNecessary(uris: (Uri | null)[]): Promise {
+ if (!this._containsLibFile(uris)) {
+ // no lib files necessary
+ return;
+ }
+ await this._fetchLibFiles();
+ }
+
+ private _fetchLibFiles(): Promise {
+ if (!this._fetchLibFilesPromise) {
+ this._fetchLibFilesPromise = this._worker()
+ .then((w) => w.getLibFiles())
+ .then((libFiles) => {
+ this._hasFetchedLibFiles = true;
+ this._libFiles = libFiles;
+ });
+ }
+ return this._fetchLibFilesPromise;
+ }
+}
+
+// --- diagnostics --- ---
+
+enum DiagnosticCategory {
+ Warning = 0,
+ Error = 1,
+ Suggestion = 2,
+ Message = 3
+}
+
+/**
+ * temporary interface until the editor API exposes
+ * `IModel.isAttachedToEditor` and `IModel.onDidChangeAttached`
+ */
+interface IInternalEditorModel extends editor.IModel {
+ onDidChangeAttached(listener: () => void): IDisposable;
+ isAttachedToEditor(): boolean;
+}
+
+export class DiagnosticsAdapter extends Adapter {
+ private _disposables: IDisposable[] = [];
+ private _listener: { [uri: string]: IDisposable } = Object.create(null);
+
+ constructor(
+ private readonly _libFiles: LibFiles,
+ private _defaults: LanguageServiceDefaults,
+ private _selector: string,
+ worker: (...uris: Uri[]) => Promise
+ ) {
+ super(worker);
+
+ const onModelAdd = (model: IInternalEditorModel): void => {
+ if (model.getLanguageId() !== _selector) {
+ return;
+ }
+
+ const maybeValidate = () => {
+ const { onlyVisible } = this._defaults.getDiagnosticsOptions();
+ if (onlyVisible) {
+ if (model.isAttachedToEditor()) {
+ this._doValidate(model);
+ }
+ } else {
+ this._doValidate(model);
+ }
+ };
+
+ let handle: number;
+ const changeSubscription = model.onDidChangeContent(() => {
+ clearTimeout(handle);
+ handle = window.setTimeout(maybeValidate, 500);
+ });
+
+ const visibleSubscription = model.onDidChangeAttached(() => {
+ const { onlyVisible } = this._defaults.getDiagnosticsOptions();
+ if (onlyVisible) {
+ if (model.isAttachedToEditor()) {
+ // this model is now attached to an editor
+ // => compute diagnostics
+ maybeValidate();
+ } else {
+ // this model is no longer attached to an editor
+ // => clear existing diagnostics
+ editor.setModelMarkers(model, this._selector, []);
+ }
+ }
+ });
+
+ this._listener[model.uri.toString()] = {
+ dispose() {
+ changeSubscription.dispose();
+ visibleSubscription.dispose();
+ clearTimeout(handle);
+ }
+ };
+
+ maybeValidate();
+ };
+
+ const onModelRemoved = (model: editor.IModel): void => {
+ editor.setModelMarkers(model, this._selector, []);
+ const key = model.uri.toString();
+ if (this._listener[key]) {
+ this._listener[key].dispose();
+ delete this._listener[key];
+ }
+ };
+
+ this._disposables.push(
+ editor.onDidCreateModel((model) => onModelAdd(model))
+ );
+ this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
+ this._disposables.push(
+ editor.onDidChangeModelLanguage((event) => {
+ onModelRemoved(event.model);
+ onModelAdd(event.model);
+ })
+ );
+
+ this._disposables.push({
+ dispose() {
+ for (const model of editor.getModels()) {
+ onModelRemoved(model);
+ }
+ }
+ });
+
+ const recomputeDiagostics = () => {
+ // redo diagnostics when options change
+ for (const model of editor.getModels()) {
+ onModelRemoved(model);
+ onModelAdd(model);
+ }
+ };
+ this._disposables.push(this._defaults.onDidChange(recomputeDiagostics));
+ this._disposables.push(this._defaults.onDidExtraLibsChange(recomputeDiagostics));
+
+ editor.getModels().forEach((model) => onModelAdd(model));
+ }
+
+ public dispose(): void {
+ this._disposables.forEach((d) => d && d.dispose());
+ this._disposables = [];
+ }
+
+ private async _doValidate(model: editor.ITextModel): Promise {
+ const worker = await this._worker(model.uri);
+
+ if (model.isDisposed()) {
+ // model was disposed in the meantime
+ return;
+ }
+
+ const promises: Promise[] = [];
+ const { noSyntaxValidation, noSemanticValidation, noSuggestionDiagnostics } =
+ this._defaults.getDiagnosticsOptions();
+ if (!noSyntaxValidation) {
+ promises.push(worker.getSyntacticDiagnostics(model.uri.toString()));
+ }
+ if (!noSemanticValidation) {
+ promises.push(worker.getSemanticDiagnostics(model.uri.toString()));
+ }
+ if (!noSuggestionDiagnostics) {
+ promises.push(worker.getSuggestionDiagnostics(model.uri.toString()));
+ }
+
+ const allDiagnostics = await Promise.all(promises);
+
+ if (!allDiagnostics || model.isDisposed()) {
+ // model was disposed in the meantime
+ return;
+ }
+
+ const diagnostics = allDiagnostics
+ .reduce((p, c) => c.concat(p), [])
+ .filter(
+ (d) =>
+ (this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore || []).indexOf(d.code) ===
+ -1
+ );
+
+ // Fetch lib files if necessary
+ const relatedUris = diagnostics
+ .map((d) => d.relatedInformation || [])
+ .reduce((p, c) => c.concat(p), [])
+ .map((relatedInformation) =>
+ relatedInformation.file ? Uri.parse(relatedInformation.file.fileName) : null
+ );
+
+ await this._libFiles.fetchLibFilesIfNecessary(relatedUris);
+
+ if (model.isDisposed()) {
+ // model was disposed in the meantime
+ return;
+ }
+
+ editor.setModelMarkers(
+ model,
+ this._selector,
+ diagnostics.map((d) => this._convertDiagnostics(model, d))
+ );
+ }
+
+ private _convertDiagnostics(model: editor.ITextModel, diag: Diagnostic): editor.IMarkerData {
+ const diagStart = diag.start || 0;
+ const diagLength = diag.length || 1;
+ const { lineNumber: startLineNumber, column: startColumn } = model.getPositionAt(diagStart);
+ const { lineNumber: endLineNumber, column: endColumn } = model.getPositionAt(
+ diagStart + diagLength
+ );
+
+ const tags: MarkerTag[] = [];
+ if (diag.reportsUnnecessary) {
+ tags.push(MarkerTag.Unnecessary);
+ }
+ if (diag.reportsDeprecated) {
+ tags.push(MarkerTag.Deprecated);
+ }
+
+ return {
+ severity: this._tsDiagnosticCategoryToMarkerSeverity(diag.category),
+ startLineNumber,
+ startColumn,
+ endLineNumber,
+ endColumn,
+ message: flattenDiagnosticMessageText(diag.messageText, '\n'),
+ code: diag.code.toString(),
+ tags,
+ relatedInformation: this._convertRelatedInformation(model, diag.relatedInformation)
+ };
+ }
+
+ private _convertRelatedInformation(
+ model: editor.ITextModel,
+ relatedInformation?: DiagnosticRelatedInformation[]
+ ): editor.IRelatedInformation[] {
+ if (!relatedInformation) {
+ return [];
+ }
+
+ const result: editor.IRelatedInformation[] = [];
+ relatedInformation.forEach((info) => {
+ let relatedResource: editor.ITextModel | null = model;
+ if (info.file) {
+ relatedResource = this._libFiles.getOrCreateModel(info.file.fileName);
+ }
+
+ if (!relatedResource) {
+ return;
+ }
+ const infoStart = info.start || 0;
+ const infoLength = info.length || 1;
+ const { lineNumber: startLineNumber, column: startColumn } =
+ relatedResource.getPositionAt(infoStart);
+ const { lineNumber: endLineNumber, column: endColumn } = relatedResource.getPositionAt(
+ infoStart + infoLength
+ );
+
+ result.push({
+ resource: relatedResource.uri,
+ startLineNumber,
+ startColumn,
+ endLineNumber,
+ endColumn,
+ message: flattenDiagnosticMessageText(info.messageText, '\n')
+ });
+ });
+ return result;
+ }
+
+ private _tsDiagnosticCategoryToMarkerSeverity(category: ts.DiagnosticCategory): MarkerSeverity {
+ switch (category) {
+ case DiagnosticCategory.Error:
+ return MarkerSeverity.Error;
+ case DiagnosticCategory.Message:
+ return MarkerSeverity.Info;
+ case DiagnosticCategory.Warning:
+ return MarkerSeverity.Warning;
+ case DiagnosticCategory.Suggestion:
+ return MarkerSeverity.Hint;
+ }
+ return MarkerSeverity.Info;
+ }
+}
+
+// --- suggest ------
+
+interface MyCompletionItem extends languages.CompletionItem {
+ label: string;
+ uri: Uri;
+ position: Position;
+ offset: number;
+}
+
+export class SuggestAdapter extends Adapter implements languages.CompletionItemProvider {
+ public get triggerCharacters(): string[] {
+ return ['.'];
+ }
+
+ public async provideCompletionItems(
+ model: editor.ITextModel,
+ position: Position,
+ _context: languages.CompletionContext,
+ token: CancellationToken
+ ): Promise {
+ const wordInfo = model.getWordUntilPosition(position);
+ const wordRange = new Range(
+ position.lineNumber,
+ wordInfo.startColumn,
+ position.lineNumber,
+ wordInfo.endColumn
+ );
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const info = await worker.getCompletionsAtPosition(resource.toString(), offset);
+
+ if (!info || model.isDisposed()) {
+ return;
+ }
+
+ const suggestions: MyCompletionItem[] = info.entries.map((entry) => {
+ let range = wordRange;
+ if (entry.replacementSpan) {
+ const p1 = model.getPositionAt(entry.replacementSpan.start);
+ const p2 = model.getPositionAt(entry.replacementSpan.start + entry.replacementSpan.length);
+ range = new Range(p1.lineNumber, p1.column, p2.lineNumber, p2.column);
+ }
+
+ const tags: languages.CompletionItemTag[] = [];
+ if (entry.kindModifiers?.indexOf('deprecated') !== -1) {
+ tags.push(languages.CompletionItemTag.Deprecated);
+ }
+
+ return {
+ uri: resource,
+ position: position,
+ offset: offset,
+ range: range,
+ label: entry.name,
+ insertText: entry.name,
+ sortText: entry.sortText,
+ kind: SuggestAdapter.convertKind(entry.kind),
+ tags
+ };
+ });
+
+ return {
+ suggestions
+ };
+ }
+
+ public async resolveCompletionItem(
+ item: languages.CompletionItem,
+ token: CancellationToken
+ ): Promise {
+ const myItem = item;
+ const resource = myItem.uri;
+ const position = myItem.position;
+ const offset = myItem.offset;
+
+ const worker = await this._worker(resource);
+ const details = await worker.getCompletionEntryDetails(
+ resource.toString(),
+ offset,
+ myItem.label
+ );
+ if (!details) {
+ return myItem;
+ }
+ return {
+ uri: resource,
+ position: position,
+ label: details.name,
+ kind: SuggestAdapter.convertKind(details.kind),
+ detail: displayPartsToString(details.displayParts),
+ documentation: {
+ value: SuggestAdapter.createDocumentationString(details)
+ }
+ };
+ }
+
+ private static convertKind(kind: string): languages.CompletionItemKind {
+ switch (kind) {
+ case Kind.primitiveType:
+ case Kind.keyword:
+ return languages.CompletionItemKind.Keyword;
+ case Kind.variable:
+ case Kind.localVariable:
+ return languages.CompletionItemKind.Variable;
+ case Kind.memberVariable:
+ case Kind.memberGetAccessor:
+ case Kind.memberSetAccessor:
+ return languages.CompletionItemKind.Field;
+ case Kind.function:
+ case Kind.memberFunction:
+ case Kind.constructSignature:
+ case Kind.callSignature:
+ case Kind.indexSignature:
+ return languages.CompletionItemKind.Function;
+ case Kind.enum:
+ return languages.CompletionItemKind.Enum;
+ case Kind.module:
+ return languages.CompletionItemKind.Module;
+ case Kind.class:
+ return languages.CompletionItemKind.Class;
+ case Kind.interface:
+ return languages.CompletionItemKind.Interface;
+ case Kind.warning:
+ return languages.CompletionItemKind.File;
+ }
+
+ return languages.CompletionItemKind.Property;
+ }
+
+ private static createDocumentationString(details: ts.CompletionEntryDetails): string {
+ let documentationString = displayPartsToString(details.documentation);
+ if (details.tags) {
+ for (const tag of details.tags) {
+ documentationString += `\n\n${tagToString(tag)}`;
+ }
+ }
+ return documentationString;
+ }
+}
+
+function tagToString(tag: ts.JSDocTagInfo): string {
+ let tagLabel = `*@${tag.name}*`;
+ if (tag.name === 'param' && tag.text) {
+ const [paramName, ...rest] = tag.text;
+ tagLabel += `\`${paramName.text}\``;
+ if (rest.length > 0) tagLabel += ` — ${rest.map((r) => r.text).join(' ')}`;
+ } else if (Array.isArray(tag.text)) {
+ tagLabel += ` — ${tag.text.map((r) => r.text).join(' ')}`;
+ } else if (tag.text) {
+ tagLabel += ` — ${tag.text}`;
+ }
+ return tagLabel;
+}
+
+export class SignatureHelpAdapter extends Adapter implements languages.SignatureHelpProvider {
+ public signatureHelpTriggerCharacters = ['(', ','];
+
+ private static _toSignatureHelpTriggerReason(
+ context: languages.SignatureHelpContext
+ ): ts.SignatureHelpTriggerReason {
+ switch (context.triggerKind) {
+ case languages.SignatureHelpTriggerKind.TriggerCharacter:
+ if (context.triggerCharacter) {
+ if (context.isRetrigger) {
+ return { kind: 'retrigger', triggerCharacter: context.triggerCharacter as any };
+ } else {
+ return { kind: 'characterTyped', triggerCharacter: context.triggerCharacter as any };
+ }
+ } else {
+ return { kind: 'invoked' };
+ }
+
+ case languages.SignatureHelpTriggerKind.ContentChange:
+ return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
+
+ case languages.SignatureHelpTriggerKind.Invoke:
+ default:
+ return { kind: 'invoked' };
+ }
+ }
+
+ public async provideSignatureHelp(
+ model: editor.ITextModel,
+ position: Position,
+ token: CancellationToken,
+ context: languages.SignatureHelpContext
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const info = await worker.getSignatureHelpItems(resource.toString(), offset, {
+ triggerReason: SignatureHelpAdapter._toSignatureHelpTriggerReason(context)
+ });
+
+ if (!info || model.isDisposed()) {
+ return;
+ }
+
+ const ret: languages.SignatureHelp = {
+ activeSignature: info.selectedItemIndex,
+ activeParameter: info.argumentIndex,
+ signatures: []
+ };
+
+ info.items.forEach((item) => {
+ const signature: languages.SignatureInformation = {
+ label: '',
+ parameters: []
+ };
+
+ signature.documentation = {
+ value: displayPartsToString(item.documentation)
+ };
+ signature.label += displayPartsToString(item.prefixDisplayParts);
+ item.parameters.forEach((p, i, a) => {
+ const label = displayPartsToString(p.displayParts);
+ const parameter: languages.ParameterInformation = {
+ label: label,
+ documentation: {
+ value: displayPartsToString(p.documentation)
+ }
+ };
+ signature.label += label;
+ signature.parameters.push(parameter);
+ if (i < a.length - 1) {
+ signature.label += displayPartsToString(item.separatorDisplayParts);
+ }
+ });
+ signature.label += displayPartsToString(item.suffixDisplayParts);
+ ret.signatures.push(signature);
+ });
+
+ return {
+ value: ret,
+ dispose() {}
+ };
+ }
+}
+
+// --- hover ------
+
+export class QuickInfoAdapter extends Adapter implements languages.HoverProvider {
+ public async provideHover(
+ model: editor.ITextModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const info = await worker.getQuickInfoAtPosition(resource.toString(), offset);
+
+ if (!info || model.isDisposed()) {
+ return;
+ }
+
+ const documentation = displayPartsToString(info.documentation);
+ const tags = info.tags ? info.tags.map((tag) => tagToString(tag)).join(' \n\n') : '';
+ const contents = displayPartsToString(info.displayParts);
+ return {
+ range: this._textSpanToRange(model, info.textSpan),
+ contents: [
+ {
+ value: '```typescript\n' + contents + '\n```\n'
+ },
+ {
+ value: documentation + (tags ? '\n\n' + tags : '')
+ }
+ ]
+ };
+ }
+}
+
+// --- occurrences ------
+
+export class OccurrencesAdapter extends Adapter implements languages.DocumentHighlightProvider {
+ public async provideDocumentHighlights(
+ model: editor.ITextModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const entries = await worker.getOccurrencesAtPosition(resource.toString(), offset);
+
+ if (!entries || model.isDisposed()) {
+ return;
+ }
+
+ return entries.map((entry) => {
+ return {
+ range: this._textSpanToRange(model, entry.textSpan),
+ kind: entry.isWriteAccess
+ ? languages.DocumentHighlightKind.Write
+ : languages.DocumentHighlightKind.Text
+ };
+ });
+ }
+}
+
+// --- definition ------
+
+export class DefinitionAdapter extends Adapter {
+ constructor(
+ private readonly _libFiles: LibFiles,
+ worker: (...uris: Uri[]) => Promise
+ ) {
+ super(worker);
+ }
+
+ public async provideDefinition(
+ model: editor.ITextModel,
+ position: Position,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const entries = await worker.getDefinitionAtPosition(resource.toString(), offset);
+
+ if (!entries || model.isDisposed()) {
+ return;
+ }
+
+ // Fetch lib files if necessary
+ await this._libFiles.fetchLibFilesIfNecessary(
+ entries.map((entry) => Uri.parse(entry.fileName))
+ );
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const result: languages.Location[] = [];
+ for (let entry of entries) {
+ const refModel = this._libFiles.getOrCreateModel(entry.fileName);
+ if (refModel) {
+ result.push({
+ uri: refModel.uri,
+ range: this._textSpanToRange(refModel, entry.textSpan)
+ });
+ }
+ }
+ return result;
+ }
+}
+
+// --- references ------
+
+export class ReferenceAdapter extends Adapter implements languages.ReferenceProvider {
+ constructor(
+ private readonly _libFiles: LibFiles,
+ worker: (...uris: Uri[]) => Promise
+ ) {
+ super(worker);
+ }
+
+ public async provideReferences(
+ model: editor.ITextModel,
+ position: Position,
+ context: languages.ReferenceContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const entries = await worker.getReferencesAtPosition(resource.toString(), offset);
+
+ if (!entries || model.isDisposed()) {
+ return;
+ }
+
+ // Fetch lib files if necessary
+ await this._libFiles.fetchLibFilesIfNecessary(
+ entries.map((entry) => Uri.parse(entry.fileName))
+ );
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const result: languages.Location[] = [];
+ for (let entry of entries) {
+ const refModel = this._libFiles.getOrCreateModel(entry.fileName);
+ if (refModel) {
+ result.push({
+ uri: refModel.uri,
+ range: this._textSpanToRange(refModel, entry.textSpan)
+ });
+ }
+ }
+ return result;
+ }
+}
+
+// --- outline ------
+
+export class OutlineAdapter extends Adapter implements languages.DocumentSymbolProvider {
+ public async provideDocumentSymbols(
+ model: editor.ITextModel,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const items = await worker.getNavigationBarItems(resource.toString());
+
+ if (!items || model.isDisposed()) {
+ return;
+ }
+
+ const convert = (
+ bucket: languages.DocumentSymbol[],
+ item: ts.NavigationBarItem,
+ containerLabel?: string
+ ): void => {
+ let result: languages.DocumentSymbol = {
+ name: item.text,
+ detail: '',
+ kind: (outlineTypeTable[item.kind] || languages.SymbolKind.Variable),
+ range: this._textSpanToRange(model, item.spans[0]),
+ selectionRange: this._textSpanToRange(model, item.spans[0]),
+ tags: []
+ };
+
+ if (containerLabel) result.containerName = containerLabel;
+
+ if (item.childItems && item.childItems.length > 0) {
+ for (let child of item.childItems) {
+ convert(bucket, child, result.name);
+ }
+ }
+
+ bucket.push(result);
+ };
+
+ let result: languages.DocumentSymbol[] = [];
+ items.forEach((item) => convert(result, item));
+ return result;
+ }
+}
+
+export class Kind {
+ public static unknown: string = '';
+ public static keyword: string = 'keyword';
+ public static script: string = 'script';
+ public static module: string = 'module';
+ public static class: string = 'class';
+ public static interface: string = 'interface';
+ public static type: string = 'type';
+ public static enum: string = 'enum';
+ public static variable: string = 'var';
+ public static localVariable: string = 'local var';
+ public static function: string = 'function';
+ public static localFunction: string = 'local function';
+ public static memberFunction: string = 'method';
+ public static memberGetAccessor: string = 'getter';
+ public static memberSetAccessor: string = 'setter';
+ public static memberVariable: string = 'property';
+ public static constructorImplementation: string = 'constructor';
+ public static callSignature: string = 'call';
+ public static indexSignature: string = 'index';
+ public static constructSignature: string = 'construct';
+ public static parameter: string = 'parameter';
+ public static typeParameter: string = 'type parameter';
+ public static primitiveType: string = 'primitive type';
+ public static label: string = 'label';
+ public static alias: string = 'alias';
+ public static const: string = 'const';
+ public static let: string = 'let';
+ public static warning: string = 'warning';
+}
+
+let outlineTypeTable: {
+ [kind: string]: languages.SymbolKind;
+} = Object.create(null);
+outlineTypeTable[Kind.module] = languages.SymbolKind.Module;
+outlineTypeTable[Kind.class] = languages.SymbolKind.Class;
+outlineTypeTable[Kind.enum] = languages.SymbolKind.Enum;
+outlineTypeTable[Kind.interface] = languages.SymbolKind.Interface;
+outlineTypeTable[Kind.memberFunction] = languages.SymbolKind.Method;
+outlineTypeTable[Kind.memberVariable] = languages.SymbolKind.Property;
+outlineTypeTable[Kind.memberGetAccessor] = languages.SymbolKind.Property;
+outlineTypeTable[Kind.memberSetAccessor] = languages.SymbolKind.Property;
+outlineTypeTable[Kind.variable] = languages.SymbolKind.Variable;
+outlineTypeTable[Kind.const] = languages.SymbolKind.Variable;
+outlineTypeTable[Kind.localVariable] = languages.SymbolKind.Variable;
+outlineTypeTable[Kind.variable] = languages.SymbolKind.Variable;
+outlineTypeTable[Kind.function] = languages.SymbolKind.Function;
+outlineTypeTable[Kind.localFunction] = languages.SymbolKind.Function;
+
+// --- formatting ----
+
+export abstract class FormatHelper extends Adapter {
+ protected static _convertOptions(options: languages.FormattingOptions): ts.FormatCodeOptions {
+ return {
+ ConvertTabsToSpaces: options.insertSpaces,
+ TabSize: options.tabSize,
+ IndentSize: options.tabSize,
+ IndentStyle: IndentStyle.Smart,
+ NewLineCharacter: '\n',
+ InsertSpaceAfterCommaDelimiter: true,
+ InsertSpaceAfterSemicolonInForStatements: true,
+ InsertSpaceBeforeAndAfterBinaryOperators: true,
+ InsertSpaceAfterKeywordsInControlFlowStatements: true,
+ InsertSpaceAfterFunctionKeywordForAnonymousFunctions: true,
+ InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
+ InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
+ InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
+ PlaceOpenBraceOnNewLineForControlBlocks: false,
+ PlaceOpenBraceOnNewLineForFunctions: false
+ };
+ }
+
+ protected _convertTextChanges(
+ model: editor.ITextModel,
+ change: ts.TextChange
+ ): languages.TextEdit {
+ return {
+ text: change.newText,
+ range: this._textSpanToRange(model, change.span)
+ };
+ }
+}
+
+export class FormatAdapter
+ extends FormatHelper
+ implements languages.DocumentRangeFormattingEditProvider
+{
+ public async provideDocumentRangeFormattingEdits(
+ model: editor.ITextModel,
+ range: Range,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const startOffset = model.getOffsetAt({
+ lineNumber: range.startLineNumber,
+ column: range.startColumn
+ });
+ const endOffset = model.getOffsetAt({
+ lineNumber: range.endLineNumber,
+ column: range.endColumn
+ });
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const edits = await worker.getFormattingEditsForRange(
+ resource.toString(),
+ startOffset,
+ endOffset,
+ FormatHelper._convertOptions(options)
+ );
+
+ if (!edits || model.isDisposed()) {
+ return;
+ }
+
+ return edits.map((edit) => this._convertTextChanges(model, edit));
+ }
+}
+
+export class FormatOnTypeAdapter
+ extends FormatHelper
+ implements languages.OnTypeFormattingEditProvider
+{
+ get autoFormatTriggerCharacters() {
+ return [';', '}', '\n'];
+ }
+
+ public async provideOnTypeFormattingEdits(
+ model: editor.ITextModel,
+ position: Position,
+ ch: string,
+ options: languages.FormattingOptions,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const edits = await worker.getFormattingEditsAfterKeystroke(
+ resource.toString(),
+ offset,
+ ch,
+ FormatHelper._convertOptions(options)
+ );
+
+ if (!edits || model.isDisposed()) {
+ return;
+ }
+
+ return edits.map((edit) => this._convertTextChanges(model, edit));
+ }
+}
+
+// --- code actions ------
+
+export class CodeActionAdaptor extends FormatHelper implements languages.CodeActionProvider {
+ public async provideCodeActions(
+ model: editor.ITextModel,
+ range: Range,
+ context: languages.CodeActionContext,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const start = model.getOffsetAt({
+ lineNumber: range.startLineNumber,
+ column: range.startColumn
+ });
+ const end = model.getOffsetAt({
+ lineNumber: range.endLineNumber,
+ column: range.endColumn
+ });
+ const formatOptions = FormatHelper._convertOptions(model.getOptions());
+ const errorCodes = context.markers
+ .filter((m) => m.code)
+ .map((m) => m.code)
+ .map(Number);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const codeFixes = await worker.getCodeFixesAtPosition(
+ resource.toString(),
+ start,
+ end,
+ errorCodes,
+ formatOptions
+ );
+
+ if (!codeFixes || model.isDisposed()) {
+ return { actions: [], dispose: () => {} };
+ }
+
+ const actions = codeFixes
+ .filter((fix) => {
+ // Removes any 'make a new file'-type code fix
+ return fix.changes.filter((change) => change.isNewFile).length === 0;
+ })
+ .map((fix) => {
+ return this._tsCodeFixActionToMonacoCodeAction(model, context, fix);
+ });
+
+ return {
+ actions: actions,
+ dispose: () => {}
+ };
+ }
+
+ private _tsCodeFixActionToMonacoCodeAction(
+ model: editor.ITextModel,
+ context: languages.CodeActionContext,
+ codeFix: ts.CodeFixAction
+ ): languages.CodeAction {
+ const edits: languages.WorkspaceTextEdit[] = [];
+ for (const change of codeFix.changes) {
+ for (const textChange of change.textChanges) {
+ edits.push({
+ resource: model.uri,
+ edit: {
+ range: this._textSpanToRange(model, textChange.span),
+ text: textChange.newText
+ }
+ });
+ }
+ }
+
+ const action: languages.CodeAction = {
+ title: codeFix.description,
+ edit: { edits: edits },
+ diagnostics: context.markers,
+ kind: 'quickfix'
+ };
+
+ return action;
+ }
+}
+// --- rename ----
+
+export class RenameAdapter extends Adapter implements languages.RenameProvider {
+ constructor(
+ private readonly _libFiles: LibFiles,
+ worker: (...uris: Uri[]) => Promise
+ ) {
+ super(worker);
+ }
+ public async provideRenameEdits(
+ model: editor.ITextModel,
+ position: Position,
+ newName: string,
+ token: CancellationToken
+ ): Promise<(languages.WorkspaceEdit & languages.Rejection) | undefined> {
+ const resource = model.uri;
+ const fileName = resource.toString();
+ const offset = model.getOffsetAt(position);
+ const worker = await this._worker(resource);
+
+ if (model.isDisposed()) {
+ return;
+ }
+
+ const renameInfo = await worker.getRenameInfo(fileName, offset, {
+ allowRenameOfImportPath: false
+ });
+ if (renameInfo.canRename === false) {
+ // use explicit comparison so that the discriminated union gets resolved properly
+ return {
+ edits: [],
+ rejectReason: renameInfo.localizedErrorMessage
+ };
+ }
+ if (renameInfo.fileToRename !== undefined) {
+ throw new Error('Renaming files is not supported.');
+ }
+
+ const renameLocations = await worker.findRenameLocations(
+ fileName,
+ offset,
+ /*strings*/ false,
+ /*comments*/ false,
+ /*prefixAndSuffix*/ false
+ );
+
+ if (!renameLocations || model.isDisposed()) {
+ return;
+ }
+
+ const edits: languages.WorkspaceTextEdit[] = [];
+ for (const renameLocation of renameLocations) {
+ const model = this._libFiles.getOrCreateModel(renameLocation.fileName);
+ if (model) {
+ edits.push({
+ resource: model.uri,
+ edit: {
+ range: this._textSpanToRange(model, renameLocation.textSpan),
+ text: newName
+ }
+ });
+ } else {
+ throw new Error(`Unknown file ${renameLocation.fileName}.`);
+ }
+ }
+
+ return { edits };
+ }
+}
+
+// --- inlay hints ----
+
+export class InlayHintsAdapter extends Adapter implements languages.InlayHintsProvider {
+ public async provideInlayHints(
+ model: editor.ITextModel,
+ range: Range,
+ token: CancellationToken
+ ): Promise {
+ const resource = model.uri;
+ const fileName = resource.toString();
+ const start = model.getOffsetAt({
+ lineNumber: range.startLineNumber,
+ column: range.startColumn
+ });
+ const end = model.getOffsetAt({
+ lineNumber: range.endLineNumber,
+ column: range.endColumn
+ });
+ const worker = await this._worker(resource);
+ if (model.isDisposed()) {
+ return [];
+ }
+
+ const hints = await worker.provideInlayHints(fileName, start, end);
+
+ return hints.map((hint) => {
+ return {
+ ...hint,
+ position: model.getPositionAt(hint.position),
+ kind: this._convertHintKind(hint.kind)
+ };
+ });
+ }
+
+ private _convertHintKind(kind?: ts.InlayHintKind) {
+ switch (kind) {
+ case 'Parameter':
+ return languages.InlayHintKind.Parameter;
+ case 'Type':
+ return languages.InlayHintKind.Type;
+ default:
+ return languages.InlayHintKind.Other;
+ }
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-lib-lib.index.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-lib-lib.index.ts.txt
new file mode 100644
index 000000000..a501460f0
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-lib-lib.index.ts.txt
@@ -0,0 +1,72 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+//
+// **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
+//
+
+
+/** Contains all the lib files */
+export const libFileSet: Record = {}
+libFileSet['lib.d.ts'] = true;
+libFileSet['lib.dom.d.ts'] = true;
+libFileSet['lib.dom.iterable.d.ts'] = true;
+libFileSet['lib.es2015.collection.d.ts'] = true;
+libFileSet['lib.es2015.core.d.ts'] = true;
+libFileSet['lib.es2015.d.ts'] = true;
+libFileSet['lib.es2015.generator.d.ts'] = true;
+libFileSet['lib.es2015.iterable.d.ts'] = true;
+libFileSet['lib.es2015.promise.d.ts'] = true;
+libFileSet['lib.es2015.proxy.d.ts'] = true;
+libFileSet['lib.es2015.reflect.d.ts'] = true;
+libFileSet['lib.es2015.symbol.d.ts'] = true;
+libFileSet['lib.es2015.symbol.wellknown.d.ts'] = true;
+libFileSet['lib.es2016.array.include.d.ts'] = true;
+libFileSet['lib.es2016.d.ts'] = true;
+libFileSet['lib.es2016.full.d.ts'] = true;
+libFileSet['lib.es2017.d.ts'] = true;
+libFileSet['lib.es2017.full.d.ts'] = true;
+libFileSet['lib.es2017.intl.d.ts'] = true;
+libFileSet['lib.es2017.object.d.ts'] = true;
+libFileSet['lib.es2017.sharedmemory.d.ts'] = true;
+libFileSet['lib.es2017.string.d.ts'] = true;
+libFileSet['lib.es2017.typedarrays.d.ts'] = true;
+libFileSet['lib.es2018.asyncgenerator.d.ts'] = true;
+libFileSet['lib.es2018.asynciterable.d.ts'] = true;
+libFileSet['lib.es2018.d.ts'] = true;
+libFileSet['lib.es2018.full.d.ts'] = true;
+libFileSet['lib.es2018.intl.d.ts'] = true;
+libFileSet['lib.es2018.promise.d.ts'] = true;
+libFileSet['lib.es2018.regexp.d.ts'] = true;
+libFileSet['lib.es2019.array.d.ts'] = true;
+libFileSet['lib.es2019.d.ts'] = true;
+libFileSet['lib.es2019.full.d.ts'] = true;
+libFileSet['lib.es2019.object.d.ts'] = true;
+libFileSet['lib.es2019.string.d.ts'] = true;
+libFileSet['lib.es2019.symbol.d.ts'] = true;
+libFileSet['lib.es2020.bigint.d.ts'] = true;
+libFileSet['lib.es2020.d.ts'] = true;
+libFileSet['lib.es2020.full.d.ts'] = true;
+libFileSet['lib.es2020.intl.d.ts'] = true;
+libFileSet['lib.es2020.promise.d.ts'] = true;
+libFileSet['lib.es2020.sharedmemory.d.ts'] = true;
+libFileSet['lib.es2020.string.d.ts'] = true;
+libFileSet['lib.es2020.symbol.wellknown.d.ts'] = true;
+libFileSet['lib.es2021.d.ts'] = true;
+libFileSet['lib.es2021.full.d.ts'] = true;
+libFileSet['lib.es2021.promise.d.ts'] = true;
+libFileSet['lib.es2021.string.d.ts'] = true;
+libFileSet['lib.es2021.weakref.d.ts'] = true;
+libFileSet['lib.es5.d.ts'] = true;
+libFileSet['lib.es6.d.ts'] = true;
+libFileSet['lib.esnext.d.ts'] = true;
+libFileSet['lib.esnext.full.d.ts'] = true;
+libFileSet['lib.esnext.intl.d.ts'] = true;
+libFileSet['lib.esnext.promise.d.ts'] = true;
+libFileSet['lib.esnext.string.d.ts'] = true;
+libFileSet['lib.esnext.weakref.d.ts'] = true;
+libFileSet['lib.scripthost.d.ts'] = true;
+libFileSet['lib.webworker.d.ts'] = true;
+libFileSet['lib.webworker.importscripts.d.ts'] = true;
+libFileSet['lib.webworker.iterable.d.ts'] = true;
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsMode.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsMode.ts.txt
new file mode 100644
index 000000000..9ebf59cf6
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsMode.ts.txt
@@ -0,0 +1,87 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { 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';
+
+let javaScriptWorker: (...uris: Uri[]) => Promise;
+let typeScriptWorker: (...uris: Uri[]) => Promise;
+
+export function setupTypeScript(defaults: LanguageServiceDefaults): void {
+ typeScriptWorker = setupMode(defaults, 'typescript');
+}
+
+export function setupJavaScript(defaults: LanguageServiceDefaults): void {
+ javaScriptWorker = setupMode(defaults, 'javascript');
+}
+
+export function getJavaScriptWorker(): Promise<(...uris: Uri[]) => Promise> {
+ return new Promise((resolve, reject) => {
+ if (!javaScriptWorker) {
+ return reject('JavaScript not registered!');
+ }
+
+ resolve(javaScriptWorker);
+ });
+}
+
+export function getTypeScriptWorker(): Promise<(...uris: Uri[]) => Promise> {
+ return new Promise((resolve, reject) => {
+ if (!typeScriptWorker) {
+ return reject('TypeScript not registered!');
+ }
+
+ resolve(typeScriptWorker);
+ });
+}
+
+function setupMode(
+ defaults: LanguageServiceDefaults,
+ modeId: string
+): (...uris: Uri[]) => Promise {
+ const client = new WorkerManager(modeId, defaults);
+ const worker = (...uris: Uri[]): Promise => {
+ 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);
+ return worker;
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsconfig.json.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsconfig.json.txt
new file mode 100644
index 000000000..001f587e6
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-tsconfig.json.txt
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "module": "amd",
+ "moduleResolution": "node",
+ "outDir": "../out/amd",
+ "declaration": true,
+ "target": "es5",
+ "lib": ["dom", "es5", "es2015.collection", "es2015.iterable", "es2015.promise"],
+ "strict": true
+ }
+}
diff --git a/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-workerManager.ts.txt b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-workerManager.ts.txt
new file mode 100644
index 000000000..6e70ae025
--- /dev/null
+++ b/refactor/baselines/site-vendor/monaco-modes/monaco-typescript-src-workerManager.ts.txt
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { LanguageServiceDefaults } from './monaco.contribution';
+import type { TypeScriptWorker } from './tsWorker';
+import { editor, Uri, IDisposable } from './fillers/monaco-editor-core';
+
+export class WorkerManager {
+ private _modeId: string;
+ private _defaults: LanguageServiceDefaults;
+ private _configChangeListener: IDisposable;
+ private _updateExtraLibsToken: number;
+ private _extraLibsChangeListener: IDisposable;
+
+ private _worker: editor.MonacoWebWorker | null;
+ private _client: Promise | null;
+
+ constructor(modeId: string, defaults: LanguageServiceDefaults) {
+ this._modeId = modeId;
+ this._defaults = defaults;
+ this._worker = null;
+ this._client = null;
+ this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
+ this._updateExtraLibsToken = 0;
+ this._extraLibsChangeListener = this._defaults.onDidExtraLibsChange(() =>
+ this._updateExtraLibs()
+ );
+ }
+
+ private _stopWorker(): void {
+ if (this._worker) {
+ this._worker.dispose();
+ this._worker = null;
+ }
+ this._client = null;
+ }
+
+ dispose(): void {
+ this._configChangeListener.dispose();
+ this._extraLibsChangeListener.dispose();
+ this._stopWorker();
+ }
+
+ private async _updateExtraLibs(): Promise {
+ if (!this._worker) {
+ return;
+ }
+ const myToken = ++this._updateExtraLibsToken;
+ const proxy = await this._worker.getProxy();
+ if (this._updateExtraLibsToken !== myToken) {
+ // avoid multiple calls
+ return;
+ }
+ proxy.updateExtraLibs(this._defaults.getExtraLibs());
+ }
+
+ private _getClient(): Promise {
+ if (!this._client) {
+ this._worker = editor.createWebWorker({
+ // module that exports the create() method and returns a `TypeScriptWorker` instance
+ moduleId: 'vs/language/typescript/tsWorker',
+
+ label: this._modeId,
+
+ keepIdleModels: true,
+
+ // passed in to the create() method
+ createData: {
+ compilerOptions: this._defaults.getCompilerOptions(),
+ extraLibs: this._defaults.getExtraLibs(),
+ customWorkerPath: this._defaults.workerOptions.customWorkerPath,
+ inlayHintsOptions: this._defaults.inlayHintsOptions
+ }
+ });
+
+ let p = >this._worker.getProxy();
+
+ if (this._defaults.getEagerModelSync()) {
+ p = p.then((worker) => {
+ if (this._worker) {
+ return this._worker.withSyncedResources(
+ editor
+ .getModels()
+ .filter((model) => model.getLanguageId() === this._modeId)
+ .map((model) => model.uri)
+ );
+ }
+ return worker;
+ });
+ }
+
+ this._client = p;
+ }
+
+ return this._client;
+ }
+
+ getLanguageServiceWorker(...resources: Uri[]): Promise {
+ let _client: TypeScriptWorker;
+ return this._getClient()
+ .then((client) => {
+ _client = client;
+ })
+ .then((_) => {
+ if (this._worker) {
+ return this._worker.withSyncedResources(resources);
+ }
+ })
+ .then((_) => _client);
+ }
+}
diff --git a/refactor/changes/2026-09-15-SITE-07-monaco-modes.md b/refactor/changes/2026-09-15-SITE-07-monaco-modes.md
new file mode 100644
index 000000000..c776a93f1
--- /dev/null
+++ b/refactor/changes/2026-09-15-SITE-07-monaco-modes.md
@@ -0,0 +1,45 @@
+# SITE-07 Monaco 四种语言模式来源与编辑器集成
+
+修改前 HEAD:99c208aeee331eec2d9ffa9bb15a608fdc17a840。
+Thumbnail 默认策略仍待用户选择,本批不改变该包的配置。
+
+## 本批实现
+
+新增四个 mode bundle 的固定来源记录及可重复执行脚本。六份 npm 归档、23 份
+固定 Git 文件包含构建配方、配置、14 个 Monaco TS 模块与六个依赖源码;另有
+两个包别名。CSS/HTML/JSON/TypeScript 分别有 5/5/12/4 个模块实例。复用全片段
+检查覆盖辅助代码和模块之间所有非空白字节,不只比较 AMD 模块名。
+四个完整压缩产物均与当前站点逐字节相等。
+
+抽出 compiler.ts 统一固定 TypeScript 4.4.4 发射,保持原标准库与各包 strict
+配置。JSON tokenization 使用 jsonc-parser 3.0.0 原始声明解析 const enum;孤立
+编译保留属性访问不能复现旧产物,因此不能手工替换数字。解析器仅允许显式
+传入的声明,不意外读当前工作区依赖。仍不声称已恢复上游完整语义类型检查。
+
+AMD 模块名增加合法 lib.index 支持,继续拒绝路径遍历段。新反例验证错误枚举
+声明会导致复现失败;此前 TypeScript 源转换和缺失模块/额外辅助代码测试保留。
+共享编译器改动后重跑全部三个语言 worker 源码及压缩复现,保持精确相等。
+
+jsonc-parser 与 vscode-languageserver-types 的 notice 资产绑定扩大到模式文件。
+这两包原有完整许可已随站点交付,没有新增或改写 notice 正文。站点依然有
+81 份 notice 加一个索引。Monaco 运行代码、旧 URL、根依赖和 yarn.lock 未变。
+
+## 实际编辑器验证
+
+新增 editor-modes.spec.js 使用真实 Monaco editor,通过自动模式加载和 provider
+注册检测 CSS/JSON/TypeScript 错误,再改成合法代码等待诊断清空。调用编辑器的
+文档格式化 action 验证 JSON/HTML 输出分行且内容保留;四个 mode 请求必须成功。
+同一个编辑器依次切换模型,最后销毁并检查旧模型诊断被清理。
+
+早期测试读取了不属于 0.30.1 的 getModeId;对照该包原始声明后使用 getLanguageId。
+这是测试元数据接口修正,没有改生产逻辑或放宽诊断/格式化断言。
+
+三引擎 3/3 通过,无重试/跳过;15/15 单元、严格 docs-tools 类型与相关 lint
+通过。来源复现、网络尝试和浏览器环境见
+[验证记录](../baselines/monaco-modes-validation.json)。网络首次请求出现 npm DNS
+ENOTFOUND,保留失败记录;缓存离线验证不被冒充为首次联网成功。
+
+SITE-07 doing / VENDOR-06 open,整体仍 199/265。Monaco editor-core、基础语言
+定义及其余上游来源细节继续审查,物理设备/外部 SDK/远端 CI/三轮复盘门槛
+未完成。回退本批脚本、绑定和测试即可,运行资产未改。独立本地提交,不推送、
+不部署、不发布,也不替用户决定 Thumbnail 默认行为。
diff --git a/refactor/plan.md b/refactor/plan.md
index e0a8cfe45..46430ec35 100644
--- a/refactor/plan.md
+++ b/refactor/plan.md
@@ -653,7 +653,7 @@
- SITE-AI-DOCS-01: [记录](changes/2026-09-14-SITE-AI-DOCS-01-documentation-pipeline.md) [记录](baselines/documentation-pipeline-validation.json)
- SITE-BUILD-01: [记录](changes/2026-09-14-SITE-BUILD-01-staged-builds.md) [记录](baselines/site-build-validation.json)
- SITE-03: [记录](changes/2026-09-14-SITE-03-desktop-editor.md) [记录](baselines/site-editor-validation.json)
-- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md) [记录](baselines/console-derived-attribution.json) [记录](baselines/console-derived-validation.json) [记录](changes/2026-09-15-SITE-07-console-derived-attribution.md) [记录](baselines/console-stackoverflow-provenance.json) [记录](baselines/console-stackoverflow-validation.json) [记录](changes/2026-09-15-SITE-07-console-stackoverflow.md) [记录](baselines/console-shallowequal-validation.json) [记录](changes/2026-09-15-SITE-07-console-shallowequal.md) [记录](console-notice-review.md) [记录](baselines/console-notice-review-validation.json) [记录](changes/2026-09-15-SITE-07-console-notice-review.md) [记录](baselines/monaco-typescript-provenance.json) [记录](baselines/monaco-typescript-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-typescript.md) [记录](baselines/monaco-languages-provenance.json) [记录](baselines/monaco-languages-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-languages.md) [记录](baselines/monaco-language-notices.json) [记录](baselines/monaco-language-notices-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-language-notices.md)
+- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md) [记录](baselines/console-derived-attribution.json) [记录](baselines/console-derived-validation.json) [记录](changes/2026-09-15-SITE-07-console-derived-attribution.md) [记录](baselines/console-stackoverflow-provenance.json) [记录](baselines/console-stackoverflow-validation.json) [记录](changes/2026-09-15-SITE-07-console-stackoverflow.md) [记录](baselines/console-shallowequal-validation.json) [记录](changes/2026-09-15-SITE-07-console-shallowequal.md) [记录](console-notice-review.md) [记录](baselines/console-notice-review-validation.json) [记录](changes/2026-09-15-SITE-07-console-notice-review.md) [记录](baselines/monaco-typescript-provenance.json) [记录](baselines/monaco-typescript-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-typescript.md) [记录](baselines/monaco-languages-provenance.json) [记录](baselines/monaco-languages-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-languages.md) [记录](baselines/monaco-language-notices.json) [记录](baselines/monaco-language-notices-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-language-notices.md) [记录](baselines/monaco-modes-provenance.json) [记录](baselines/monaco-modes-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-modes.md)
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
- MOD-01: [记录](changes/2026-09-15-MOD-01-bun-evaluation.md) [记录](baselines/bun-install-validation.json) [记录](bun-evaluation.md)
diff --git a/refactor/progress.md b/refactor/progress.md
index bed2fcf36..6c2e4f1b9 100644
--- a/refactor/progress.md
+++ b/refactor/progress.md
@@ -1,5 +1,14 @@
# 进度与证据
+## SITE-07 Monaco 四种语言模式
+
+CSS/HTML/JSON/TypeScript mode 的 26 个模块实例及完整压缩产物已精确复现,
+使用 6 归档/23 Git 来源,jsonc 原声明驱动 const enum 编译;许可绑定补齐模式
+资产。单元 15/15,自动编辑器诊断/格式化/切换/销毁三引擎 3/3,三个 worker
+共享编译器回归复现通过。联网首次 DNS 失败后重试成功,离线复现独立通过。
+见[记录](changes/2026-09-15-SITE-07-monaco-modes.md)。运行/notice 字节与锁未变,
+199/265,SITE-07/VENDOR-06 仍开放;Thumbnail 默认决策仍待答。
+
## PKG-TOOL-THUMB-04 默认兼容策略待选择
重新核对恢复的 3.5.31 与工作区 4.4.0,历史契约/行为 62/62 通过。已将先前待答
diff --git a/refactor/risks.json b/refactor/risks.json
index 8bb862c17..5b1ce6ef2 100644
--- a/refactor/risks.json
+++ b/refactor/risks.json
@@ -638,11 +638,16 @@
"refactor/baselines/monaco-language-notices.json",
"refactor/baselines/monaco-language-notices-validation.json",
"refactor/changes/2026-09-15-SITE-07-monaco-language-notices.md",
- "scripts/site-vendor/monaco/notices.ts"
+ "scripts/site-vendor/monaco/notices.ts",
+ "refactor/baselines/monaco-modes-provenance.json",
+ "refactor/baselines/monaco-modes-validation.json",
+ "refactor/changes/2026-09-15-SITE-07-monaco-modes.md",
+ "scripts/site-vendor/monaco/compiler.ts",
+ "scripts/site-vendor/monaco/reproduce-modes.ts"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。",
- "workspaceState": "Monaco 0.30.1 TypeScript worker identifies 4.4.4, unlike the original stale 2.7.2 notice. Fixed Git lock/recipes and four archives prove the 9698327-character adapted service segment and exact minified worker. Three original TypeScript notices plus a version/modification explanation are delivered. Unit 10/10 and three-engine editor/notice checks 6/6 pass. Other language services, shim, core embedded libraries and language definitions remain under review; VENDOR-06 is open. CSS/HTML/JSON complete workers now have exact source coverage for 119 module instances from 91 npm sources, 8 aliases, a shared Monaco-owned nls shim and three adapters; 11 archives/13 Git sources and all three minified outputs match. Four unit tests and three real-engine diagnostics/completion/formatting checks pass. Service notices, embedded attribution, mode bundles, core and basic languages remain open. Seven language-service packages now deliver nine original notices, two complete formatter source headers and attribution. JSON glob BSD terms and the HTML formatter author-year difference are preserved. Component/source/notice bindings and all 81 site notice HTTP bytes/links pass; unit 14/14 and three-engine language/mobile suites 6/6. Broader Monaco origin review remains open."
+ "workspaceState": "Monaco 0.30.1 TypeScript worker identifies 4.4.4, unlike the original stale 2.7.2 notice. Fixed Git lock/recipes and four archives prove the 9698327-character adapted service segment and exact minified worker. Three original TypeScript notices plus a version/modification explanation are delivered. Unit 10/10 and three-engine editor/notice checks 6/6 pass. Other language services, shim, core embedded libraries and language definitions remain under review; VENDOR-06 is open. CSS/HTML/JSON complete workers now have exact source coverage for 119 module instances from 91 npm sources, 8 aliases, a shared Monaco-owned nls shim and three adapters; 11 archives/13 Git sources and all three minified outputs match. Four unit tests and three real-engine diagnostics/completion/formatting checks pass. Service notices, embedded attribution, mode bundles, core and basic languages remain open. Seven language-service packages now deliver nine original notices, two complete formatter source headers and attribution. JSON glob BSD terms and the HTML formatter author-year difference are preserved. Component/source/notice bindings and all 81 site notice HTTP bytes/links pass; unit 14/14 and three-engine language/mobile suites 6/6. Broader Monaco origin review remains open. All four mode bundles now reproduce exactly from 14 Monaco sources, 6 npm modules and 2 aliases (26 instances), with 6 archives/23 Git files. jsonc-parser declarations drive const enum emission; mode assets are included in license bindings. Automatic editor diagnostics/formatting/model-switch/cleanup checks pass in three engines, unit 15/15 and all three worker source regressions pass. Core/basic-language and remaining origin review remain open."
},
{
"id": "VENDOR-07",
diff --git a/refactor/tasks.json b/refactor/tasks.json
index 1d104f78a..e875e1101 100644
--- a/refactor/tasks.json
+++ b/refactor/tasks.json
@@ -4522,7 +4522,10 @@
"changes/2026-09-15-SITE-07-monaco-languages.md",
"baselines/monaco-language-notices.json",
"baselines/monaco-language-notices-validation.json",
- "changes/2026-09-15-SITE-07-monaco-language-notices.md"
+ "changes/2026-09-15-SITE-07-monaco-language-notices.md",
+ "baselines/monaco-modes-provenance.json",
+ "baselines/monaco-modes-validation.json",
+ "changes/2026-09-15-SITE-07-monaco-modes.md"
]
},
{
diff --git a/refactor/third-party.json b/refactor/third-party.json
index b7bd7cae3..df9a8ba54 100644
--- a/refactor/third-party.json
+++ b/refactor/third-party.json
@@ -512,7 +512,7 @@
"SITE-05"
],
"sourceStatus": "Monaco 0.30.1 verified against official npm archive: 98 byte-exact files, one CSS newline-only difference. The bundled font additionally matches @vscode/codicons 0.0.26 exactly; see site-codicons-provenance.json.",
- "licenseStatus": "Full Monaco root notices and Codicons historical notices are delivered. The actual TypeScript 4.4.4 worker is exactly reproduced and has a complete original LICENSE/CopyrightNotice/ThirdPartyNoticeText supplement plus attribution; the original stale 2.7.2 label is preserved with explanation. Other bundled-component completeness remains under VENDOR-06. No permission for unrelated fonts/media is inferred. CSS/HTML/JSON worker source proof now binds seven service packages to nine original license/third-party notice files, two embedded formatter headers and attribution. JSON glob BSD conditions and actual formatter author years are retained; all 81 site notices pass HTTP byte checks. Mode/core/basic-language and remaining embedded-source completeness stay open.",
+ "licenseStatus": "Full Monaco root notices and Codicons historical notices are delivered. The actual TypeScript 4.4.4 worker is exactly reproduced and has a complete original LICENSE/CopyrightNotice/ThirdPartyNoticeText supplement plus attribution; the original stale 2.7.2 label is preserved with explanation. Other bundled-component completeness remains under VENDOR-06. No permission for unrelated fonts/media is inferred. CSS/HTML/JSON worker source proof now binds seven service packages to nine original license/third-party notice files, two embedded formatter headers and attribution. JSON glob BSD conditions and actual formatter author years are retained; all 81 site notices pass HTTP byte checks. Mode/core/basic-language and remaining embedded-source completeness stay open. All four language mode bundles are now exactly reproduced and the two shared npm dependencies are bound to those mode assets as well as workers. Core/basic-language and remaining upstream-origin review stay open.",
"upstreamSources": [
"https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.30.1.tgz",
"https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.26.tgz"
diff --git a/scripts/site-vendor/manifest.json b/scripts/site-vendor/manifest.json
index be4976978..305277428 100644
--- a/scripts/site-vendor/manifest.json
+++ b/scripts/site-vendor/manifest.json
@@ -1037,7 +1037,8 @@
"version": "3.0.0",
"tarball": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"assets": [
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/jsonc-parser/LICENSE.md",
@@ -1103,7 +1104,10 @@
"assets": [
"docs/assets/js/vs/language/css/cssWorker.js",
"docs/assets/js/vs/language/html/htmlWorker.js",
- "docs/assets/js/vs/language/json/jsonWorker.js"
+ "docs/assets/js/vs/language/json/jsonWorker.js",
+ "docs/assets/js/vs/language/css/cssMode.js",
+ "docs/assets/js/vs/language/html/htmlMode.js",
+ "docs/assets/js/vs/language/json/jsonMode.js"
],
"notices": [
"docs/licenses/monaco-editor/language-services/vscode-languageserver-types/License.txt",
diff --git a/scripts/site-vendor/monaco/README.md b/scripts/site-vendor/monaco/README.md
index fe1bddb99..4d9ba55b9 100644
--- a/scripts/site-vendor/monaco/README.md
+++ b/scripts/site-vendor/monaco/README.md
@@ -80,6 +80,35 @@ disposes both workers and models. Monaco 0.30.1 has no public CSS/HTML/JSON work
getter equivalent to `getTypeScriptWorker`. Tests exercise valid/invalid CSS and
JSON, HTML tag completion, document symbols, and HTML/JSON formatting on three engines.
+## Mode registration bundles
+
+`reproduce-modes.ts` covers cssMode, htmlMode, jsonMode and tsMode. The fixed record
+has six archives, 23 Git files, 14 Monaco sources, six npm source modules and two
+package aliases. All 26 module instances and intervening helper bytes match the
+development bundles; their four complete minified outputs match existing assets.
+`jsonc-parser` and `vscode-languageserver-types` notice bindings include these mode
+assets as well as workers. No runtime or notice text is rewritten.
+
+`compiler.ts` shares pinned TypeScript emission with the worker reproducer.
+JSON tokenization needs the original jsonc-parser 3.0.0 main.d.ts to inline const
+enums. The compiler host resolves only explicitly supplied declarations, avoiding
+accidental resolution against current root dependencies. Module names may contain
+a dot (`lib.index`); traversal segments remain rejected. TypeScript mode compilation
+uses the fixed strict config. Exact emission is not a complete upstream typecheck.
+
+```sh
+yarn verify:monaco-mode-sources --fetch
+yarn verify:monaco-mode-sources
+yarn verify:monaco-language-sources
+yarn test:browser test/browser/editor-modes.spec.js --workers=1
+```
+
+`editor-modes.spec.js` uses a real editor, automatic mode loading/provider registration
+and model switching. CSS/JSON/TypeScript errors appear and clear after correction;
+the editor's document-format action formats JSON/HTML while preserving content.
+All four mode URLs must return 200; disposed models must lose their diagnostics.
+This complements direct worker methods and the typed player test.
+
## Language-service notices
`monaco-language-notices.json` binds seven verified package versions to their nine
@@ -99,7 +128,7 @@ ranges. Preserve raw bytes and the `-text` Git attributes for frozen/output noti
12 relative links, alongside mobile player playback and console cleanup.
This does not close all Monaco embedded-source review. Core embedded libraries,
-mode bundles, language definitions and remaining upstream data/origin details stay
+language definitions and remaining upstream data/origin details stay
under VENDOR-06. Revalidate editor-types and site-vendor tests when changing
declarations or delivered notices. Whole-site, physical-device and remote release
gates remain separate.
diff --git a/scripts/site-vendor/monaco/compiler.ts b/scripts/site-vendor/monaco/compiler.ts
new file mode 100644
index 000000000..cc7c48fb9
--- /dev/null
+++ b/scripts/site-vendor/monaco/compiler.ts
@@ -0,0 +1,34 @@
+import assert from 'node:assert/strict'
+
+export interface CompilerModule { name: string, source: string }
+
+// Reproduce emission with pinned standard libraries and optional verified module
+// declarations. This is intentionally not a full upstream semantic typecheck.
+export function emitAmd(ts: typeof import('typescript'), source: string, libraries: string[], strict = false, modules: CompilerModule[] = []): string {
+ const options: import('typescript').CompilerOptions = {
+ target: ts.ScriptTarget.ES5,
+ module: ts.ModuleKind.AMD,
+ newLine: ts.NewLineKind.LineFeed,
+ noResolve: modules.length === 0,
+ lib: libraries.map(library => `lib.${library}.d.ts`),
+ strict,
+ }
+ const host = ts.createCompilerHost(options)
+ const getSourceFile = host.getSourceFile.bind(host)
+ const inputs = new Map([['worker.ts', source], ...modules.map((module, index): [string, string] => [`pinned-${index}.d.ts`, module.source])])
+ host.getSourceFile = (file, languageVersion, onError, createNew) => inputs.has(file)
+ ? ts.createSourceFile(file, inputs.get(file)!, languageVersion, true)
+ : getSourceFile(file, languageVersion, onError, createNew)
+ host.resolveModuleNames = names => names.map((name) => {
+ const index = modules.findIndex(module => module.name === name)
+ return index < 0 ? undefined : { resolvedFileName: `pinned-${index}.d.ts`, extension: ts.Extension.Dts }
+ })
+ let output = ''
+ host.writeFile = (file, text) => {
+ assert(file.endsWith('.js') && !output, 'Unexpected compiler output')
+ output = text
+ }
+ const result = ts.createProgram(['worker.ts'], options, host).emit()
+ assert(!result.emitSkipped && output, 'Missing source emission')
+ return output
+}
diff --git a/scripts/site-vendor/monaco/languages.ts b/scripts/site-vendor/monaco/languages.ts
index 1e2d0c54f..32d0d15b3 100644
--- a/scripts/site-vendor/monaco/languages.ts
+++ b/scripts/site-vendor/monaco/languages.ts
@@ -25,7 +25,7 @@ export function moduleIds(source: string): string[] {
// RequireJS names one anonymous AMD definition and removes newline-ended maps.
// Locate the call syntactically so comments/strings containing define( are inert.
export function nameModule(source: string, id: string): string {
- assert(/^[\w/-]+$/.test(id), 'Unexpected AMD identifier')
+ assert(/^[\w./-]+$/.test(id) && id.split('/').every(part => part !== '.' && part !== '..'), 'Unexpected AMD identifier')
const calls = definitions(source)
assert.equal(calls.length, 1, 'Expected one anonymous AMD definition')
const call = calls[0]!
@@ -70,7 +70,7 @@ export function verifyWorkerSources(worker: string, ids: string[], fragments: {
}
export function languageHeader(language: string): string {
- assert(['css', 'html', 'json'].includes(language), 'Unexpected Monaco language')
+ assert(['css', 'html', 'json', 'typescript'].includes(language), 'Unexpected Monaco language')
return `/*!-----------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* monaco-${language} version: 0.30.1(5a7ba61be909ae9e4889768a3453ebb0dec392e2)
diff --git a/scripts/site-vendor/monaco/notices.ts b/scripts/site-vendor/monaco/notices.ts
index 2998ae2c5..1e3e42631 100644
--- a/scripts/site-vendor/monaco/notices.ts
+++ b/scripts/site-vendor/monaco/notices.ts
@@ -29,6 +29,7 @@ function readNotices(root: string): NoticeRecord {
export function verifyMonacoLanguageNotices(root: string, manifest: VendorManifest): number {
const record = readNotices(root)
const sources: Sources = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-languages-provenance.json'), 'utf8'))
+ const modes: { files: Sources['workers'] } = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-modes-provenance.json'), 'utf8'))
assert.equal(record.notices.length, 12, 'Missing Monaco language notice source')
assert.equal(record.components.length, 9, 'Missing Monaco language component source')
assert.deepEqual(record.packages.map(item => item.name).sort(), [...new Set(sources.modules.map(item => item.id.split('/')[0]))].sort(), 'Incomplete Monaco service attribution')
@@ -38,7 +39,7 @@ export function verifyMonacoLanguageNotices(root: string, manifest: VendorManife
const archive = sources.archives.find(item => `${item.name}-${item.version}` === pkg.archive)
assert(archive && archive.name === pkg.name && archive.version === pkg.version && archive.tarball === pkg.tarball, 'Wrong Monaco service source identity')
const modules = sources.modules.filter(item => item.archive === pkg.archive).map(item => item.id)
- const assets = sources.workers.filter(worker => worker.ids.some(id => modules.includes(id))).map(worker => worker.target.path)
+ const assets = [...sources.workers, ...modes.files].filter(worker => worker.ids.some(id => modules.includes(id))).map(worker => worker.target.path)
assert.deepEqual(pkg.assets, assets, 'Wrong Monaco service asset binding')
}
for (const expected of record.components) {
diff --git a/scripts/site-vendor/monaco/reproduce-languages.ts b/scripts/site-vendor/monaco/reproduce-languages.ts
index 78b037cfb..cf684ffcb 100644
--- a/scripts/site-vendor/monaco/reproduce-languages.ts
+++ b/scripts/site-vendor/monaco/reproduce-languages.ts
@@ -6,6 +6,7 @@ import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { ArchiveCache, hash } from './archives.ts'
+import { emitAmd } from './compiler.ts'
import { aliasModule, languageHeader, nameModule, verifyWorkerSources } from './languages.ts'
import { verifyMonacoLanguageNoticeArchives } from './notices.ts'
@@ -65,32 +66,7 @@ assert.equal(require('terser/package.json').version, '5.9.0', 'Wrong Terser comp
assert.equal(require('source-map/package.json').version, '0.7.3', 'Wrong minifier dependency')
-function compile(source: string): string {
- // Emit with the real pinned standard libraries. Isolated transpileModule loses
- // Promise type resolution and emits a different async helper argument here.
- // Unresolved service imports are intentionally not a full upstream typecheck.
- const options: import('typescript').CompilerOptions = {
- target: ts.ScriptTarget.ES5,
- module: ts.ModuleKind.AMD,
- newLine: ts.NewLineKind.LineFeed,
- noResolve: true,
- lib: ['lib.es5.d.ts', 'lib.dom.d.ts', 'lib.es2015.collection.d.ts', 'lib.es2015.promise.d.ts', 'lib.es2015.iterable.d.ts'],
- }
- const host = ts.createCompilerHost(options)
- const getSourceFile = host.getSourceFile.bind(host)
- host.getSourceFile = (file, languageVersion, onError, createNew) => file === 'worker.ts'
- ? ts.createSourceFile(file, source, languageVersion, true)
- : getSourceFile(file, languageVersion, onError, createNew)
- let output = ''
- host.writeFile = (file, text) => {
- assert(file.endsWith('.js') && !output, 'Unexpected compiler output')
- output = text
- }
- const program = ts.createProgram(['worker.ts'], options, host)
- const result = program.emit()
- assert(!result.emitSkipped && output, 'Missing language source emission')
- return output
-}
+const compile = (source: string) => emitAmd(ts, source, ['es5', 'dom', 'es2015.collection', 'es2015.promise', 'es2015.iterable'])
const modules = new Map(record.modules.map(member => [member.id, nameModule(cache.member(member).toString('utf8'), member.id)]))
const aliases = new Map(record.aliases.map(alias => [alias.id, aliasModule(alias.id, alias.main)]))
const results = []
diff --git a/scripts/site-vendor/monaco/reproduce-modes.ts b/scripts/site-vendor/monaco/reproduce-modes.ts
new file mode 100644
index 000000000..13fc471aa
--- /dev/null
+++ b/scripts/site-vendor/monaco/reproduce-modes.ts
@@ -0,0 +1,81 @@
+import type { Archive, Member, Remote } from './archives.ts'
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import { createRequire } from 'node:module'
+import path from 'node:path'
+import process from 'node:process'
+import { fileURLToPath } from 'node:url'
+import { ArchiveCache, hash } from './archives.ts'
+import { emitAmd } from './compiler.ts'
+import { aliasModule, languageHeader, nameModule, verifyWorkerSources } from './languages.ts'
+
+interface Provenance {
+ archives: Archive[]
+ remotes: Remote[]
+ compilerMembers: Member[]
+ declaration: Member
+ npmModules: (Member & { id: string })[]
+ aliases: { id: string, main: string }[]
+ files: {
+ language: string
+ development: Member
+ target: { path: string, sha256: string }
+ ids: string[]
+ modules: { id: string, source: string, resolveJsonc: boolean }[]
+ config: string
+ }[]
+}
+const root = fileURLToPath(new URL('../../../', import.meta.url))
+assert(process.argv.slice(2).every(arg => arg === '--fetch'), 'Use reproduce-modes.ts [--fetch]')
+assert.equal(process.version, `v${fs.readFileSync(path.join(root, '.node-version'), 'utf8').trim()}`, 'Use canonical Node')
+const record: Provenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-modes-provenance.json'), 'utf8'))
+assert.deepEqual(record.files.map(file => file.language), ['css', 'html', 'json', 'typescript'], 'Missing mode bundle')
+assert.equal(record.files.flatMap(file => file.modules).length, 14, 'Missing Monaco mode source')
+assert.equal(record.npmModules.length, 6, 'Missing mode dependency source')
+const cache = new ArchiveCache(root, path.join(root, 'refactor/.cache/monaco-review'))
+await cache.verify(record.archives, record.remotes, process.argv.includes('--fetch'))
+for (const name of ['typescript', 'terser', 'source-map']) {
+ const archive = record.archives.find(item => item.name === name)
+ assert(archive, 'Missing historical compiler dependency')
+ cache.extractCompiler(archive)
+}
+for (const member of record.compilerMembers)
+ cache.member(member)
+const require = createRequire(path.join(cache.directory, 'compiler/entry.cjs'))
+const ts = require('typescript') as typeof import('typescript')
+
+const terser = require('terser') as { minify: (source: string, options: { output: { comments: string } }) => Promise<{ code: string }> }
+
+assert.equal(ts.version, '4.4.4')
+assert.equal(require('terser/package.json').version, '5.9.0')
+
+assert.equal(require('source-map/package.json').version, '0.7.3')
+
+const jsonc = cache.member(record.declaration).toString('utf8')
+const modules = new Map(record.npmModules.map(member => [member.id, nameModule(cache.member(member).toString('utf8'), member.id)]))
+const aliases = new Map(record.aliases.map(alias => [alias.id, aliasModule(alias.id, alias.main)]))
+const results = []
+for (const file of record.files) {
+ assert(record.remotes.some(remote => remote.source === file.config), 'Unverified mode compiler config')
+ const config: { compilerOptions: { module: string, target: string, lib: string[], strict?: boolean } } = JSON.parse(fs.readFileSync(path.join(root, file.config), 'utf8'))
+ assert.equal(config.compilerOptions.module, 'amd')
+ assert.equal(config.compilerOptions.target, 'es5')
+ const local = new Map(file.modules.map((module) => {
+ assert(record.remotes.some(remote => remote.source === module.source), 'Unverified mode source')
+ const source = fs.readFileSync(path.join(root, module.source), 'utf8')
+ const compiled = emitAmd(ts, source, config.compilerOptions.lib, config.compilerOptions.strict, module.resolveJsonc ? [{ name: 'jsonc-parser', source: jsonc }] : [])
+ return [module.id, nameModule(compiled, module.id)]
+ }))
+ const development = cache.member(file.development).toString('utf8')
+ verifyWorkerSources(development, file.ids, file.ids.map((id) => {
+ const source = local.get(id) ?? modules.get(id) ?? aliases.get(id)
+ assert(source, `Missing mode source: ${id}`)
+ return { id, source }
+ }))
+ const target = fs.readFileSync(path.join(root, file.target.path))
+ assert.equal(hash(target), file.target.sha256, 'Shipped Monaco mode changed')
+ const { code } = await terser.minify(development, { output: { comments: 'some' } })
+ assert.equal(languageHeader(file.language) + code, target.toString('utf8'), 'Minified mode bundle differs')
+ results.push({ language: file.language, modules: file.ids.length, exactSources: true, exactOutput: true, sha256: hash(target) })
+}
+console.log(JSON.stringify({ archives: record.archives.length, gitSources: record.remotes.length, ownModules: 14, npmModules: modules.size, aliases: aliases.size, modes: results, coreAndBasicLanguagesReviewed: false }))
diff --git a/test/browser/README.md b/test/browser/README.md
index 2de6116fd..7f8157f32 100644
--- a/test/browser/README.md
+++ b/test/browser/README.md
@@ -1,5 +1,11 @@
# Browser regression entry
+`editor-modes.spec.js` exercises Monaco's actual automatic mode/provider registration
+through a real editor. It switches CSS/JSON/TypeScript/HTML models, checks diagnostic
+arrival/removal and document formatting, verifies all four mode bundle responses,
+and checks model disposal clears markers. It complements direct worker tests;
+neither suite alone proves all editor UI, physical-device or player integration paths.
+
`editor-languages.spec.js` loads the frozen Monaco 0.30.1 CSS/HTML/JSON workers,
checks real Worker creation, positive/negative diagnostics, tag completion, document
symbols and formatting, and disposes models/workers. It uses `createWebWorker` with
diff --git a/test/browser/editor-modes.spec.js b/test/browser/editor-modes.spec.js
new file mode 100644
index 000000000..fed4086f8
--- /dev/null
+++ b/test/browser/editor-modes.spec.js
@@ -0,0 +1,72 @@
+import { expect, test } from './fixtures.js'
+
+test('docs Monaco mode registrations update editor diagnostics and formatting across languages', async ({ page }, testInfo) => {
+ const loadedModes = []
+ page.on('response', (response) => {
+ if (/\/language\/(?:css|html|json|typescript)\/\w+Mode\.js$/.test(response.url()))
+ loadedModes.push({ url: response.url(), status: response.status() })
+ })
+ await page.goto('/test/player.html?core=candidate&chapter=published')
+ await page.addScriptTag({ url: '/assets/js/vs/loader.js' })
+ await page.evaluate(async () => {
+ window.require.config({ paths: { vs: '/assets/js/vs' } })
+ await new Promise((resolve, reject) => window.require(['vs/editor/editor.main'], resolve, reject))
+ const host = document.createElement('div')
+ host.style.cssText = 'width:800px;height:400px'
+ document.body.appendChild(host)
+ const editor = window.monaco.editor.create(host, { model: null, minimap: { enabled: false } })
+ window.modeProbe = { editor, host, models: [] }
+ })
+ const evidence = []
+ try {
+ for (const phase of [
+ { language: 'css', invalid: 'a { color: ; }', valid: 'a { color: red; }' },
+ { language: 'json', invalid: '{"value":}', valid: '{"value":1}' },
+ { language: 'typescript', invalid: 'const value: number = "wrong";', valid: 'const value: number = 1;' },
+ ]) {
+ await page.evaluate((phase) => {
+ const api = window.monaco
+ const model = api.editor.createModel(phase.invalid, phase.language, api.Uri.parse(`file:///mode-probe-${phase.language}`))
+ model.updateOptions({ tabSize: 2, insertSpaces: true })
+ window.modeProbe.models.push(model)
+ window.modeProbe.editor.setModel(model)
+ }, phase)
+ await expect.poll(() => page.evaluate(() => window.monaco.editor.getModelMarkers({ resource: window.modeProbe.editor.getModel().uri }).filter(marker => marker.severity === window.monaco.MarkerSeverity.Error).length)).toBeGreaterThan(0)
+ evidence.push(await page.evaluate(() => ({ language: window.modeProbe.editor.getModel().getLanguageId(), markers: window.monaco.editor.getModelMarkers({ resource: window.modeProbe.editor.getModel().uri }) })))
+ await page.evaluate(value => window.modeProbe.editor.getModel().setValue(value), phase.valid)
+ await expect.poll(() => page.evaluate(() => window.monaco.editor.getModelMarkers({ resource: window.modeProbe.editor.getModel().uri }).length)).toBe(0)
+ if (phase.language === 'json') {
+ await expect.poll(() => page.evaluate(() => window.modeProbe.editor.getAction('editor.action.formatDocument').isSupported())).toBe(true)
+ await page.evaluate(() => window.modeProbe.editor.getAction('editor.action.formatDocument').run())
+ const formatted = await page.evaluate(() => window.modeProbe.editor.getValue())
+ expect(formatted).toContain('\n')
+ expect(JSON.parse(formatted)).toEqual({ value: 1 })
+ evidence.push({ language: 'json', formatted })
+ }
+ }
+ await page.evaluate(() => {
+ const api = window.monaco
+ const model = api.editor.createModel('', 'html', api.Uri.parse('file:///mode-probe-html'))
+ model.updateOptions({ tabSize: 2, insertSpaces: true })
+ window.modeProbe.models.push(model)
+ window.modeProbe.editor.setModel(model)
+ })
+ await expect.poll(() => page.evaluate(() => window.modeProbe.editor.getAction('editor.action.formatDocument').isSupported())).toBe(true)
+ await page.evaluate(() => window.modeProbe.editor.getAction('editor.action.formatDocument').run())
+ const formatted = await page.evaluate(() => window.modeProbe.editor.getValue())
+ expect(formatted).toContain('\n')
+ expect(formatted.replace(/\s+/g, '')).toBe('')
+ evidence.push({ language: 'html', formatted })
+ expect(loadedModes.map(item => item.url.split('/').pop()).sort()).toEqual(['cssMode.js', 'htmlMode.js', 'jsonMode.js', 'tsMode.js'])
+ expect(loadedModes.every(item => item.status === 200)).toBe(true)
+ await testInfo.attach('monaco-mode-results', { contentType: 'application/json', body: JSON.stringify({ evidence, loadedModes }, null, 2) })
+ }
+ finally {
+ await page.evaluate(() => {
+ window.modeProbe.editor.dispose()
+ window.modeProbe.models.forEach(model => model.dispose())
+ window.modeProbe.host.remove()
+ })
+ }
+ await expect.poll(() => page.evaluate(() => window.modeProbe.models.flatMap(model => window.monaco.editor.getModelMarkers({ resource: model.uri })).length)).toBe(0)
+})
diff --git a/test/monaco-provenance.test.js b/test/monaco-provenance.test.js
index b42f759b7..eca365a6b 100644
--- a/test/monaco-provenance.test.js
+++ b/test/monaco-provenance.test.js
@@ -1,6 +1,8 @@
import assert from 'node:assert/strict'
// eslint-disable-next-line test/no-import-node-test -- Verify fixed source transforms without executing archived runtime.
import test from 'node:test'
+import ts from 'typescript'
+import { emitAmd } from '../scripts/site-vendor/monaco/compiler.ts'
import { aliasModule, moduleIds, nameModule, verifyWorkerSources } from '../scripts/site-vendor/monaco/languages.ts'
import { browserTypeScript, verifyTypeScriptSource } from '../scripts/site-vendor/monaco/typescript.ts'
@@ -46,6 +48,8 @@ test('Monaco AMD naming ignores strings and preserves source bodies', () => {
assert(named.includes('define(\'library/main\',["exports"]'))
assert(!named.includes('sourceMappingURL'))
assert.deepEqual(moduleIds(named), ['library/main'])
+ assert.deepEqual(moduleIds(nameModule(anonymous, 'library/lib.index')), ['library/lib.index'])
+ assert.throws(() => nameModule(anonymous, '../library'), /identifier/)
assert(nameModule(anonymous.trimEnd(), 'library/main').endsWith('//# sourceMappingURL=source.js.map;'))
assert.throws(() => nameModule(named, 'library/main'), /anonymous AMD dependency array/)
assert.throws(() => nameModule(anonymous + anonymous, 'library/main'), /one anonymous/)
@@ -53,6 +57,17 @@ test('Monaco AMD naming ignores strings and preserves source bodies', () => {
assert.throws(() => nameModule(`${anonymous}//# sourceMappingURL=second.map\n`, 'library/main'), /Duplicate source map/)
})
+test('Monaco mode emission resolves const enums only from explicit declaration inputs', () => {
+ const source = 'import { ScanError } from "pinned-json"; export const code = ScanError.End;'
+ const declarations = [{ name: 'pinned-json', source: 'export declare const enum ScanError { End = 2 }' }]
+ const compiled = emitAmd(ts, source, ['es5'], true, declarations)
+ assert.match(compiled, /exports.code = 2/)
+ const wrong = emitAmd(ts, source, ['es5'], true, [{ ...declarations[0], source: declarations[0].source.replace('2', '3') }])
+ const fragment = nameModule(compiled, 'mode')
+ assert.throws(() => verifyWorkerSources(nameModule(wrong, 'mode'), ['mode'], [{ id: 'mode', source: fragment }]), /Source differs/)
+ assert(!emitAmd(ts, source, ['es5'], true).includes('exports.code = 2'))
+})
+
test('Monaco worker proof covers helper code, aliases and all module boundaries', () => {
const id = 'library/main'
const source = nameModule('const helper = 1;\ndefine(["exports"], function (exports) { exports.value = helper; });', id)