Skip to content

Commit 1aab032

Browse files
committed
Make getSupportedCodeFixes on LS so it can be proxied by plugins
Fixes #28966
1 parent 0c09d2f commit 1aab032

File tree

11 files changed

+4117
-8
lines changed

11 files changed

+4117
-8
lines changed

src/harness/client.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
FormatCodeOptions,
3232
FormatCodeSettings,
3333
getSnapshotText,
34+
getSupportedCodeFixes,
3435
identity,
3536
ImplementationLocation,
3637
InlayHint,
@@ -950,6 +951,10 @@ export class SessionClient implements LanguageService {
950951
return response.body.map(item => this.convertCallHierarchyOutgoingCall(fileName, item));
951952
}
952953

954+
getSupportedCodeFixes(): readonly string[] {
955+
return getSupportedCodeFixes();
956+
}
957+
953958
getProgram(): Program {
954959
throw new Error("Program objects are not serializable through the server protocol.");
955960
}

src/harness/harnessLanguageService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,9 @@ class LanguageServiceShimProxy implements ts.LanguageService {
600600
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan {
601601
return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine));
602602
}
603+
getSupportedCodeFixes(): never {
604+
throw new Error("Not supported on the shim.");
605+
}
603606
getCodeFixesAtPosition(): never {
604607
throw new Error("Not supported on the shim.");
605608
}

src/server/protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ export interface FileLocationRequest extends FileRequest {
840840
*/
841841
export interface GetSupportedCodeFixesRequest extends Request {
842842
command: CommandTypes.GetSupportedCodeFixes;
843+
arguments?: Partial<FileRequestArgs>;
843844
}
844845

845846
/**

src/server/session.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,8 +2640,15 @@ export class Session<TMessage = string> implements EventSender {
26402640
}
26412641
}
26422642

2643-
private getSupportedCodeFixes(): string[] {
2644-
return getSupportedCodeFixes();
2643+
private getSupportedCodeFixes(args: Partial<protocol.FileRequestArgs> | undefined): readonly string[] {
2644+
if (!args) return getSupportedCodeFixes(); // Compatibility
2645+
if (args.file) {
2646+
const { file, project } = this.getFileAndProject(args as protocol.FileRequestArgs);
2647+
return project.getLanguageService().getSupportedCodeFixes(file);
2648+
}
2649+
const project = this.getProject(args.projectFileName);
2650+
if (!project) Errors.ThrowNoProject();
2651+
return project.getLanguageService().getSupportedCodeFixes();
26452652
}
26462653

26472654
private isLocation(locationOrSpan: protocol.FileLocationOrRangeRequestArgs): locationOrSpan is protocol.FileLocationRequestArgs {
@@ -3419,8 +3426,8 @@ export class Session<TMessage = string> implements EventSender {
34193426
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
34203427
return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
34213428
},
3422-
[CommandNames.GetSupportedCodeFixes]: () => {
3423-
return this.requiredResponse(this.getSupportedCodeFixes());
3429+
[CommandNames.GetSupportedCodeFixes]: (request: protocol.GetSupportedCodeFixesRequest) => {
3430+
return this.requiredResponse(this.getSupportedCodeFixes(request.arguments));
34243431
},
34253432
[CommandNames.GetApplicableRefactors]: (request: protocol.GetApplicableRefactorsRequest) => {
34263433
return this.requiredResponse(this.getApplicableRefactors(request.arguments));

src/services/codeFixProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function registerCodeFix(reg: CodeFixRegistration) {
6161
}
6262

6363
/** @internal */
64-
export function getSupportedErrorCodes(): string[] {
64+
export function getSupportedErrorCodes(): readonly string[] {
6565
return arrayFrom(errorCodeToFixes.keys());
6666
}
6767

src/services/services.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,8 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[]
15121512
"prepareCallHierarchy",
15131513
"provideCallHierarchyIncomingCalls",
15141514
"provideCallHierarchyOutgoingCalls",
1515-
"provideInlayHints"
1515+
"provideInlayHints",
1516+
"getSupportedCodeFixes",
15161517
];
15171518

15181519
const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [
@@ -3046,6 +3047,7 @@ export function createLanguageService(
30463047
commentSelection,
30473048
uncommentSelection,
30483049
provideInlayHints,
3050+
getSupportedCodeFixes,
30493051
};
30503052

30513053
switch (languageServiceMode) {

src/services/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ export interface LanguageService {
657657
commentSelection(fileName: string, textRange: TextRange): TextChange[];
658658
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
659659

660+
getSupportedCodeFixes(fileName?: string): readonly string[];
661+
660662
dispose(): void;
661663
}
662664

src/testRunner/unittests/tsserver/plugins.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,73 @@ describe("unittests:: tsserver:: plugins loading", () => {
159159

160160
baselineTsserverLogs("plugins", "gets external files with config file reload", session);
161161
});
162+
});
163+
164+
describe("unittests:: tsserver:: plugins overriding getSupportedCodeFixes", () => {
165+
it("getSupportedCodeFixes can be proxied", () => {
166+
const aTs: File = {
167+
path: "/a.ts",
168+
content: `class c { prop = "hello"; foo() { const x = 0; } }`
169+
};
170+
const bTs: File = {
171+
path: "/b.ts",
172+
content: aTs.content
173+
};
174+
const cTs: File = {
175+
path: "/c.ts",
176+
content: aTs.content
177+
};
178+
const config: File = {
179+
path: "/tsconfig.json",
180+
content: JSON.stringify({
181+
compilerOptions: { plugins: [{ name: "myplugin" }] }
182+
})
183+
};
184+
const host = createServerHost([aTs, bTs, cTs, config, libFile]);
185+
host.require = () => {
186+
return {
187+
module: () => ({
188+
create(info: ts.server.PluginCreateInfo) {
189+
const proxy = Harness.LanguageService.makeDefaultProxy(info);
190+
proxy.getSupportedCodeFixes = (fileName) => {
191+
switch (fileName) {
192+
case "/a.ts":
193+
return ["a"];
194+
case "/b.ts":
195+
return ["b"];
196+
default:
197+
return info.languageService.getSupportedCodeFixes(fileName);
198+
}
199+
};
200+
return proxy;
201+
}
202+
}),
203+
error: undefined
204+
};
205+
};
206+
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
207+
openFilesForSession([aTs, bTs, cTs], session);
208+
// Without arguments
209+
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
210+
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
211+
});
212+
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
213+
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
214+
arguments: { file: aTs.path }
215+
});
216+
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
217+
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
218+
arguments: { file: bTs.path }
219+
});
220+
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
221+
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
222+
arguments: { file: cTs.path }
223+
});
224+
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
225+
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
226+
arguments: { projectFileName: config.path }
227+
});
228+
229+
baselineTsserverLogs("plugins", "getSupportedCodeFixes can be proxied", session);
230+
});
162231
});

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ declare namespace ts {
691691
*/
692692
interface GetSupportedCodeFixesRequest extends Request {
693693
command: CommandTypes.GetSupportedCodeFixes;
694+
arguments?: Partial<FileRequestArgs>;
694695
}
695696
/**
696697
* A response for GetSupportedCodeFixesRequest request.
@@ -10038,6 +10039,7 @@ declare namespace ts {
1003810039
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
1003910040
commentSelection(fileName: string, textRange: TextRange): TextChange[];
1004010041
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
10042+
getSupportedCodeFixes(fileName?: string): readonly string[];
1004110043
dispose(): void;
1004210044
}
1004310045
interface JsxClosingTagInfo {
@@ -11020,7 +11022,7 @@ declare namespace ts {
1102011022
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
1102111023
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
1102211024
function getDefaultCompilerOptions(): CompilerOptions;
11023-
function getSupportedCodeFixes(): string[];
11025+
function getSupportedCodeFixes(): readonly string[];
1102411026
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
1102511027
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
1102611028
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry, syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode): LanguageService;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6178,6 +6178,7 @@ declare namespace ts {
61786178
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
61796179
commentSelection(fileName: string, textRange: TextRange): TextChange[];
61806180
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
6181+
getSupportedCodeFixes(fileName?: string): readonly string[];
61816182
dispose(): void;
61826183
}
61836184
interface JsxClosingTagInfo {
@@ -7160,7 +7161,7 @@ declare namespace ts {
71607161
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
71617162
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
71627163
function getDefaultCompilerOptions(): CompilerOptions;
7163-
function getSupportedCodeFixes(): string[];
7164+
function getSupportedCodeFixes(): readonly string[];
71647165
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
71657166
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
71667167
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry, syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode): LanguageService;

0 commit comments

Comments
 (0)