mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Added update of project structure on idle following change (if no
changes in last s seconds (where s is currently 1.5), then check project structure to account for references that may have changed. Turned this off pending fix for getScriptFileNames returning only the root names. Added event handler for deleted file, so that session can update error messages upon deletion of a file from a project.
This commit is contained in:
@@ -65,6 +65,7 @@ module ts.server {
|
||||
ls: ts.LanguageService = null;
|
||||
compilationSettings: ts.CompilerOptions;
|
||||
filenameToScript: ts.Map<ScriptInfo> = {};
|
||||
roots: ScriptInfo[] = [];
|
||||
|
||||
constructor(public host: ServerHost, public project: Project) {
|
||||
}
|
||||
@@ -144,7 +145,7 @@ module ts.server {
|
||||
var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);
|
||||
if (!scriptInfo) {
|
||||
this.filenameToScript[info.fileName] = info;
|
||||
return info;
|
||||
this.roots.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,10 +287,12 @@ module ts.server {
|
||||
return this.filenameToSourceFile[info.fileName];
|
||||
}
|
||||
|
||||
getSourceFileFromName(filename: string) {
|
||||
getSourceFileFromName(filename: string, requireOpen?: boolean) {
|
||||
var info = this.projectService.getScriptInfo(filename);
|
||||
if (info) {
|
||||
return this.getSourceFile(info);
|
||||
if ((!requireOpen) || info.isOpen) {
|
||||
return this.getSourceFile(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +327,7 @@ module ts.server {
|
||||
// add a root file to project
|
||||
addRoot(info: ScriptInfo) {
|
||||
info.defaultProject = this;
|
||||
return this.compilerService.host.addRoot(info);
|
||||
this.compilerService.host.addRoot(info);
|
||||
}
|
||||
|
||||
filesToString() {
|
||||
@@ -360,7 +363,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project): void;
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
@@ -392,7 +395,6 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log(msg: string, type = "Err") {
|
||||
this.psLogger.msg(msg, type);
|
||||
}
|
||||
@@ -423,7 +425,20 @@ module ts.server {
|
||||
for (var i = 0, len = referencingProjects.length; i < len; i++) {
|
||||
referencingProjects[i].removeReferencedFile(info);
|
||||
}
|
||||
for (var j = 0, flen = this.openFileRoots.length; j < flen; j++) {
|
||||
var openFile = this.openFileRoots[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
for (var j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
|
||||
var openFile = this.openFilesReferenced[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
@@ -503,19 +518,52 @@ module ts.server {
|
||||
info.close();
|
||||
}
|
||||
|
||||
findReferencingProjects(info: ScriptInfo) {
|
||||
findReferencingProjects(info: ScriptInfo, excludedProject?: Project) {
|
||||
var referencingProjects: Project[] = [];
|
||||
info.defaultProject = undefined;
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
this.inferredProjects[i].updateGraph();
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
if (this.inferredProjects[i] != excludedProject) {
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return referencingProjects;
|
||||
}
|
||||
|
||||
updateProjectStructure() {
|
||||
this.log("updating project structure from ...", "Info");
|
||||
this.printProjects();
|
||||
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
|
||||
var refdFile = this.openFilesReferenced[i];
|
||||
refdFile.defaultProject.updateGraph();
|
||||
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
|
||||
if (!sourceFile) {
|
||||
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
|
||||
this.addOpenFile(refdFile);
|
||||
}
|
||||
}
|
||||
var openFileRoots: ScriptInfo[] = [];
|
||||
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
|
||||
var rootFile = this.openFileRoots[i];
|
||||
var rootedProject = rootFile.defaultProject;
|
||||
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
|
||||
if (referencingProjects.length == 0) {
|
||||
rootFile.defaultProject = rootedProject;
|
||||
openFileRoots.push(rootFile);
|
||||
}
|
||||
else {
|
||||
// remove project from inferred projects list
|
||||
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
|
||||
this.openFilesReferenced.push(rootFile);
|
||||
}
|
||||
}
|
||||
this.openFileRoots = openFileRoots;
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
getScriptInfo(filename: string) {
|
||||
filename = ts.normalizePath(filename);
|
||||
return ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
@@ -621,6 +669,7 @@ module ts.server {
|
||||
this.psLogger.startGroup();
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
var project = this.inferredProjects[i];
|
||||
project.updateGraph();
|
||||
this.psLogger.info("Project " + i.toString());
|
||||
this.psLogger.info(project.filesToString());
|
||||
this.psLogger.info("-----------------------------------------------");
|
||||
|
||||
@@ -82,7 +82,6 @@ module ts.server {
|
||||
private watchedFiles: WatchedFile[] = [];
|
||||
private nextFileToCheck = 0;
|
||||
private watchTimer: NodeJS.Timer;
|
||||
private static fileDeleted = 34;
|
||||
|
||||
// average async stat takes about 30 microseconds
|
||||
// set chunk size to do 30 files in < 1 millisecond
|
||||
@@ -111,13 +110,7 @@ module ts.server {
|
||||
|
||||
fs.stat(watchedFile.fileName,(err, stats) => {
|
||||
if (err) {
|
||||
var msg = err.message;
|
||||
if (err.errno) {
|
||||
msg += " errno: " + err.errno.toString();
|
||||
}
|
||||
if (err.errno == WatchedFileSet.fileDeleted) {
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
|
||||
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
|
||||
|
||||
@@ -114,7 +114,18 @@ module ts.server {
|
||||
changeSeq = 0;
|
||||
|
||||
constructor(private host: ServerHost, private logger: Logger) {
|
||||
this.projectService = new ProjectService(host, logger);
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName,project,fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n == this.changeSeq, 100);
|
||||
}
|
||||
}
|
||||
|
||||
logError(err: Error, cmd: string) {
|
||||
@@ -191,6 +202,14 @@ module ts.server {
|
||||
this.semanticCheck(file, project);
|
||||
}
|
||||
|
||||
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
|
||||
setTimeout(() => {
|
||||
if (matchSeq(seq)) {
|
||||
this.projectService.updateProjectStructure();
|
||||
}
|
||||
}, ms);
|
||||
}
|
||||
|
||||
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
if (followMs > ms) {
|
||||
@@ -207,7 +226,7 @@ module ts.server {
|
||||
var checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
var checkSpec = checkList[index++];
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName)) {
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = setImmediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
@@ -535,6 +554,10 @@ module ts.server {
|
||||
compilerService.host.editScript(file, start, end, insertString);
|
||||
this.changeSeq++;
|
||||
}
|
||||
// update project structure on idle commented out
|
||||
// until we can have the host return only the root files
|
||||
// from getScriptFileNames()
|
||||
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user