Skip to content

Commit

Permalink
Send config file diagnonstics event even when no errors were found (#…
Browse files Browse the repository at this point in the history
…11285)

* emit config diagnostics event when no errors found

* Add tests for project service events
  • Loading branch information
zhengbli authored Oct 10, 2016
1 parent 997acae commit 3b0515f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
63 changes: 60 additions & 3 deletions src/harness/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\harness.ts" />
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />

namespace ts.projectSystem {
Expand Down Expand Up @@ -136,6 +136,19 @@ namespace ts.projectSystem {
return map(fileNames, toExternalFile);
}

export class TestServerEventManager {
private events: server.ProjectServiceEvent[] = [];

handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => {
this.events.push(event);
}

checkEventCountOfType(eventType: "context" | "configFileDiag", expectedCount: number) {
const eventsOfType = filter(this.events, e => e.eventName === eventType);
assert.equal(eventsOfType.length, expectedCount, `The actual event counts of type ${eventType} is ${eventsOfType.length}, while expected ${expectedCount}`);
}
}

export interface TestServerHostCreationParameters {
useCaseSensitiveFileNames?: boolean;
executingFilePath?: string;
Expand All @@ -159,11 +172,11 @@ namespace ts.projectSystem {
return host;
}

export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller) {
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
if (typingsInstaller === undefined) {
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
}

export interface CreateProjectServiceParameters {
Expand Down Expand Up @@ -2121,4 +2134,48 @@ namespace ts.projectSystem {
projectService.inferredProjects[0].getLanguageService().getProgram();
});
});

describe("Configure file diagnostics events", () => {

it("are generated when the config file has errors", () => {
const serverEventManager = new TestServerEventManager();
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 host = createServerHost([file, configFile]);
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
});

it("are generated when the config file doesn't have errors", () => {
const serverEventManager = new TestServerEventManager();
const file = {
path: "/a/b/app.ts",
content: "let x = 10"
};
const configFile = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {}
}`
};

const host = createServerHost([file, configFile]);
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
openFilesForSession([file], session);
serverEventManager.checkEventCountOfType("configFileDiag", 1);
});
});
}
12 changes: 7 additions & 5 deletions src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -755,12 +755,14 @@ namespace ts.server {
}

private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) {
if (diagnostics && diagnostics.length > 0) {
this.eventHandler({
eventName: "configFileDiag",
data: { configFileName, diagnostics, triggerFile }
});
if (!this.eventHandler) {
return;
}

this.eventHandler({
eventName: "configFileDiag",
data: { configFileName, diagnostics: diagnostics || [], triggerFile }
});
}

private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
Expand Down
20 changes: 13 additions & 7 deletions src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ namespace ts.server {
private immediateId: any;
private changeSeq = 0;

private eventHander: ProjectServiceEventHandler;

constructor(
private host: ServerHost,
cancellationToken: HostCancellationToken,
Expand All @@ -163,17 +165,18 @@ namespace ts.server {
private byteLength: (buf: string, encoding?: string) => number,
private hrtime: (start?: number[]) => number[],
protected logger: Logger,
protected readonly canUseEvents: boolean) {
protected readonly canUseEvents: boolean,
eventHandler?: ProjectServiceEventHandler) {

const eventHandler: ProjectServiceEventHandler = canUseEvents
? event => this.handleEvent(event)
this.eventHander = canUseEvents
? eventHandler || (event => this.defaultEventHandler(event))
: undefined;

this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, eventHandler);
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
}

private handleEvent(event: ProjectServiceEvent) {
private defaultEventHandler(event: ProjectServiceEvent) {
switch (event.eventName) {
case "context":
const { project, fileName } = event.data;
Expand Down Expand Up @@ -734,8 +737,11 @@ namespace ts.server {
*/
private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind) {
const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind);
if (configFileErrors) {
this.configFileDiagnosticEvent(fileName, configFileName, configFileErrors);
if (this.eventHander) {
this.eventHander({
eventName: "configFileDiag",
data: { fileName, configFileName, diagnostics: configFileErrors || [] }
});
}
}

Expand Down

0 comments on commit 3b0515f

Please sign in to comment.