Browse Source

Work on getting the typescript to compile w/o error when there are additional .js files in the project. Also work on getting Atomic completions to work inside pure JS files.

Shaddock Heath 9 years ago
parent
commit
aa8c9ba4e3

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

@@ -29,19 +29,6 @@ import * as EditorEvents from "../../editor/EditorEvents";
  * @type {ts.CompilerOptions}
  */
 const defaultCompilerOptions = {
-    noEmitOnError: true,
-    noImplicitAny: false,
-    target: "es5",
-    module: "commonjs",
-    declaration: false,
-    inlineSourceMap: false,
-    removeComments: false,
-    noLib: true,
-    allowNonTsExtensions: false,
-    allowJs: false
-};
-
-const defaultCompilerOptionsJs = {
     noEmitOnError: true,
     noImplicitAny: false,
     target: "es5",
@@ -102,18 +89,11 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
         });
 
         let compilerOptions = defaultCompilerOptions;
-        if (!this.isTypescriptProject)  {
-            compilerOptions = defaultCompilerOptionsJs;
-        }
-
         Atomic.fileSystem.scanDir(ToolCore.toolSystem.project.resourcePath, "*.js", Atomic.SCAN_FILES, true).forEach(filename => {
             let fn = Atomic.addTrailingSlash(ToolCore.toolSystem.project.resourcePath) + filename;
-
-            // only add .js files that don't match .ts files
-            if (projectFiles.indexOf(fn.replace(/\.js$/, ".ts")) == -1) {
-                projectFiles.push(Atomic.addTrailingSlash(ToolCore.toolSystem.project.resourcePath) + filename);
-            }
+            projectFiles.push(Atomic.addTrailingSlash(ToolCore.toolSystem.project.resourcePath) + filename);
         });
+
         // First we need to load in a copy of the lib.core.d.ts that is necessary for the hosted typescript compiler
         projectFiles.push(Atomic.addTrailingSlash(Atomic.addTrailingSlash(ToolCore.toolEnvironment.toolDataDir) + "TypeScriptSupport") + "lib.core.d.ts");
 

+ 27 - 42
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/TypescriptLanguageExtension.ts

@@ -198,36 +198,21 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
             this.buildWorker();
 
             let tsConfig = this.getTsConfig();
-            if (!this.isTranspiledJsFile(ev.filename, tsConfig)) {
-                let model = this.editor.getModel();
-                let handle: number;
-                model.onDidChangeContent(() => {
-                    clearTimeout(handle);
-                    handle = setTimeout(() => this.getAnnotations(), 500);
-                });
+            let model = this.editor.getModel();
+            let handle: number;
+            model.onDidChangeContent(() => {
+                clearTimeout(handle);
+                handle = setTimeout(() => this.getAnnotations(), 500);
+            });
 
-                // post a message to the shared web worker
-                this.worker.port.postMessage({
-                    command: WorkerProcessTypes.Connect,
-                    sender: "Typescript Language Extension",
-                    filename: ev.filename,
-                    tsConfig: tsConfig,
-                    code: ev.code
-                });
-            } else {
-                // This is a transpiled file..make it readonly
-                const generatedHeader = [
-                    "// ********************** MACHINE GENERATED FILE *********************************",
-                    `// This file was generated from the TypeScript source file: ${ev.filename.replace(/\.js$/, ".ts")}`,
-                    "// Any edits made to this file will be overwritten.",
-                    "// *******************************************************************************",
-                    "",
-                    ""
-                ].join("\n");
-
-                let model = this.editor.getModel();
-                model.setValue(generatedHeader + model.getValue());
-            }
+            // post a message to the shared web worker
+            this.worker.port.postMessage({
+                command: WorkerProcessTypes.Connect,
+                sender: "Typescript Language Extension",
+                filename: ev.filename,
+                tsConfig: tsConfig,
+                code: ev.code
+            });
         }
     }
 
@@ -287,19 +272,19 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
     setAnnotations(event: WorkerProcessTypes.GetAnnotationsResponseMessageData) {
         let model = this.editor.getModel();
         let markers = event.annotations
-        .filter(ann => ann.start != undefined)
-        .map(ann => {
-            return {
-                code: ann.code,
-                severity: monaco.Severity.Error,
-                message: ann.message,
-                //source?: string;
-                startLineNumber: model.getPositionAt(ann.start).lineNumber,
-                startColumn: model.getPositionAt(ann.start).column,
-                endLineNumber: model.getPositionAt(ann.start + ann.length).lineNumber,
-                endColumn: model.getPositionAt(ann.start + ann.length).column
-            };
-        });
+            .filter(ann => ann.start != undefined)
+            .map(ann => {
+                return {
+                    code: ann.code,
+                    severity: monaco.Severity.Error,
+                    message: ann.message,
+                    //source?: string;
+                    startLineNumber: model.getPositionAt(ann.start).lineNumber,
+                    startColumn: model.getPositionAt(ann.start).column,
+                    endLineNumber: model.getPositionAt(ann.start + ann.length).lineNumber,
+                    endColumn: model.getPositionAt(ann.start + ann.length).column
+                };
+            });
 
         monaco.editor.setModelMarkers(this.editor.getModel(), "Atomic", markers);
     }

+ 57 - 44
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/workerprocess/TypescriptLanguageService.ts

@@ -76,12 +76,6 @@ export class TypescriptLanguageService {
 
     name: string = "TypescriptLanguageService";
 
-    /**
-     * Perform a full compile on save, or just transpile the current file
-     * @type {boolean}
-     */
-    fullCompile: boolean = true;
-
     private projectFiles: string[] = [];
     private versionMap: ts.Map<{ version: number, snapshot?: ts.IScriptSnapshot }> = {};
 
@@ -119,6 +113,28 @@ export class TypescriptLanguageService {
     setTsConfig(tsConfig: any) {
         let cmdLine = ts.parseJsonConfigFileContent(tsConfig, undefined, undefined);
         this.compilerOptions = cmdLine.options;
+
+        // Set a dummy out directory because we need to be able to handle JS files
+        // and if we don't set one, then the compiler complains that it will
+        // overwrite a source file.  During emit, we just won't emit
+        // js files
+        this.compilerOptions.outDir = "DUMMY_OUT_DIR";
+    }
+
+    /**
+     * Release a project file from the internal project cache
+     * @param  {string} filename
+     */
+    releaseProjectFile(filename: string) {
+        if (this.versionMap[filename]) {
+            const fileIndex = this.projectFiles.indexOf(filename);
+            if (fileIndex > -1) {
+                this.projectFiles.splice(fileIndex, 1);
+            }
+
+            delete this.versionMap[filename];
+            this.documentRegistry.releaseDocument(filename, this.compilerOptions);
+        }
     }
 
     /**
@@ -154,8 +170,10 @@ export class TypescriptLanguageService {
         if (this.projectFiles.indexOf(filename) == -1) {
             return this.addProjectFile(filename, fileContents);
         } else {
+            console.log("Updating file: " + filename);
             this.versionMap[filename].version++;
             this.versionMap[filename].snapshot = ts.ScriptSnapshot.fromString(fileContents);
+
             return this.documentRegistry.updateDocument(
                 filename,
                 this.compilerOptions,
@@ -178,6 +196,7 @@ export class TypescriptLanguageService {
             this.versionMap[filename].snapshot,
             this.versionMap[filename].version.toString());
     }
+
     /**
      * Returns the list of project files
      * @return {string[]}
@@ -203,22 +222,6 @@ export class TypescriptLanguageService {
             };
         });
     }
-    getPreEmitWarnings(filename: string) {
-        let allDiagnostics = this.compileFile(filename);
-        let results = [];
-
-        allDiagnostics.forEach(diagnostic => {
-            results.push({
-                message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"),
-                type: diagnostic.category == 1 ? "error" : "warning",
-                start: diagnostic.start,
-                length: diagnostic.length,
-                code: diagnostic.code,
-                source: filename
-            });
-        });
-        return results;
-    }
 
     /**
      * Simply transpile the typescript file.  This is much faster and only checks for syntax errors
@@ -284,6 +287,15 @@ export class TypescriptLanguageService {
             this.addProjectFile(file);
         });
 
+        // We need to run through and release any transpiled JS files
+        this.projectFiles
+            .filter(f => f.endsWith(".js"))
+            .forEach(f => {
+                if (this.projectFiles.indexOf(f.replace(/\.js$/, ".ts")) > -1) {
+                    this.releaseProjectFile(f);
+                }
+            });
+
         let errors: ts.Diagnostic[] = [];
 
         // if we have a 0 length for files, let's compile all files
@@ -292,11 +304,6 @@ export class TypescriptLanguageService {
         }
 
         files.forEach(filename => {
-            // Don't compile .js files
-            if (!filename.endsWith(".js")) {
-                return;
-            }
-
             let currentErrors = this.compileFile(filename);
             errors = errors.concat(currentErrors);
             if (progress) {
@@ -331,14 +338,18 @@ export class TypescriptLanguageService {
     renameProjectFile(filepath: string, newpath: string): void {
         let oldFile = this.versionMap[filepath];
         if (oldFile) {
-            console.log(`Rename project file from ${filepath} to ${newpath}`);
-            delete this.versionMap[filepath];
+            this.releaseProjectFile(filepath);
+
+            oldFile.version++;
+
             this.versionMap[newpath] = oldFile;
-        }
-        let idx = this.projectFiles.indexOf(filepath);
-        if (idx > -1) {
-            console.log(`Update project files array from ${filepath} to ${newpath}`);
-            this.projectFiles[idx] = newpath;
+            this.projectFiles.push(newpath);
+
+            this.documentRegistry.acquireDocument(
+                newpath,
+                this.compilerOptions,
+                oldFile.snapshot,
+                oldFile.version.toString());
         }
     }
 
@@ -375,17 +386,19 @@ export class TypescriptLanguageService {
      * @return {[ts.Diagnostic]} a list of any errors
      */
     private emitFile(filename: string): ts.Diagnostic[] {
-        let output = this.languageService.getEmitOutput(filename);
         let allDiagnostics: ts.Diagnostic[] = [];
-        if (output.emitSkipped) {
-            console.log(`${this.name}: Failure Emitting ${filename}`);
-            allDiagnostics = this.languageService.getCompilerOptionsDiagnostics()
-                .concat(this.languageService.getSyntacticDiagnostics(filename))
-                .concat(this.languageService.getSemanticDiagnostics(filename));
-        } else {
-            output.outputFiles.forEach(o => {
-                this.fs.writeFile(o.name, o.text);
-            });
+        if (filename.endsWith(".ts")) {
+            let output = this.languageService.getEmitOutput(filename);
+            if (output.emitSkipped) {
+                console.log(`${this.name}: Failure Emitting ${filename}`);
+                allDiagnostics = this.languageService.getCompilerOptionsDiagnostics()
+                    .concat(this.languageService.getSyntacticDiagnostics(filename))
+                    .concat(this.languageService.getSemanticDiagnostics(filename));
+            } else {
+                output.outputFiles.forEach(o => {
+                    this.fs.writeFile(filename.replace(/\.ts$/, ".js"), o.text);
+                });
+            }
         }
 
         return allDiagnostics;

+ 2 - 10
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/workerprocess/TypescriptLanguageServiceWebWorker.ts

@@ -214,14 +214,10 @@ export default class TypescriptLanguageServiceWebWorker {
                     case WorkerProcessTypes.MonacoResolveCompletionItem:
                         this.monacoHandleResolveCompletionItem(port, e.data);
                         break;
-
-
-
                 }
             } catch (e) {
                 port.postMessage({ command: WorkerProcessTypes.Message, message: `Error in TypescriptLanguageServiceWebWorker: ${e}\n${e.stack}` });
             }
-
         }, false);
 
         port.start();
@@ -319,6 +315,7 @@ export default class TypescriptLanguageServiceWebWorker {
         let result = this.tsConfig.files.find(fn => fn.endsWith(partial));
         return result || partial;
     }
+
     /**
      * Get completions
      * @param  {MessagePort} port
@@ -336,7 +333,6 @@ export default class TypescriptLanguageServiceWebWorker {
             command: WorkerProcessTypes.CompletionResponse,
             completions: []
         };
-        let langService = this.languageService;
 
         if (completions) {
             message.completions = completions.entries.map((completion: ts.CompletionEntry) => {
@@ -482,7 +478,6 @@ export default class TypescriptLanguageServiceWebWorker {
         // filename may not include the entire path, so let"s find it in the tsconfig
         let filename = this.resolvePartialFilename(eventData.uri);
         let sourceFile = this.languageService.updateProjectFile(filename, eventData.source);
-
         let completions = this.languageService.getCompletions(filename, eventData.positionOffset);
 
         let message: WorkerProcessTypes.MonacoProvideCompletionItemsResponseMessageData = {
@@ -490,10 +485,7 @@ export default class TypescriptLanguageServiceWebWorker {
             completions: []
         };
 
-        let langService = this.languageService;
-
         if (completions) {
-
             message.completions = completions.entries.map((completion: ts.CompletionEntry) => {
                 let completionItem: WorkerProcessTypes.MonacoWordCompletion = {
                     label: completion.name,
@@ -505,7 +497,7 @@ export default class TypescriptLanguageServiceWebWorker {
                 };
                 return completionItem;
             });
-        }
+        };
 
         port.postMessage(message);
     }