Skip to content
This repository has been archived by the owner on Nov 5, 2021. It is now read-only.

Commit

Permalink
Adds a vfs project
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed Aug 31, 2020
1 parent 89fdcf5 commit 166e63b
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 26 deletions.
24 changes: 24 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 3 additions & 2 deletions src/tsWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 -----------------------
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
}
}

Expand Down
53 changes: 30 additions & 23 deletions test/custom-worker.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ <h2>Monaco Editor TypeScript test page</h2>
<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
<h3>Custom webworker</h3>
<button id="logDTS">Log DTS</button>
<button id="getAST">Print AST to console</button>

<script>
var paths = {
Expand Down Expand Up @@ -181,35 +182,41 @@ <h3>Custom webworker</h3>
'vs/language/typescript/monaco.contribution'
], () => {

monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: "http://localhost:5000/test/custom-worker.js" })
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ target: 99, jsx: 1, allowNonTsExtensions: true, declaration: true })

var editor = monaco.editor.create(document.getElementById('container'), {
value: localStorage.getItem("code") || getDefaultCode(),
language: 'typescript',
lightbulb: { enabled: true }
});
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: "http://localhost:5000/test/custom-worker.js" })
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ target: 99, jsx: 1, allowNonTsExtensions: true, declaration: true, noLibCheck: true })

var editor = monaco.editor.create(document.getElementById('container'), {
value: localStorage.getItem("code") || getDefaultCode(),
language: 'typescript',
lightbulb: { enabled: true }
});

editor.onDidChangeModelContent(() => {
const code = editor.getModel().getValue()
localStorage.setItem("code", code)
});

editor.onDidChangeModelContent(() => {
const code = editor.getModel().getValue()
localStorage.setItem("code", code)
});
document.getElementById('resetBtn').onclick = () => {
editor.setValue(getDefaultCode());
};

document.getElementById('resetBtn').onclick = () => {
editor.setValue(getDefaultCode());
};
document.getElementById('logDTS').onclick = async () => {
const model = editor.getModel()
const worker = await monaco.languages.typescript.getTypeScriptWorker()
const thisWorker = await worker(model.uri)
const dts = await thisWorker.getDTSEmitForFile(model.uri.toString())
console.log(dts)
};

document.getElementById('logDTS').onclick = async () => {
const model = editor.getModel()
const worker = await monaco.languages.typescript.getTypeScriptWorker()
const thisWorker = await worker(model.uri)
const dts = await thisWorker.getDTSEmitForFile(model.uri.toString())
console.log(dts)
};
document.getElementById('getAST').onclick = async () => {
const model = editor.getModel()
const worker = await monaco.languages.typescript.getTypeScriptWorker()
const thisWorker = await worker(model.uri)
const ast = await thisWorker.printAST(model.uri.toString())
console.log(ast)
};

});
});
</script>
</body>
</html>
56 changes: 55 additions & 1 deletion test/custom-worker.js
Original file line number Diff line number Diff line change
@@ -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<string, string>} 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
Expand All @@ -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

0 comments on commit 166e63b

Please sign in to comment.