Move the cleanup of script infos to next file open

This helps in reusing script infos even if the project is closed but next open recreates the same project
This commit is contained in:
Sheetal Nandi 2017-06-14 11:37:31 -07:00
parent 1bf1209f7e
commit 98cb0ce815
2 changed files with 35 additions and 13 deletions

View file

@ -2204,10 +2204,10 @@ namespace ts.projectSystem {
projectService.closeClientFile(f1.path);
projectService.checkNumberOfProjects({});
for (const f of [f2, f3]) {
for (const f of [f1, f2, f3]) {
// There shouldnt be any script info as we closed the file that resulted in creation of it
const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path));
assert.equal(scriptInfo, undefined, `expected script info to be closed: '${f.path}'`);
assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`);
}
});

View file

@ -563,10 +563,17 @@ namespace ts.server {
}
else {
if (info && (!info.isScriptOpen())) {
// file has been changed which might affect the set of referenced files in projects that include
// this file and set of inferred projects
info.reloadFromFile();
this.updateProjectGraphs(info.containingProjects);
if (info.containingProjects.length === 0) {
// Orphan script info, remove it as we can always reload it on next open
info.stopWatcher();
this.filenameToScriptInfo.remove(info.path);
}
else {
// file has been changed which might affect the set of referenced files in projects that include
// this file and set of inferred projects
info.reloadFromFile();
this.updateProjectGraphs(info.containingProjects);
}
}
}
}
@ -828,8 +835,17 @@ namespace ts.server {
}
}
// Cleanup script infos that are not open and not part of any project
this.deleteOrphanScriptInfoNotInAnyProject();
// Cleanup script infos that arent part of any project is postponed to
// next file open so that if file from same project is opened we wont end up creating same script infos
}
// If the current info is being just closed - add the watcher file to track changes
// But if file was deleted, handle that part
if (this.host.fileExists(info.fileName)) {
this.watchClosedScriptInfo(info);
}
else {
this.handleDeletedFile(info);
}
}
@ -1310,6 +1326,14 @@ namespace ts.server {
return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
}
watchClosedScriptInfo(info: ScriptInfo) {
// do not watch files with mixed content - server doesn't know how to interpret it
if (!info.hasMixedContent) {
const { fileName } = info;
info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName)));
}
}
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean) {
let info = this.getScriptInfoForNormalizedPath(fileName);
if (!info) {
@ -1325,15 +1349,13 @@ namespace ts.server {
}
}
else {
// do not watch files with mixed content - server doesn't know how to interpret it
if (!hasMixedContent) {
info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName)));
}
this.watchClosedScriptInfo(info);
}
}
}
if (info) {
if (openedByClient && !info.isScriptOpen()) {
info.stopWatcher();
info.open(fileContent);
if (hasMixedContent) {
info.registerFileUpdate();
@ -1429,7 +1451,6 @@ namespace ts.server {
p.updateGraph();
}
this.deleteOrphanScriptInfoNotInAnyProject();
this.printProjects();
}
@ -1463,6 +1484,7 @@ namespace ts.server {
// at this point if file is the part of some configured/external project then this project should be created
const info = this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent);
this.assignScriptInfoToInferredProjectIfNecessary(info, /*addToListOfOpenFiles*/ true);
this.deleteOrphanScriptInfoNotInAnyProject();
this.printProjects();
return { configFileName, configFileErrors };
}