call updateGraph before getting language service

This commit is contained in:
Vladimir Matveev 2016-07-22 16:01:54 -07:00
parent c0f4fdd489
commit bb016148da
3 changed files with 57 additions and 47 deletions

View File

@ -110,7 +110,7 @@ namespace ts {
const { project, rootScriptInfo } = createProject(root.name, serverHost);
// ensure that imported file was found
let diags = project.languageService.getSemanticDiagnostics(imported.name);
let diags = project.getLanguageService().getSemanticDiagnostics(imported.name);
assert.equal(diags.length, 1);
@ -126,7 +126,7 @@ namespace ts {
var x: string = 1;`;
rootScriptInfo.editContent(0, root.content.length, newContent);
// trigger synchronization to make sure that import will be fetched from the cache
diags = project.languageService.getSemanticDiagnostics(imported.name);
diags = project.getLanguageService().getSemanticDiagnostics(imported.name);
// ensure file has correct number of errors after edit
assert.equal(diags.length, 1);
}
@ -145,7 +145,7 @@ namespace ts {
try {
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
project.languageService.getSemanticDiagnostics(imported.name);
project.getLanguageService().getSemanticDiagnostics(imported.name);
assert.isTrue(false, `should not find file '${imported.name}'`);
}
catch (e) {
@ -167,7 +167,7 @@ namespace ts {
const newContent = `import {x} from "f1"`;
rootScriptInfo.editContent(0, root.content.length, newContent);
project.languageService.getSemanticDiagnostics(imported.name);
project.getLanguageService().getSemanticDiagnostics(imported.name);
assert.isTrue(fileExistsCalled);
// setting compiler options discards module resolution cache
@ -177,7 +177,7 @@ namespace ts {
compilerOptions.target = ts.ScriptTarget.ES5;
project.setCompilerOptions(compilerOptions);
project.languageService.getSemanticDiagnostics(imported.name);
project.getLanguageService().getSemanticDiagnostics(imported.name);
assert.isTrue(fileExistsCalled);
}
});
@ -211,7 +211,7 @@ namespace ts {
const { project, rootScriptInfo } = createProject(root.name, serverHost);
let diags = project.languageService.getSemanticDiagnostics(root.name);
let diags = project.getLanguageService().getSemanticDiagnostics(root.name);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
assert.isTrue(diags.length === 1, "one diagnostic expected");
assert.isTrue(typeof diags[0].messageText === "string" && ((<string>diags[0].messageText).indexOf("Cannot find module") === 0), "should be 'cannot find module' message");
@ -221,7 +221,7 @@ namespace ts {
fileExistsCalledForBar = false;
rootScriptInfo.editContent(0, root.content.length, `import {y} from "bar"`);
diags = project.languageService.getSemanticDiagnostics(root.name);
diags = project.getLanguageService().getSemanticDiagnostics(root.name);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
assert.isTrue(diags.length === 0);
});

View File

@ -24,7 +24,7 @@ namespace ts.server {
private lsHost: ServerLanguageServiceHost;
private program: ts.Program;
languageService: LanguageService;
private languageService: LanguageService;
/**
* Set of files that was returned from the last call to getChangesSinceVersion.
@ -74,6 +74,13 @@ namespace ts.server {
this.markAsDirty();
}
getLanguageService(ensureSynchronized = true): LanguageService {
if (ensureSynchronized) {
this.updateGraph();
}
return this.languageService;
}
getProjectVersion() {
return this.projectStateVersion.toString();
}
@ -225,6 +232,7 @@ namespace ts.server {
}
}
}
return oldProjectStructureVersion === this.projectStructureVersion;
}
@ -278,6 +286,8 @@ namespace ts.server {
}
getChangesSinceVersion(lastKnownVersion?: number): protocol.ProjectFiles {
this.updateGraph();
const info = {
projectName: this.getProjectName(),
version: this.projectStructureVersion,

View File

@ -262,7 +262,7 @@ namespace ts.server {
private semanticCheck(file: NormalizedPath, project: Project) {
try {
const diags = project.languageService.getSemanticDiagnostics(file);
const diags = project.getLanguageService().getSemanticDiagnostics(file);
if (diags) {
const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
@ -276,7 +276,7 @@ namespace ts.server {
private syntacticCheck(file: NormalizedPath, project: Project) {
try {
const diags = project.languageService.getSyntacticDiagnostics(file);
const diags = project.getLanguageService().getSyntacticDiagnostics(file);
if (diags) {
const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
this.event({ file: file, diagnostics: bakedDiags }, "syntaxDiag");
@ -338,7 +338,7 @@ namespace ts.server {
}
this.logger.info(`cleaning ${caption}`);
for (const p of projects) {
p.languageService.cleanupSemanticCache();
p.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache();
}
}
@ -356,7 +356,7 @@ namespace ts.server {
private getEncodedSemanticClassifications(args: protocol.FileSpanRequestArgs) {
const { file, project } = this.getFileAndProject(args);
return project.languageService.getEncodedSemanticClassifications(file, args);
return project.getLanguageService().getEncodedSemanticClassifications(file, args);
}
private getProject(projectFileName: string) {
@ -365,7 +365,7 @@ namespace ts.server {
private getCompilerOptionsDiagnostics(args: protocol.ProjectRequestArgs) {
const project = this.getProject(args.projectFileName);
return this.convertToDiagnosticsWithLinePosition(project.languageService.getCompilerOptionsDiagnostics(), /*scriptInfo*/ undefined);
return this.convertToDiagnosticsWithLinePosition(project.getLanguageService().getCompilerOptionsDiagnostics(), /*scriptInfo*/ undefined);
}
private convertToDiagnosticsWithLinePosition(diagnostics: Diagnostic[], scriptInfo: ScriptInfo) {
@ -394,7 +394,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const definitions = project.languageService.getDefinitionAtPosition(file, position);
const definitions = project.getLanguageService().getDefinitionAtPosition(file, position);
if (!definitions) {
return undefined;
}
@ -419,7 +419,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const definitions = project.languageService.getTypeDefinitionAtPosition(file, position);
const definitions = project.getLanguageService().getTypeDefinitionAtPosition(file, position);
if (!definitions) {
return undefined;
}
@ -439,7 +439,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const occurrences = project.languageService.getOccurrencesAtPosition(file, position);
const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
if (!occurrences) {
return undefined;
@ -460,18 +460,18 @@ namespace ts.server {
}
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
return this.getDiagnosticsWorker(args, (project, file) => project.languageService.getSyntacticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
}
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
return this.getDiagnosticsWorker(args, (project, file) => project.languageService.getSemanticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
}
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): protocol.DocumentHighlightsItem[] | DocumentHighlights[] {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const documentHighlights = project.languageService.getDocumentHighlights(file, position, args.filesToSearch);
const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch);
if (!documentHighlights) {
return undefined;
@ -520,7 +520,7 @@ namespace ts.server {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
return project.languageService.getRenameInfo(file, position);
return project.getLanguageService().getRenameInfo(file, position);
}
private getProjects(args: protocol.FileRequestArgs) {
@ -552,7 +552,7 @@ namespace ts.server {
const defaultProject = projects[0];
// The rename info should be the same for every project
const renameInfo = defaultProject.languageService.getRenameInfo(file, position);
const renameInfo = defaultProject.getLanguageService().getRenameInfo(file, position);
if (!renameInfo) {
return undefined;
}
@ -567,7 +567,7 @@ namespace ts.server {
const fileSpans = combineProjectOutput(
projects,
(project: Project) => {
const renameLocations = project.languageService.findRenameLocations(file, position, args.findInStrings, args.findInComments);
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
if (!renameLocations) {
return [];
}
@ -605,7 +605,7 @@ namespace ts.server {
else {
return combineProjectOutput(
projects,
p => p.languageService.findRenameLocations(file, position, args.findInStrings, args.findInComments),
p => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
/*comparer*/ undefined,
renameLocationIsEqualTo
);
@ -653,7 +653,7 @@ namespace ts.server {
const scriptInfo = defaultProject.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
if (simplifiedResult) {
const nameInfo = defaultProject.languageService.getQuickInfoAtPosition(file, position);
const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
if (!nameInfo) {
return undefined;
}
@ -665,7 +665,7 @@ namespace ts.server {
const refs = combineProjectOutput<protocol.ReferencesResponseItem>(
projects,
(project: Project) => {
const references = project.languageService.getReferencesAtPosition(file, position);
const references = project.getLanguageService().getReferencesAtPosition(file, position);
if (!references) {
return [];
}
@ -699,7 +699,7 @@ namespace ts.server {
else {
return combineProjectOutput(
projects,
project => project.languageService.findReferences(file, position),
project => project.getLanguageService().findReferences(file, position),
undefined,
// TODO: fixme
undefined
@ -750,51 +750,51 @@ namespace ts.server {
private getOutliningSpans(args: protocol.FileRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
return project.languageService.getOutliningSpans(file);
return project.getLanguageService(/*ensureSynchronized*/ false).getOutliningSpans(file);
}
private getTodoComments(args: protocol.TodoCommentRequestArgs) {
const { file, project } = this.getFileAndProject(args);
return project.languageService.getTodoComments(file, args.descriptors);
return project.getLanguageService().getTodoComments(file, args.descriptors);
}
private getDocCommentTemplate(args: protocol.FileLocationRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
return project.languageService.getDocCommentTemplateAtPosition(file, position);
return project.getLanguageService(/*ensureSynchronized*/ false).getDocCommentTemplateAtPosition(file, position);
}
private getIndentation(args: protocol.IndentationRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
const options = args.options || this.projectService.getFormatCodeOptions(file);
const indentation = project.languageService.getIndentationAtPosition(file, position, options);
const indentation = project.getLanguageService(/*ensureSynchronized*/ false).getIndentationAtPosition(file, position, options);
return { position, indentation };
}
private getBreakpointStatement(args: protocol.FileLocationRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
return project.languageService.getBreakpointStatementAtPosition(file, position);
return project.getLanguageService(/*ensureSynchronized*/ false).getBreakpointStatementAtPosition(file, position);
}
private getNameOrDottedNameSpan(args: protocol.FileLocationRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
return project.languageService.getNameOrDottedNameSpan(file, position, position);
return project.getLanguageService(/*ensureSynchronized*/ false).getNameOrDottedNameSpan(file, position, position);
}
private isValidBraceCompletion(args: protocol.BraceCompletionRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
return project.languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
return project.getLanguageService(/*ensureSynchronized*/ false).isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
}
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const quickInfo = project.languageService.getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
if (!quickInfo) {
return undefined;
}
@ -824,7 +824,7 @@ namespace ts.server {
const endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
// TODO: avoid duplicate code (with formatonkey)
const edits = project.languageService.getFormattingEditsForRange(file, startPosition, endPosition,
const edits = project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForRange(file, startPosition, endPosition,
this.projectService.getFormatCodeOptions(file));
if (!edits) {
return undefined;
@ -842,19 +842,19 @@ namespace ts.server {
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
return project.languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForRange(file, args.position, args.endPosition, options);
}
private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
return project.languageService.getFormattingEditsForDocument(file, options);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForDocument(file, options);
}
private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
return project.languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
}
private getFormattingEditsAfterKeystroke(args: protocol.FormatOnKeyRequestArgs): protocol.CodeEdit[] {
@ -862,7 +862,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = scriptInfo.lineOffsetToPosition(args.line, args.offset);
const formatOptions = this.projectService.getFormatCodeOptions(file);
const edits = project.languageService.getFormattingEditsAfterKeystroke(file, position, args.key,
const edits = project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsAfterKeystroke(file, position, args.key,
formatOptions);
// Check whether we should auto-indent. This will be when
// the position is on a line containing only whitespace.
@ -875,7 +875,7 @@ namespace ts.server {
if (lineInfo && (lineInfo.leaf) && (lineInfo.leaf.text)) {
const lineText = lineInfo.leaf.text;
if (lineText.search("\\S") < 0) {
const preferredIndent = project.languageService.getIndentationAtPosition(file, position, formatOptions);
const preferredIndent = project.getLanguageService(/*ensureSynchronized*/ false).getIndentationAtPosition(file, position, formatOptions);
let hasIndent = 0;
let i: number, len: number;
for (i = 0, len = lineText.length; i < len; i++) {
@ -921,7 +921,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const completions = project.languageService.getCompletionsAtPosition(file, position);
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
if (!completions) {
return undefined;
}
@ -944,7 +944,7 @@ namespace ts.server {
const position = this.getPosition(args, scriptInfo);
return args.entryNames.reduce((accum: protocol.CompletionEntryDetails[], entryName: string) => {
const details = project.languageService.getCompletionEntryDetails(file, position, entryName);
const details = project.getLanguageService().getCompletionEntryDetails(file, position, entryName);
if (details) {
accum.push(details);
}
@ -956,7 +956,7 @@ namespace ts.server {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const helpItems = project.languageService.getSignatureHelpItems(file, position);
const helpItems = project.getLanguageService().getSignatureHelpItems(file, position);
if (!helpItems) {
return undefined;
}
@ -1057,7 +1057,7 @@ namespace ts.server {
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
const { file, project } = this.getFileAndProject(args);
const items = project.languageService.getNavigationBarItems(file);
const items = project.getLanguageService().getNavigationBarItems(file);
if (!items) {
return undefined;
}
@ -1074,7 +1074,7 @@ namespace ts.server {
return combineProjectOutput(
projects,
project => {
const navItems = project.languageService.getNavigateToItems(args.searchValue, args.maxResultCount);
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount);
if (!navItems) {
return [];
}
@ -1112,7 +1112,7 @@ namespace ts.server {
else {
return combineProjectOutput(
projects,
project => project.languageService.getNavigateToItems(args.searchValue, args.maxResultCount),
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount),
/*comparer*/ undefined,
navigateToItemIsEqualTo);
}
@ -1152,7 +1152,7 @@ namespace ts.server {
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const spans = project.languageService.getBraceMatchingAtPosition(file, position);
const spans = project.getLanguageService().getBraceMatchingAtPosition(file, position);
if (!spans) {
return undefined;
}