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