From 166e63b991edd91c9aabdc34e54cd1413cf83114 Mon Sep 17 00:00:00 2001 From: Orta Date: Mon, 31 Aug 2020 13:09:47 -0400 Subject: [PATCH] Adds a vfs project --- package-lock.json | 24 ++++++++++++++++++ package.json | 1 + src/tsWorker.ts | 5 ++-- test/custom-worker.html | 53 +++++++++++++++++++++----------------- test/custom-worker.js | 56 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 113 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 080cf8f..d4e5588 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,15 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@typescript/vfs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.2.0.tgz", + "integrity": "sha512-3YhBC+iyngEHjEedSAWk9rbJHoBwa2cd4h/tzb2TXmZc2CUclTl3x5AQRKNoRqm7t+X9PGTc2q2/Dpray/O4mA==", + "dev": true, + "requires": { + "debug": "^4.1.1" + } + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -16,6 +25,15 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, "monaco-editor-core": { "version": "0.20.0", "resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.20.0.tgz", @@ -45,6 +63,12 @@ } } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "requirejs": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", diff --git a/package.json b/package.json index 73e7dcf..d2eb199 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "url": "https://github.com/Microsoft/monaco-typescript/issues" }, "devDependencies": { + "@typescript/vfs": "^1.2.0", "monaco-editor-core": "^0.20.0", "monaco-languages": "^1.10.0", "monaco-plugin-helpers": "^1.0.2", diff --git a/src/tsWorker.ts b/src/tsWorker.ts index fd3689a..f4079ae 100644 --- a/src/tsWorker.ts +++ b/src/tsWorker.ts @@ -10,6 +10,7 @@ import { IExtraLibs } from './monaco.contribution'; import IWorkerContext = monaco.worker.IWorkerContext; + export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.languages.typescript.TypeScriptWorker { // --- model sync ----------------------- @@ -36,7 +37,7 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language return models.concat(Object.keys(this._extraLibs)); } - private _getModel(fileName: string): monaco.worker.IMirrorModel | null { + _getModel(fileName: string): monaco.worker.IMirrorModel | null { let models = this._ctx.getMirrorModels(); for (let i = 0; i < models.length; i++) { if (models[i].uri.toString() === fileName) { @@ -271,7 +272,7 @@ export function create(ctx: IWorkerContext, createData: ICreateData): TypeScript throw new Error(`The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self`) } // @ts-ignore - The throw validates this - TSWorkerClass = self.customTSWorkerFactory(TypeScriptWorker) + TSWorkerClass = self.customTSWorkerFactory(TypeScriptWorker, ts, libFileMap) } } diff --git a/test/custom-worker.html b/test/custom-worker.html index ba58de9..74bfdbb 100644 --- a/test/custom-worker.html +++ b/test/custom-worker.html @@ -20,6 +20,7 @@

Monaco Editor TypeScript test page

Custom webworker

+ diff --git a/test/custom-worker.js b/test/custom-worker.js index 498b567..ccc7e0f 100644 --- a/test/custom-worker.js +++ b/test/custom-worker.js @@ -1,4 +1,19 @@ -self.customTSWorkerFactory = (TypeScriptWorker) => { +// This example uses @typescript/vfs to create a virtual TS program +// which can do work on a bg thread. + +importScripts("https://unpkg.com/@typescript/vfs@1.3.0/dist/vfs.globals.js") + +/** + * + * @param {import("../src/tsWorker").TypeScriptWorker} TypeScriptWorker + * @param {import("typescript")} ts + * @param {Record} libFileMap + * + */ +const worker = (TypeScriptWorker, ts, libFileMap) => { + /** @type { import("@typescript/vfs") } */ + const tsvfs = globalThis.tsvfs + return class MonacoTSWorker extends TypeScriptWorker { // Adds a custom function to the webworker @@ -8,5 +23,44 @@ self.customTSWorkerFactory = (TypeScriptWorker) => { return (firstDTS && firstDTS.text) || "" } + async printAST(fileName) { + console.log("Creating virtual TS project") + const compilerOptions = this.getCompilationSettings() + const fsMap = new Map() + for (const key of Object.keys(libFileMap)) { + fsMap.set(key, "/" + libFileMap[key]) + } + + const thisCode = await this.getScriptText(fileName) + fsMap.set("index.ts", thisCode) + + console.log("Starting up TS program") + const system = tsvfs.createSystem(fsMap) + const host = tsvfs.createVirtualCompilerHost(system, compilerOptions, ts) + + const program = ts.createProgram({ + rootNames: [...fsMap.keys()], + options: compilerOptions, + host: host.compilerHost, + }) + + // Now I can look at the AST for the .ts file too + const mainSrcFile = program.getSourceFile("index.ts") + let miniAST = "SourceFile" + + const recurse = (parent, depth) => { + if (depth > 5) return + ts.forEachChild(parent, node => { + const spaces = " ".repeat(depth + 1) + miniAST += `\n${spaces}${ts.SyntaxKind[node.kind]}` + recurse(node, depth + 1) + }) + } + recurse(mainSrcFile, 0) + return miniAST + } + } } + +self.customTSWorkerFactory = worker