This commit is contained in:
Eugene Zolenko 2017-02-08 17:37:27 -07:00
parent 93fa5680d2
commit acad7e7eaf

View File

@ -2,6 +2,7 @@ import * as ts from "typescript";
import * as graph from "graphlib";
import * as hash from "object-hash";
import * as fs from "fs";
import * as _ from "lodash";
interface ICode
{
@ -40,6 +41,7 @@ export class Cache
public setDependency(importee: string, importer: string): void
{
// importer -> importee
this.dependencyTree.setEdge(importer, importee);
}
@ -48,61 +50,65 @@ export class Cache
this.treeComplete = true;
}
public markAsDirty(fileName: string, _snapshot: ts.IScriptSnapshot)
public markAsDirty(id: string, _snapshot: ts.IScriptSnapshot)
{
this.dependencyTree.setNode(fileName, { dirty: true });
this.dependencyTree.setNode(id, { dirty: true });
}
public isDirty(fileName: string, _snapshot: ts.IScriptSnapshot): boolean
// returns true if node or any of its imports changed
public isDirty(id: string, _snapshot: ts.IScriptSnapshot, checkImports: boolean): boolean
{
let label = this.dependencyTree.node(fileName) as INodeLabel;
let label = this.dependencyTree.node(id) as INodeLabel;
// TODO: also if any dependencies are dirty
if (checkImports || label.dirty)
return label.dirty;
return label.dirty;
let dependencies = graph.alg.dijkstra(this.dependencyTree, id);
return _.some(_.keys(dependencies), (dependencyId: string) => (this.dependencyTree.node(dependencyId) as INodeLabel).dirty);
}
public getCompiled(fileName: string, snapshot: ts.IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined
public getCompiled(id: string, snapshot: ts.IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined
{
let path = this.makePath(fileName, snapshot);
let path = this.makePath(id, snapshot);
if (!fs.existsSync(path) || this.isDirty(fileName, snapshot))
if (!fs.existsSync(path) || this.isDirty(id, snapshot, false))
{
let data = transform();
this.setCache(path, fileName, snapshot, data);
this.setCache(path, id, snapshot, data);
return data;
}
return JSON.parse(fs.readFileSync(path, "utf8")) as ICode;
}
public getDiagnostics(fileName: string, snapshot: ts.IScriptSnapshot, check: () => ts.Diagnostic[]): ts.Diagnostic[]
public getDiagnostics(id: string, snapshot: ts.IScriptSnapshot, check: () => ts.Diagnostic[]): ts.Diagnostic[]
{
let path = `${this.makePath(fileName, snapshot)}.diagnostics`;
let path = `${this.makePath(id, snapshot)}.diagnostics`;
if (!fs.existsSync(path) || this.isDirty(fileName, snapshot))
if (!fs.existsSync(path) || this.isDirty(id, snapshot, true))
{
let data = check();
this.setCache(path, fileName, snapshot, data);
this.setCache(path, id, snapshot, data);
return data;
}
return JSON.parse(fs.readFileSync(path, "utf8")) as ts.Diagnostic[];
}
private setCache(path: string, fileName: string, snapshot: ts.IScriptSnapshot, data: ts.Diagnostic[] | ICode | undefined): void
private setCache(path: string, id: string, snapshot: ts.IScriptSnapshot, data: ts.Diagnostic[] | ICode | undefined): void
{
if (data === undefined)
return;
fs.writeFileSync(path, JSON.stringify(data));
this.markAsDirty(fileName, snapshot);
this.markAsDirty(id, snapshot);
}
private makePath(fileName: string, snapshot: ts.IScriptSnapshot): string
private makePath(id: string, snapshot: ts.IScriptSnapshot): string
{
let data = snapshot.getText(0, snapshot.getLength());
return `${this.cacheRoot}/${hash.sha1({ data, fileName })}`;
return `${this.cacheRoot}/${hash.sha1({ data, id })}`;
}
}