Browse Source

- Removed the logic that generates the temporary tsconfig.atomic and instead just pushes the tsconfig directly into the web view
- Show a message when trying to do a full compile and a typescript editor is not open ( temporary fix until a way is found to compile the typescript without an editor open)

Shaddock Heath 9 years ago
parent
commit
d7ff17d7a7

+ 45 - 22
Script/AtomicEditor/hostExtensions/languageExtensions/TypscriptLanguageExtension.ts

@@ -51,10 +51,10 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
     }
 
     /**
-     * Seed the language service with all of the relevant files in the project.  This updates the tsconifg.atomic file in
-     * the root of the resources directory.
+     * Build an in-memory config file to be sent down to the web view client.  This will scan the resources directory
+     * and generate a file list
      */
-    private loadProjectFiles() {
+    private buildTsConfig(): any {
         let projectFiles: Array<string> = [];
 
         //scan all the files in the project for any typescript files so we can determine if this is a typescript project
@@ -78,7 +78,7 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
 
             if (!found) {
                 // Load up the Atomic.d.ts from the tool core
-                console.log("Need to load up hosted Atomic.d.ts!");
+                projectFiles.push(Atomic.addTrailingSlash(Atomic.addTrailingSlash(ToolCore.toolEnvironment.toolDataDir) + "TypeScriptSupport") + "Atomic.d.ts");
             }
 
             let files = projectFiles.map((f: string) => {
@@ -95,14 +95,11 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
                 files: files
             };
 
-            let filename = Atomic.addTrailingSlash(ToolCore.toolSystem.project.resourcePath) + "tsconfig.atomic";
-            let script = new Atomic.File(filename, Atomic.FILE_WRITE);
-            try {
-                script.writeString(JSON.stringify(tsConfig));
-                script.flush();
-            } finally {
-                script.close();
-            }
+            return tsConfig;
+        } else {
+            return {
+                files: []
+            };
         }
     }
 
@@ -124,7 +121,7 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
      */
     delete(ev: Editor.EditorEvents.DeleteResourceEvent) {
         if (this.isValidFiletype(ev.path)) {
-            console.log(`${this.name}: received a delete resource event`);
+            // console.log(`${this.name}: received a delete resource event`);
 
             // Delete the corresponding js file
             let jsFile = ev.path.replace(/\.ts$/, ".js");
@@ -137,10 +134,8 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
                     path: jsFile
                 };
 
+                this.setTsConfigOnWebView(this.buildTsConfig());
                 this.serviceRegistry.sendEvent(EditorEvents.DeleteResourceNotification, eventData);
-
-                // rebuild the tsconfig.atomic
-                this.loadProjectFiles();
             }
         }
     }
@@ -151,7 +146,7 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
      */
     rename(ev: Editor.EditorEvents.RenameResourceEvent) {
         if (this.isValidFiletype(ev.path)) {
-            console.log(`${this.name}: received a rename resource event`);
+            // console.log(`${this.name}: received a rename resource event`);
 
             // Rename the corresponding js file
             let jsFile = ev.path.replace(/\.ts$/, ".js");
@@ -168,10 +163,8 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
                     asset: jsFileAsset
                 };
 
+                this.setTsConfigOnWebView(this.buildTsConfig());
                 this.serviceRegistry.sendEvent(EditorEvents.RenameResourceNotification, eventData);
-
-                // rebuild the tsconfig.atomic
-                this.loadProjectFiles();
             }
         }
     }
@@ -186,7 +179,7 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
         if (!this.isTypescriptProject) {
             if (Atomic.getExtension(ev.path) == ".ts") {
                 this.isTypescriptProject = true;
-                this.loadProjectFiles();
+                this.setTsConfigOnWebView(this.buildTsConfig());
             }
         }
     }
@@ -200,7 +193,7 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
     projectLoaded(ev: Editor.EditorEvents.LoadProjectEvent) {
         // got a load, we need to reset the language service
         console.log(`${this.name}: received a project loaded event for project at ${ev.path}`);
-        this.loadProjectFiles();
+        this.setTsConfigOnWebView(this.buildTsConfig());
         this.rebuildMenu();
     }
 
@@ -260,6 +253,10 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
         }
     }
 
+    setTsConfigOnWebView(tsConfig: any) {
+        WebView.WebBrowserHost.setGlobalStringProperty("TypeScriptLanguageExtension", "tsConfig", JSON.stringify(tsConfig));
+    }
+
     /**
      * Perform a full compile of the TypeScript
      */
@@ -268,7 +265,33 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
         if (editor && editor.typeName == "JSResourceEditor") {
             const jsEditor = <Editor.JSResourceEditor>editor;
             jsEditor.webView.webClient.executeJavaScript(`TypeScript_DoFullCompile();`);
+        } else {
+            this.serviceRegistry.uiServices.showModalError("TypeScript Compilation", "Please open a TypeScript file in the editor before attempting to do a full compile.");
         }
+
+        // Ideally, we would want to either launch up a background web view, or shell out to node or something and not
+        // need to have an editor open.  Still researching this
+        /*
+            const url = `atomic://${ToolCore.toolEnvironment.toolDataDir}CodeEditor/Editor.html`;
+            const webClient = new WebView.WebClient();
+            this.webClient = webClient;
+            //this.webClient.loadURL(url);
+
+            const webTexture = new WebView.WebTexture2D();
+            webClient.webRenderHandler = webTexture;
+
+            // doesn't work because atomicquery doesn't seem to be exposed to WebView.WebClient instances
+            webClient.subscribeToEvent(EditorEvents.WebMessage, (data) => {
+                switch (data.message) {
+                    case "editorLoadComplete":
+                        webClient.unsubscribeFromEvent(EditorEvents.WebMessage);
+                        webClient.executeJavaScript(`TypeScript_DoFullCompile();`);
+                        break;
+                }
+            });
+
+            webClient.createBrowser(url, 1, 1);
+        */
     }
 
     /**

+ 15 - 2
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/TypescriptLanguageExtension.ts

@@ -93,6 +93,14 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
         });
     }
 
+    /**
+     * Grabs the TS Config file attached to the global window object
+     * @return {any}
+     */
+    private getTsConfig():any {
+        return JSON.parse(window["TypeScriptLanguageExtension"]["tsConfig"]);
+    }
+
     /**
      * Called when the editor needs to be configured for a particular file
      * @param  {Editor.EditorEvents.EditorFileEvent} ev
@@ -133,7 +141,12 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
             this.buildWorker();
 
             // post a message to the shared web worker
-            this.worker.port.postMessage({ command: WorkerProcessTypes.Connect, sender: "Typescript Language Extension", filename: ev.filename });
+            this.worker.port.postMessage({
+                command: WorkerProcessTypes.Connect,
+                sender: "Typescript Language Extension",
+                filename: ev.filename,
+                tsConfig: this.getTsConfig()
+            });
         }
     }
 
@@ -166,7 +179,6 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
      * @param  {WorkerProcessTypes.SaveMessageData} event
      */
     saveFile(event: WorkerProcessTypes.SaveMessageData) {
-        console.log("Save File:" + event.filename);
         this.serviceLocator.clientServices.getHostInterop().saveFile(event.filename, event.code);
     }
 
@@ -261,6 +273,7 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
                 filename: ev.filename,
                 fileExt: ev.fileExt,
                 code: ev.code,
+                tsConfig: this.getTsConfig(),
                 editor: null // cannot send editor across the boundary
             };
 

+ 12 - 31
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/workerprocess/TypescriptLanguageServiceWebWorker.ts

@@ -35,30 +35,6 @@ interface TSConfigFile {
     files: Array<string>;
 }
 
-/**
- * Promise version of atomic query
- * @param  {string} message the query to use to pass to atomicQuery.  If there is no payload, this will be passed directly, otherwise it will be passed in a data object
- * @param  {any} payload optional data to send
- * @return {Promise}
- */
-function atomicQueryPromise(message: any): Promise<{}> {
-    return new Promise(function(resolve, reject) {
-        let queryMessage = message;
-
-        // if message is coming in as an object then let's stringify it
-        if (typeof (message) != "string") {
-            queryMessage = JSON.stringify(message);
-        }
-
-        window.atomicQuery({
-            request: queryMessage,
-            persistent: false,
-            onSuccess: resolve,
-            onFailure: (error_code, error_message) => reject({ error_code: error_code, error_message: error_message })
-        });
-    });
-}
-
 /**
  * Queries the host for a particular resource and returns it in a promise
  * @param  {string} codeUrl
@@ -144,7 +120,8 @@ class WebFileSystem implements FileSystemInterface {
             filename: filename,
             code: contents,
             fileExt: fileExt,
-            editor: null
+            editor: null,
+            tsConfig: null
         };
 
         this.communicationPort.postMessage(message);
@@ -181,6 +158,8 @@ export default class TypescriptLanguageServiceWebWorker {
         compileOnSave: false
     };
 
+    tsConfig: TSConfigFile = null;
+
     constructor() {
         this.fs = new WebFileSystem();
         this.languageService = new TypescriptLanguageService(this.fs);
@@ -251,23 +230,22 @@ export default class TypescriptLanguageServiceWebWorker {
         // and delete any that may be been removed and sync up
         return getFileResource("resources/tsconfig.atomic").then((jsonTsConfig: string) => {
             let promises: PromiseLike<void>[] = [];
-            let tsConfig: TSConfigFile = JSON.parse(jsonTsConfig);
 
-            if (tsConfig.compilerOptions) {
-                this.languageService.compilerOptions = tsConfig.compilerOptions;
+            if (this.tsConfig.compilerOptions) {
+                this.languageService.compilerOptions = this.tsConfig.compilerOptions;
             };
 
             let existingFiles = this.languageService.getProjectFiles();
 
             // see if anything was deleted
             existingFiles.forEach((f) => {
-                if (tsConfig.files.indexOf(f) == -1) {
+                if (this.tsConfig.files.indexOf(f) == -1) {
                     this.languageService.deleteProjectFile(f);
                 }
             });
 
             // load up any new files that may have been added
-            tsConfig.files.forEach((f) => {
+            this.tsConfig.files.forEach((f) => {
                 if (existingFiles.indexOf(f) == -1) {
                     promises.push(getFileResource(f).then((code: string) => {
                         this.languageService.addProjectFile(f, code);
@@ -289,9 +267,11 @@ export default class TypescriptLanguageServiceWebWorker {
      */
     handleHELO(port: MessagePort, eventData: any | {
         sender: string,
-        filename: string
+        filename: string,
+        tsConfig: any
     }) {
         // port.postMessage({ command: WorkerProcessTypes.Message, message: "Hello " + eventData.sender + " (port #" + this.connections + ")" });
+        this.tsConfig = eventData.tsConfig;
         this.loadProjectFiles().then(() => {
             let diagnostics = this.languageService.compile([eventData.filename]);
             this.handleGetAnnotations(port, eventData);
@@ -384,6 +364,7 @@ export default class TypescriptLanguageServiceWebWorker {
      * @param  {WorkerProcessCommands.SaveMessageData} eventData
      */
     handleSave(port: MessagePort, eventData: WorkerProcessTypes.SaveMessageData) {
+        this.tsConfig = eventData.tsConfig;
         this.languageService.updateProjectFile(eventData.filename, eventData.code);
         this.handleGetAnnotations(port, eventData);
 

+ 5 - 1
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/workerprocess/workerProcessTypes.ts

@@ -28,7 +28,11 @@ export interface WorkerProcessMessageData {
     command: string;
 }
 
-export interface SaveMessageData extends WorkerProcessMessageData, Editor.EditorEvents.CodeSavedEvent { }
+export interface TSConfigAttached {
+    tsConfig: any;
+}
+
+export interface SaveMessageData extends WorkerProcessMessageData, Editor.EditorEvents.CodeSavedEvent, TSConfigAttached { }
 export interface DeleteMessageData extends WorkerProcessMessageData, Editor.EditorEvents.DeleteResourceEvent {}
 export interface RenameMessageData extends WorkerProcessMessageData, Editor.EditorEvents.RenameResourceEvent {}