Skip to content

Commit f9518b2

Browse files
author
steveluc
committed
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.
1 parent f19619e commit f9518b2

File tree

3 files changed

+85
-20
lines changed

3 files changed

+85
-20
lines changed

src/server/editorServices.ts

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module ts.server {
6565
ls: ts.LanguageService = null;
6666
compilationSettings: ts.CompilerOptions;
6767
filenameToScript: ts.Map<ScriptInfo> = {};
68+
roots: ScriptInfo[] = [];
6869

6970
constructor(public host: ServerHost, public project: Project) {
7071
}
@@ -144,7 +145,7 @@ module ts.server {
144145
var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);
145146
if (!scriptInfo) {
146147
this.filenameToScript[info.fileName] = info;
147-
return info;
148+
this.roots.push(info);
148149
}
149150
}
150151

@@ -286,10 +287,12 @@ module ts.server {
286287
return this.filenameToSourceFile[info.fileName];
287288
}
288289

289-
getSourceFileFromName(filename: string) {
290+
getSourceFileFromName(filename: string, requireOpen?: boolean) {
290291
var info = this.projectService.getScriptInfo(filename);
291292
if (info) {
292-
return this.getSourceFile(info);
293+
if ((!requireOpen) || info.isOpen) {
294+
return this.getSourceFile(info);
295+
}
293296
}
294297
}
295298

@@ -324,7 +327,7 @@ module ts.server {
324327
// add a root file to project
325328
addRoot(info: ScriptInfo) {
326329
info.defaultProject = this;
327-
return this.compilerService.host.addRoot(info);
330+
this.compilerService.host.addRoot(info);
328331
}
329332

330333
filesToString() {
@@ -360,7 +363,7 @@ module ts.server {
360363
}
361364

362365
interface ProjectServiceEventHandler {
363-
(eventName: string, project: Project): void;
366+
(eventName: string, project: Project, fileName: string): void;
364367
}
365368

366369
export class ProjectService {
@@ -392,7 +395,6 @@ module ts.server {
392395
}
393396
}
394397

395-
396398
log(msg: string, type = "Err") {
397399
this.psLogger.msg(msg, type);
398400
}
@@ -423,7 +425,20 @@ module ts.server {
423425
for (var i = 0, len = referencingProjects.length; i < len; i++) {
424426
referencingProjects[i].removeReferencedFile(info);
425427
}
428+
for (var j = 0, flen = this.openFileRoots.length; j < flen; j++) {
429+
var openFile = this.openFileRoots[j];
430+
if (this.eventHandler) {
431+
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
432+
}
433+
}
434+
for (var j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
435+
var openFile = this.openFilesReferenced[j];
436+
if (this.eventHandler) {
437+
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
438+
}
439+
}
426440
}
441+
427442
this.printProjects();
428443
}
429444

@@ -503,19 +518,52 @@ module ts.server {
503518
info.close();
504519
}
505520

506-
findReferencingProjects(info: ScriptInfo) {
521+
findReferencingProjects(info: ScriptInfo, excludedProject?: Project) {
507522
var referencingProjects: Project[] = [];
508523
info.defaultProject = undefined;
509524
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
510525
this.inferredProjects[i].updateGraph();
511-
if (this.inferredProjects[i].getSourceFile(info)) {
512-
info.defaultProject = this.inferredProjects[i];
513-
referencingProjects.push(this.inferredProjects[i]);
526+
if (this.inferredProjects[i] != excludedProject) {
527+
if (this.inferredProjects[i].getSourceFile(info)) {
528+
info.defaultProject = this.inferredProjects[i];
529+
referencingProjects.push(this.inferredProjects[i]);
530+
}
514531
}
515532
}
516533
return referencingProjects;
517534
}
518535

536+
updateProjectStructure() {
537+
this.log("updating project structure from ...", "Info");
538+
this.printProjects();
539+
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
540+
var refdFile = this.openFilesReferenced[i];
541+
refdFile.defaultProject.updateGraph();
542+
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
543+
if (!sourceFile) {
544+
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
545+
this.addOpenFile(refdFile);
546+
}
547+
}
548+
var openFileRoots: ScriptInfo[] = [];
549+
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
550+
var rootFile = this.openFileRoots[i];
551+
var rootedProject = rootFile.defaultProject;
552+
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
553+
if (referencingProjects.length == 0) {
554+
rootFile.defaultProject = rootedProject;
555+
openFileRoots.push(rootFile);
556+
}
557+
else {
558+
// remove project from inferred projects list
559+
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
560+
this.openFilesReferenced.push(rootFile);
561+
}
562+
}
563+
this.openFileRoots = openFileRoots;
564+
this.printProjects();
565+
}
566+
519567
getScriptInfo(filename: string) {
520568
filename = ts.normalizePath(filename);
521569
return ts.lookUp(this.filenameToScriptInfo, filename);
@@ -621,6 +669,7 @@ module ts.server {
621669
this.psLogger.startGroup();
622670
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
623671
var project = this.inferredProjects[i];
672+
project.updateGraph();
624673
this.psLogger.info("Project " + i.toString());
625674
this.psLogger.info(project.filesToString());
626675
this.psLogger.info("-----------------------------------------------");

src/server/server.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ module ts.server {
8282
private watchedFiles: WatchedFile[] = [];
8383
private nextFileToCheck = 0;
8484
private watchTimer: NodeJS.Timer;
85-
private static fileDeleted = 34;
8685

8786
// average async stat takes about 30 microseconds
8887
// set chunk size to do 30 files in < 1 millisecond
@@ -111,13 +110,7 @@ module ts.server {
111110

112111
fs.stat(watchedFile.fileName,(err, stats) => {
113112
if (err) {
114-
var msg = err.message;
115-
if (err.errno) {
116-
msg += " errno: " + err.errno.toString();
117-
}
118-
if (err.errno == WatchedFileSet.fileDeleted) {
119-
watchedFile.callback(watchedFile.fileName);
120-
}
113+
watchedFile.callback(watchedFile.fileName);
121114
}
122115
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
123116
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);

src/server/session.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,18 @@ module ts.server {
114114
changeSeq = 0;
115115

116116
constructor(private host: ServerHost, private logger: Logger) {
117-
this.projectService = new ProjectService(host, logger);
117+
this.projectService =
118+
new ProjectService(host, logger, (eventName,project,fileName) => {
119+
this.handleEvent(eventName, project, fileName);
120+
});
121+
}
122+
123+
handleEvent(eventName: string, project: Project, fileName: string) {
124+
if (eventName == "context") {
125+
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
126+
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
127+
(n) => n == this.changeSeq, 100);
128+
}
118129
}
119130

120131
logError(err: Error, cmd: string) {
@@ -191,6 +202,14 @@ module ts.server {
191202
this.semanticCheck(file, project);
192203
}
193204

205+
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
206+
setTimeout(() => {
207+
if (matchSeq(seq)) {
208+
this.projectService.updateProjectStructure();
209+
}
210+
}, ms);
211+
}
212+
194213
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
195214
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
196215
if (followMs > ms) {
@@ -207,7 +226,7 @@ module ts.server {
207226
var checkOne = () => {
208227
if (matchSeq(seq)) {
209228
var checkSpec = checkList[index++];
210-
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName)) {
229+
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
211230
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
212231
this.immediateId = setImmediate(() => {
213232
this.semanticCheck(checkSpec.fileName, checkSpec.project);
@@ -535,6 +554,10 @@ module ts.server {
535554
compilerService.host.editScript(file, start, end, insertString);
536555
this.changeSeq++;
537556
}
557+
// update project structure on idle commented out
558+
// until we can have the host return only the root files
559+
// from getScriptFileNames()
560+
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
538561
}
539562
}
540563

0 commit comments

Comments
 (0)