1// @module: commonjs 2// @skipLibCheck: true 3// @noImplicitAny:true 4// @strictNullChecks:true 5 6// @filename: node_modules/typescript/package.json 7{ 8 "name": "typescript", 9 "types": "/.ts/typescript.d.ts" 10} 11 12// @filename: APISample_watcher.ts 13/* 14 * Note: This test is a public API sample. The sample sources can be found 15 * at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services 16 * Please log a "breaking change" issue for any API breaking change affecting this issue 17 */ 18 19declare var process: any; 20declare var console: any; 21declare var fs: { 22 existsSync(path: string): boolean; 23 readdirSync(path: string): string[]; 24 readFileSync(filename: string, encoding?: string): string; 25 writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; } | string): void; 26 watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: { mtime: Date }, prev: { mtime: Date }) => void): void; 27}; 28declare var path: any; 29 30import * as ts from "typescript"; 31 32function watch(rootFileNames: string[], options: ts.CompilerOptions) { 33 const files: ts.MapLike<{ version: number }> = {}; 34 35 // initialize the list of files 36 rootFileNames.forEach(fileName => { 37 files[fileName] = { version: 0 }; 38 }); 39 40 // Create the language service host to allow the LS to communicate with the host 41 const servicesHost: ts.LanguageServiceHost = { 42 getScriptFileNames: () => rootFileNames, 43 getScriptVersion: (fileName) => files[fileName] && files[fileName].version.toString(), 44 getScriptSnapshot: (fileName) => { 45 if (!fs.existsSync(fileName)) { 46 return undefined; 47 } 48 49 return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString()); 50 }, 51 getCurrentDirectory: () => process.cwd(), 52 getCompilationSettings: () => options, 53 getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), 54 fileExists: fileName => fs.existsSync(fileName), 55 readFile: fileName => fs.readFileSync(fileName), 56 }; 57 58 // Create the language service files 59 const services = ts.createLanguageService(servicesHost, ts.createDocumentRegistry()) 60 61 // Now let's watch the files 62 rootFileNames.forEach(fileName => { 63 // First time around, emit all files 64 emitFile(fileName); 65 66 // Add a watch on the file to handle next change 67 fs.watchFile(fileName, 68 { persistent: true, interval: 250 }, 69 (curr, prev) => { 70 // Check timestamp 71 if (+curr.mtime <= +prev.mtime) { 72 return; 73 } 74 75 // Update the version to signal a change in the file 76 files[fileName].version++; 77 78 // write the changes to disk 79 emitFile(fileName); 80 }); 81 }); 82 83 function emitFile(fileName: string) { 84 let output = services.getEmitOutput(fileName); 85 86 if (!output.emitSkipped) { 87 console.log(`Emitting ${fileName}`); 88 } 89 else { 90 console.log(`Emitting ${fileName} failed`); 91 logErrors(fileName); 92 } 93 94 output.outputFiles.forEach(o => { 95 fs.writeFileSync(o.name, o.text, "utf8"); 96 }); 97 } 98 99 function logErrors(fileName: string) { 100 let allDiagnostics = services.getCompilerOptionsDiagnostics() 101 .concat(services.getSyntacticDiagnostics(fileName)) 102 .concat(services.getSemanticDiagnostics(fileName)); 103 104 allDiagnostics.forEach(diagnostic => { 105 let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); 106 if (diagnostic.file) { 107 let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); 108 console.log(` Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); 109 } 110 else { 111 console.log(` Error: ${message}`); 112 } 113 }); 114 } 115} 116 117// Initialize files constituting the program as all .ts files in the current directory 118const currentDirectoryFiles = fs.readdirSync(process.cwd()). 119 filter(fileName=> fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts"); 120 121// Start the watcher 122watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS }); 123