Add support for suppressing project events

VS doesn't consume (e.g.) `syntaxDiag` events, so there's no reason to
do the work to compute their payloads.
This commit is contained in:
Andrew Casey
2018-03-14 18:12:12 -07:00
parent 810b386c2a
commit 517cf6aa89
3 changed files with 27 additions and 5 deletions

View File

@@ -305,6 +305,7 @@ namespace ts.server {
useInferredProjectPerProjectRoot: boolean;
typingsInstaller: ITypingsInstaller;
eventHandler?: ProjectServiceEventHandler;
suppressDiagnosticEvents?: boolean;
throttleWaitMilliseconds?: number;
globalPlugins?: ReadonlyArray<string>;
pluginProbeLocations?: ReadonlyArray<string>;
@@ -392,6 +393,7 @@ namespace ts.server {
public readonly typingsInstaller: ITypingsInstaller;
public readonly throttleWaitMilliseconds?: number;
private readonly eventHandler?: ProjectServiceEventHandler;
private readonly suppressDiagnosticEvents?: boolean;
public readonly globalPlugins: ReadonlyArray<string>;
public readonly pluginProbeLocations: ReadonlyArray<string>;
@@ -413,6 +415,7 @@ namespace ts.server {
this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller;
this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds;
this.eventHandler = opts.eventHandler;
this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
this.globalPlugins = opts.globalPlugins || emptyArray;
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
@@ -1598,7 +1601,7 @@ namespace ts.server {
}
private sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath) {
if (!this.eventHandler) {
if (!this.eventHandler || this.suppressDiagnosticEvents) {
return;
}

View File

@@ -512,6 +512,7 @@ namespace ts.server {
hrtime: process.hrtime,
logger,
canUseEvents: true,
suppressDiagnosticEvents,
globalPlugins,
pluginProbeLocations,
allowLocalPluginLoads,
@@ -927,6 +928,7 @@ namespace ts.server {
const useSingleInferredProject = hasArgument("--useSingleInferredProject");
const useInferredProjectPerProjectRoot = hasArgument("--useInferredProjectPerProjectRoot");
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
const suppressDiagnosticEvents = hasArgument("--suppressDiagnosticEvents");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
logger.info(`Starting TS Server`);

View File

@@ -295,6 +295,8 @@ namespace ts.server {
*/
canUseEvents: boolean;
eventHandler?: ProjectServiceEventHandler;
/** Has no effect if eventHandler is also specified. */
suppressDiagnosticEvents?: boolean;
throttleWaitMilliseconds?: number;
globalPlugins?: ReadonlyArray<string>;
@@ -318,6 +320,7 @@ namespace ts.server {
protected logger: Logger;
protected canUseEvents: boolean;
private suppressDiagnosticEvents?: boolean;
private eventHandler: ProjectServiceEventHandler;
constructor(opts: SessionOptions) {
@@ -328,6 +331,7 @@ namespace ts.server {
this.hrtime = opts.hrtime;
this.logger = opts.logger;
this.canUseEvents = opts.canUseEvents;
this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
const { throttleWaitMilliseconds } = opts;
@@ -352,6 +356,7 @@ namespace ts.server {
typingsInstaller: this.typingsInstaller,
throttleWaitMilliseconds,
eventHandler: this.eventHandler,
suppressDiagnosticEvents: this.suppressDiagnosticEvents,
globalPlugins: opts.globalPlugins,
pluginProbeLocations: opts.pluginProbeLocations,
allowLocalPluginLoads: opts.allowLocalPluginLoads
@@ -401,11 +406,12 @@ namespace ts.server {
private projectsUpdatedInBackgroundEvent(openFiles: string[]): void {
this.projectService.logger.info(`got projects updated in background, updating diagnostics for ${openFiles}`);
if (openFiles.length) {
const checkList = this.createCheckList(openFiles);
// For now only queue error checking for open files. We can change this to include non open files as well
this.errorCheck.startNew(next => this.updateErrorCheck(next, checkList, 100, /*requireOpen*/ true));
if (!this.suppressDiagnosticEvents) {
const checkList = this.createCheckList(openFiles);
// For now only queue error checking for open files. We can change this to include non open files as well
this.errorCheck.startNew(next => this.updateErrorCheck(next, checkList, 100, /*requireOpen*/ true));
}
// Send project changed event
this.event<protocol.ProjectsUpdatedInBackgroundEventBody>({
@@ -489,7 +495,10 @@ namespace ts.server {
}
}
/** It is the caller's responsibility to verify that `!this.suppressDiagnosticEvents`. */
private updateErrorCheck(next: NextStep, checkList: PendingErrorCheck[], ms: number, requireOpen = true) {
Debug.assert(!this.suppressDiagnosticEvents); // Caller's responsibility
const seq = this.changeSeq;
const followMs = Math.min(ms, 200);
@@ -1379,6 +1388,10 @@ namespace ts.server {
}
private getDiagnostics(next: NextStep, delay: number, fileNames: string[]): void {
if (this.suppressDiagnosticEvents) {
return;
}
const checkList = this.createCheckList(fileNames);
if (checkList.length > 0) {
this.updateErrorCheck(next, checkList, delay);
@@ -1748,6 +1761,10 @@ namespace ts.server {
}
private getDiagnosticsForProject(next: NextStep, delay: number, fileName: string): void {
if (this.suppressDiagnosticEvents) {
return;
}
const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true, /*excludeConfigFiles*/ true);
if (languageServiceDisabled) {
return;