Skip to content

Commit 0996bff

Browse files
Support syntactic diagnostics in partial mode (#44859)
* Initial work to support syntactic diagnostics in partial mode. * Test out 'syntacticDiagnosticsSync' requests. * Added a 'geterr' test. * Accepted baselines. * Remove/clean up comments.
1 parent acdf62f commit 0996bff

File tree

4 files changed

+82
-10
lines changed

4 files changed

+82
-10
lines changed

src/server/session.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,7 @@ namespace ts.server {
629629
CommandNames.CompilerOptionsDiagnosticsFull,
630630
CommandNames.EncodedSemanticClassificationsFull,
631631
CommandNames.SemanticDiagnosticsSync,
632-
CommandNames.SyntacticDiagnosticsSync,
633632
CommandNames.SuggestionDiagnosticsSync,
634-
CommandNames.Geterr,
635633
CommandNames.GeterrForProject,
636634
CommandNames.Reload,
637635
CommandNames.ReloadProjects,
@@ -1055,7 +1053,7 @@ namespace ts.server {
10551053

10561054
const { fileName, project } = item;
10571055

1058-
// Ensure the project is upto date before checking if this file is present in the project
1056+
// Ensure the project is up to date before checking if this file is present in the project.
10591057
updateProjectIfDirty(project);
10601058
if (!project.containsFile(fileName, requireOpen)) {
10611059
return;
@@ -1066,6 +1064,11 @@ namespace ts.server {
10661064
return;
10671065
}
10681066

1067+
// Don't provide semantic diagnostics unless we're in full semantic mode.
1068+
if (project.projectService.serverMode !== LanguageServiceMode.Semantic) {
1069+
goNext();
1070+
return;
1071+
}
10691072
next.immediate(() => {
10701073
this.semanticCheck(fileName, project);
10711074
if (this.changeSeq !== seq) {
@@ -1074,13 +1077,12 @@ namespace ts.server {
10741077

10751078
if (this.getPreferences(fileName).disableSuggestions) {
10761079
goNext();
1080+
return;
10771081
}
1078-
else {
1079-
next.immediate(() => {
1080-
this.suggestionCheck(fileName, project);
1081-
goNext();
1082-
});
1083-
}
1082+
next.immediate(() => {
1083+
this.suggestionCheck(fileName, project);
1084+
goNext();
1085+
});
10841086
});
10851087
};
10861088

src/services/services.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,6 @@ namespace ts {
11711171
}
11721172

11731173
const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[] = [
1174-
"getSyntacticDiagnostics",
11751174
"getSemanticDiagnostics",
11761175
"getSuggestionDiagnostics",
11771176
"getCompilerOptionsDiagnostics",

src/testRunner/unittests/tsserver/partialSemanticServer.ts

+40
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,46 @@ import { something } from "something";
111111
assert.isTrue(hasException);
112112
});
113113

114+
it("allows syntactic diagnostic commands", () => {
115+
const file1: File = {
116+
path: `${tscWatch.projectRoot}/a.ts`,
117+
content: `if (a < (b + c) { }`
118+
};
119+
const configFile: File = {
120+
path: `${tscWatch.projectRoot}/tsconfig.json`,
121+
content: `{}`
122+
};
123+
const expectedErrorMessage = "')' expected.";
124+
125+
const host = createServerHost([file1, libFile, configFile]);
126+
const session = createSession(host, {
127+
serverMode: LanguageServiceMode.PartialSemantic,
128+
useSingleInferredProject: true,
129+
logger: createLoggerWithInMemoryLogs()
130+
});
131+
132+
const service = session.getProjectService();
133+
openFilesForSession([file1], session);
134+
const request: protocol.SyntacticDiagnosticsSyncRequest = {
135+
type: "request",
136+
seq: 1,
137+
command: protocol.CommandTypes.SyntacticDiagnosticsSync,
138+
arguments: { file: file1.path }
139+
};
140+
const response = session.executeCommandSeq(request).response as protocol.SyntacticDiagnosticsSyncResponse["body"];
141+
assert.isDefined(response);
142+
assert.equal(response!.length, 1);
143+
assert.equal((response![0] as protocol.Diagnostic).text, expectedErrorMessage);
144+
145+
const project = service.inferredProjects[0];
146+
const diagnostics = project.getLanguageService().getSyntacticDiagnostics(file1.path);
147+
assert.isTrue(diagnostics.length === 1);
148+
assert.equal(diagnostics[0].messageText, expectedErrorMessage);
149+
150+
verifyGetErrRequest({ session, host, files: [file1], skip: [{ semantic: true, suggestion: true }] });
151+
baselineTsserverLogs("partialSemanticServer", "syntactic diagnostics are returned with no error", session);
152+
});
153+
114154
it("should not include auto type reference directives", () => {
115155
const { host, session, file1 } = setup();
116156
const atTypes: File = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Provided types map file "/a/lib/typesMap.json" doesn't exist
2+
request:{"seq":0,"type":"request","command":"open","arguments":{"file":"/user/username/projects/myproject/a.ts"}}
3+
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
4+
Starting updateGraphWorker: Project: /dev/null/inferredProject1*
5+
Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
6+
Project '/dev/null/inferredProject1*' (Inferred)
7+
Files (2)
8+
/a/lib/lib.d.ts
9+
/user/username/projects/myproject/a.ts
10+
11+
12+
a/lib/lib.d.ts
13+
Default library for target 'es5'
14+
user/username/projects/myproject/a.ts
15+
Root file specified for compilation
16+
17+
-----------------------------------------------
18+
Project '/dev/null/inferredProject1*' (Inferred)
19+
Files (2)
20+
21+
-----------------------------------------------
22+
Open files:
23+
FileName: /user/username/projects/myproject/a.ts ProjectRootPath: undefined
24+
Projects: /dev/null/inferredProject1*
25+
response:{"responseRequired":false}
26+
request:{"type":"request","seq":1,"command":"syntacticDiagnosticsSync","arguments":{"file":"/user/username/projects/myproject/a.ts"}}
27+
response:{"response":[{"start":{"line":1,"offset":17},"end":{"line":1,"offset":18},"text":"')' expected.","code":1005,"category":"error"}],"responseRequired":true}
28+
request:{"command":"geterr","arguments":{"delay":0,"files":["/user/username/projects/myproject/a.ts"]},"seq":2,"type":"request"}
29+
response:{"responseRequired":false}
30+
Session does not support events: ignored event: {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"/user/username/projects/myproject/a.ts","diagnostics":[{"start":{"line":1,"offset":17},"end":{"line":1,"offset":18},"text":"')' expected.","code":1005,"category":"error"}]}}
31+
Session does not support events: ignored event: {"seq":0,"type":"event","event":"requestCompleted","body":{"request_seq":2}}

0 commit comments

Comments
 (0)