Skip to content

Update the project graph before checking if opened file is present in the existing project #20515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/harness/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3468,6 +3468,38 @@ namespace ts.projectSystem {
it("works when project root is used with case-insensitive system", () => {
verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ false);
});

it("uses existing project even if project refresh is pending", () => {
const projectFolder = "/user/someuser/projects/myproject";
const aFile: FileOrFolder = {
path: `${projectFolder}/src/a.ts`,
content: "export const x = 0;"
};
const configFile: FileOrFolder = {
path: `${projectFolder}/tsconfig.json`,
content: "{}"
};
const files = [aFile, configFile, libFile];
const host = createServerHost(files);
const service = createProjectService(host);
service.openClientFile(aFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder);
verifyProject();

const bFile: FileOrFolder = {
path: `${projectFolder}/src/b.ts`,
content: `export {}; declare module "./a" { export const y: number; }`
};
files.push(bFile);
host.reloadFS(files);
service.openClientFile(bFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder);
verifyProject();

function verifyProject() {
assert.isDefined(service.configuredProjects.get(configFile.path));
const project = service.configuredProjects.get(configFile.path);
checkProjectActualFiles(project, files.map(f => f.path));
}
});
});

describe("tsserverProjectSystem Language service", () => {
Expand Down
26 changes: 16 additions & 10 deletions src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,15 +725,6 @@ namespace ts.server {
}
}

private findContainingExternalProject(fileName: NormalizedPath): ExternalProject {
for (const proj of this.externalProjects) {
if (proj.containsFile(fileName)) {
return proj;
}
}
return undefined;
}

getFormatCodeOptions(file?: NormalizedPath) {
let formatCodeSettings: FormatCodeSettings;
if (file) {
Expand Down Expand Up @@ -1991,13 +1982,24 @@ namespace ts.server {
return this.openClientFileWithNormalizedPath(toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? toNormalizedPath(projectRootPath) : undefined);
}

private findExternalProjetContainingOpenScriptInfo(info: ScriptInfo): ExternalProject {
for (const proj of this.externalProjects) {
// Ensure project structure is uptodate to check if info is present in external project
proj.updateGraph();
if (proj.containsScriptInfo(info)) {
return proj;
}
}
return undefined;
}

openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
let configFileName: NormalizedPath;
let sendConfigFileDiagEvent = false;
let configFileErrors: ReadonlyArray<Diagnostic>;

const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent);
let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName);
let project: ConfiguredProject | ExternalProject = this.findExternalProjetContainingOpenScriptInfo(info);
if (!project) {
configFileName = this.getConfigFileNameForFile(info, projectRootPath);
if (configFileName) {
Expand All @@ -2007,6 +2009,10 @@ namespace ts.server {
// Send the event only if the project got created as part of this open request
sendConfigFileDiagEvent = true;
}
else {
// Ensure project is ready to check if it contains opened script info
project.updateGraph();
}
}
}
if (project && !project.languageServiceEnabled) {
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7605,7 +7605,6 @@ declare namespace ts.server {
* @param forceInferredProjectsRefresh when true updates the inferred projects even if there is no pending work to update the files/project structures
*/
private ensureProjectStructuresUptoDate(forceInferredProjectsRefresh?);
private findContainingExternalProject(fileName);
getFormatCodeOptions(file?: NormalizedPath): FormatCodeSettings;
private updateProjectGraphs(projects);
private onSourceFileChanged(fileName, eventKind);
Expand Down Expand Up @@ -7723,6 +7722,7 @@ declare namespace ts.server {
* @param fileContent is a known version of the file content that is more up to date than the one on disk
*/
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult;
private findExternalProjetContainingOpenScriptInfo(info);
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult;
/**
* Close file whose contents is managed by the client
Expand Down