106 lines
No EOL
3.8 KiB
TypeScript
106 lines
No EOL
3.8 KiB
TypeScript
// @module: commonjs
|
|
// @includebuiltfile: typescript_standalone.d.ts
|
|
// @stripInternal: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: any;
|
|
declare var path: any;
|
|
|
|
import * as ts from "typescript";
|
|
|
|
function watch(rootFileNames: string[], options: ts.CompilerOptions) {
|
|
const files: ts.Map<{ 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 }); |