mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Merge pull request #22590 from amcasey/DiagEvents
Add support for suppressing project events
This commit is contained in:
commit
6524fc53be
@ -168,11 +168,12 @@ namespace ts.projectSystem {
|
||||
readonly session: TestSession;
|
||||
readonly service: server.ProjectService;
|
||||
readonly host: TestServerHost;
|
||||
constructor(files: FileOrFolder[]) {
|
||||
constructor(files: FileOrFolder[], suppressDiagnosticEvents?: boolean) {
|
||||
this.host = createServerHost(files);
|
||||
this.session = createSession(this.host, {
|
||||
canUseEvents: true,
|
||||
eventHandler: event => this.events.push(event),
|
||||
suppressDiagnosticEvents,
|
||||
});
|
||||
this.service = this.session.getProjectService();
|
||||
}
|
||||
@ -485,6 +486,12 @@ namespace ts.projectSystem {
|
||||
checkNthEvent(session, server.toEvent("projectsUpdatedInBackground", { openFiles }), 0, /*isMostRecent*/ true);
|
||||
}
|
||||
|
||||
function checkNoDiagnosticEvents(session: TestSession) {
|
||||
for (const event of session.events) {
|
||||
assert.isFalse(event.event.endsWith("Diag"), JSON.stringify(event));
|
||||
}
|
||||
}
|
||||
|
||||
function checkNthEvent(session: TestSession, expectedEvent: protocol.Event, index: number, isMostRecent: boolean) {
|
||||
const events = session.events;
|
||||
assert.deepEqual(events[index], expectedEvent);
|
||||
@ -4074,6 +4081,63 @@ namespace ts.projectSystem {
|
||||
session.clearMessages();
|
||||
});
|
||||
|
||||
it("suppressed diagnostic events", () => {
|
||||
const file: FileOrFolder = {
|
||||
path: "/a.ts",
|
||||
content: "1 = 2;",
|
||||
};
|
||||
|
||||
const host = createServerHost([file]);
|
||||
const session = createSession(host, { canUseEvents: true, suppressDiagnosticEvents: true });
|
||||
const service = session.getProjectService();
|
||||
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: server.CommandNames.Open,
|
||||
arguments: { file: file.path, fileContent: file.content },
|
||||
});
|
||||
|
||||
checkNumberOfProjects(service, { inferredProjects: 1 });
|
||||
|
||||
host.checkTimeoutQueueLength(0);
|
||||
checkNoDiagnosticEvents(session);
|
||||
|
||||
session.clearMessages();
|
||||
|
||||
let expectedSequenceId = session.getNextSeq();
|
||||
|
||||
session.executeCommandSeq<protocol.GeterrRequest>({
|
||||
command: server.CommandNames.Geterr,
|
||||
arguments: {
|
||||
delay: 0,
|
||||
files: [file.path],
|
||||
}
|
||||
});
|
||||
|
||||
host.checkTimeoutQueueLength(0);
|
||||
checkNoDiagnosticEvents(session);
|
||||
|
||||
checkCompleteEvent(session, 1, expectedSequenceId);
|
||||
|
||||
session.clearMessages();
|
||||
|
||||
expectedSequenceId = session.getNextSeq();
|
||||
|
||||
session.executeCommandSeq<protocol.GeterrForProjectRequest>({
|
||||
command: server.CommandNames.Geterr,
|
||||
arguments: {
|
||||
delay: 0,
|
||||
file: file.path,
|
||||
}
|
||||
});
|
||||
|
||||
host.checkTimeoutQueueLength(0);
|
||||
checkNoDiagnosticEvents(session);
|
||||
|
||||
checkCompleteEvent(session, 1, expectedSequenceId);
|
||||
|
||||
session.clearMessages();
|
||||
});
|
||||
|
||||
function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray<string> = []): protocol.Diagnostic {
|
||||
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category: diagnosticCategoryName(message), source: undefined };
|
||||
}
|
||||
@ -4149,7 +4213,7 @@ namespace ts.projectSystem {
|
||||
serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, configFile.path);
|
||||
});
|
||||
|
||||
it("are not generated when the config file doesnot include file opened and config file has errors", () => {
|
||||
it("are not generated when the config file does not include file opened and config file has errors", () => {
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
@ -4173,7 +4237,26 @@ namespace ts.projectSystem {
|
||||
serverEventManager.hasZeroEvent("configFileDiag");
|
||||
});
|
||||
|
||||
it("are not generated when the config file doesnot include file opened and doesnt contain any errors", () => {
|
||||
it("are not generated when the config file has errors but suppressDiagnosticEvents is true", () => {
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
};
|
||||
const configFile = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: `{
|
||||
"compilerOptions": {
|
||||
"foo": "bar",
|
||||
"allowJS": true
|
||||
}
|
||||
}`
|
||||
};
|
||||
const serverEventManager = new TestServerEventManager([file, configFile], /*suppressDiagnosticEvents*/ true);
|
||||
openFilesForSession([file], serverEventManager.session);
|
||||
serverEventManager.hasZeroEvent("configFileDiag");
|
||||
});
|
||||
|
||||
it("are not generated when the config file does not include file opened and doesnt contain any errors", () => {
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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`);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -7258,6 +7258,8 @@ declare namespace ts.server {
|
||||
*/
|
||||
canUseEvents: boolean;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
/** Has no effect if eventHandler is also specified. */
|
||||
suppressDiagnosticEvents?: boolean;
|
||||
throttleWaitMilliseconds?: number;
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
@ -7276,6 +7278,7 @@ declare namespace ts.server {
|
||||
private hrtime;
|
||||
protected logger: Logger;
|
||||
protected canUseEvents: boolean;
|
||||
private suppressDiagnosticEvents?;
|
||||
private eventHandler;
|
||||
constructor(opts: SessionOptions);
|
||||
private sendRequestCompletedEvent;
|
||||
@ -7291,6 +7294,7 @@ declare namespace ts.server {
|
||||
private syntacticCheck;
|
||||
private infoCheck;
|
||||
private sendDiagnosticsEvent;
|
||||
/** It is the caller's responsibility to verify that `!this.suppressDiagnosticEvents`. */
|
||||
private updateErrorCheck;
|
||||
private cleanProjects;
|
||||
private cleanup;
|
||||
@ -7819,6 +7823,7 @@ declare namespace ts.server {
|
||||
useInferredProjectPerProjectRoot: boolean;
|
||||
typingsInstaller: ITypingsInstaller;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
suppressDiagnosticEvents?: boolean;
|
||||
throttleWaitMilliseconds?: number;
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
@ -7885,6 +7890,7 @@ declare namespace ts.server {
|
||||
readonly typingsInstaller: ITypingsInstaller;
|
||||
readonly throttleWaitMilliseconds?: number;
|
||||
private readonly eventHandler?;
|
||||
private readonly suppressDiagnosticEvents?;
|
||||
readonly globalPlugins: ReadonlyArray<string>;
|
||||
readonly pluginProbeLocations: ReadonlyArray<string>;
|
||||
readonly allowLocalPluginLoads: boolean;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user