Pārlūkot izejas kodu

Merge pull request #7004 from sailro/monaco

Use the Monaco TS Language service for the Playground
David Catuhe 5 gadi atpakaļ
vecāks
revīzija
e26b356adb

+ 2 - 2
Playground/js/main.js

@@ -40,7 +40,7 @@ compileAndRun = function(parent, fpsLabel) {
         var createEngineFunction = "createDefaultEngine";
         var createSceneFunction;
 
-        parent.monacoCreator.getRunCode(function (code) {
+        parent.monacoCreator.getRunCode().then(code => {
             var createDefaultEngine = function () {
                 return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
             }
@@ -172,7 +172,7 @@ compileAndRun = function(parent, fpsLabel) {
                     }
                 }
             }
-        }.bind(this));
+        });
 
     } catch (e) {
         parent.utils.showError(e.message, e);

+ 2 - 2
Playground/js/mainWebGPU.js

@@ -45,7 +45,7 @@ compileAndRun = function(parent, fpsLabel) {
             return;
         }
 
-        parent.monacoCreator.getRunCode((async function (code) {
+        parent.monacoCreator.getRunCode().then(async code => {
             try {
                 var createDefaultEngine = function () {
                     return new BABYLON.WebGPUEngine(canvas);
@@ -196,7 +196,7 @@ compileAndRun = function(parent, fpsLabel) {
                 // Also log error in console to help debug playgrounds
                 console.error(e);
             }
-        }).bind(this));
+        });
     } catch (e) {
         parent.utils.showError(e.message, e);
         // Also log error in console to help debug playgrounds

+ 47 - 68
Playground/js/monacoCreator.js

@@ -58,10 +58,26 @@ class MonacoCreator {
                 if (xhr.status === 200) {
                     require.config({ paths: { 'vs': 'node_modules/monaco-editor/min/vs' } });
                     require(['vs/editor/editor.main'], function () {
+                        const typescript = monaco.languages.typescript;
+
                         if (this.monacoMode === "javascript") {
-                            monaco.languages.typescript.javascriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
+                            typescript.javascriptDefaults.setCompilerOptions({
+                                noLib: true,
+                                allowNonTsExtensions: true // required to prevent Uncaught Error: Could not find file: 'inmemory://model/1'.
+                            });
+
+                            typescript.javascriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
                         } else {
-                            monaco.languages.typescript.typescriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
+                            typescript.typescriptDefaults.setCompilerOptions({
+                                module: typescript.ModuleKind.AMD,
+                                target: typescript.ScriptTarget.ES5,
+                                noLib: true,
+                                noResolve: true,
+                                suppressOutputPathCheck: true,
+
+                                allowNonTsExtensions: true // required to prevent Uncaught Error: Could not find file: 'inmemory://model/1'.
+                            });
+                            typescript.typescriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
                         }
 
                         this.parent.main.run();
@@ -133,75 +149,38 @@ class MonacoCreator {
 
     /**
      * Get the code in the editor
-     * @param {Function} callBack : Function that will be called after retrieving the code.
      */
-    getRunCode(callBack) {
-        if (this.parent.settingsPG.ScriptLanguage == "JS")
-            callBack(this.jsEditor.getValue());
-        else if (this.parent.settingsPG.ScriptLanguage == "TS") {
-            this.triggerCompile(this.JsEditor.getValue(), function (result) {
-                callBack(result + "var createScene = function() { return Playground.CreateScene(engine, engine.getRenderingCanvas()); }")
+    async getRunCode() {
+        var parent = this.parent;
+
+        if (parent.settingsPG.ScriptLanguage == "JS")
+            return this.jsEditor.getValue();
+
+        else if (parent.settingsPG.ScriptLanguage == "TS") {
+            const model = this.jsEditor.getModel();
+            const uri = model.uri;
+
+            const worker = await monaco.languages.typescript.getTypeScriptWorker();
+            const languageService = await worker(uri);
+
+            const uriStr = uri.toString();
+            const result = await languageService.getEmitOutput(uriStr);
+            const diagnostics = await Promise.all([languageService.getSyntacticDiagnostics(uriStr), languageService.getSemanticDiagnostics(uriStr)]);
+
+            diagnostics.forEach(function(diagset) {
+                if (diagset.length) {
+                    var diagnostic = diagset[0];
+                    var position = model.getPositionAt(diagnostic.start);
+                    
+                    parent.utils.showError(`Line ${position.lineNumber}:${position.column} - ${diagnostic.messageText}`);
+                    return;
+                }
             });
-        }
-    };
 
-    /**
-     * Usefull function for TypeScript code
-     * @param {*} codeValue 
-     * @param {*} callback 
-     */
-    triggerCompile(codeValue, callback) {
-        if (this.compilerTriggerTimeoutID !== null) {
-            window.clearTimeout(this.compilerTriggerTimeoutID);
+            const output = result.outputFiles[0].text;
+            const stub = "var createScene = function() { return Playground.CreateScene(engine, engine.getRenderingCanvas()); }";
+
+            return output + stub;
         }
-        this.compilerTriggerTimeoutID = window.setTimeout(function () {
-            try {
-
-                var output = this.transpileModule(codeValue, {
-                    module: ts.ModuleKind.AMD,
-                    target: ts.ScriptTarget.ES5,
-                    noLib: true,
-                    noResolve: true,
-                    suppressOutputPathCheck: true
-                });
-                if (typeof output === "string") {
-                    callback(output);
-                }
-            }
-            catch (e) {
-                this.parent.utils.showError(e.message, e);
-            }
-        }.bind(this), 100);
     };
-    
-    /**
-     * Usefull function for TypeScript code
-     * @param {*} input 
-     * @param {*} options 
-     */
-    transpileModule(input, options) {
-        var inputFileName = options.jsx ? "module.tsx" : "module.ts";
-        var sourceFile = ts.createSourceFile(inputFileName, input, options.target || ts.ScriptTarget.ES5);
-        // Output
-        var outputText;
-        var program = ts.createProgram([inputFileName], options, {
-            getSourceFile: function (fileName) { return fileName.indexOf("module") === 0 ? sourceFile : undefined; },
-            writeFile: function (_name, text) { outputText = text; },
-            getDefaultLibFileName: function () { return "lib.d.ts"; },
-            useCaseSensitiveFileNames: function () { return false; },
-            getCanonicalFileName: function (fileName) { return fileName; },
-            getCurrentDirectory: function () { return ""; },
-            getNewLine: function () { return "\r\n"; },
-            fileExists: function (fileName) { return fileName === inputFileName; },
-            readFile: function () { return ""; },
-            directoryExists: function () { return true; },
-            getDirectories: function () { return []; }
-        });
-        // Emit
-        program.emit();
-        if (outputText === undefined) {
-            throw new Error("Output generation failed");
-        }
-        return outputText;
-    }
 };

+ 1 - 1
Playground/package.json

@@ -9,7 +9,7 @@
   "readme": "https://github.com/BabylonJS/Babylon.js/blob/master/readme.md",
   "license": "(Apache-2.0)",
   "devDependencies": {
-    "monaco-editor": "~0.10.1"
+    "monaco-editor": "~0.18.1"
   },
   "scripts": {
     "test": "browser-sync start --server --files **/* --no-inject-changes --startPath index.html"

+ 1 - 0
dist/preview release/what's new.md

@@ -74,6 +74,7 @@
 - Added support for side by side and top bottom images in the `PhotoDome` ([Deltakosh](https://github.com/deltakosh/))
 - Added playground ts-local (TypeScript support for local playground) ([pjoe](https://github.com/pjoe/))
 - Added RGBD Texture tools [Sebavan](https://github.com/sebavan/)
+- Bumped Monaco Editor to 0.18.1 and improved TypeScript compilation pipeline in the playground ([sailro](http://www.github.com/sailro))
 
 ### Meshes