Skip to content

Commit 3716ffe

Browse files
authored
Make getSupportedCodeFixes on LS so it can be proxied by plugins (#51769)
Fixes #28966
1 parent 52203db commit 3716ffe

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.
@@ -10051,6 +10052,7 @@ declare namespace ts {
1005110052
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
1005210053
commentSelection(fileName: string, textRange: TextRange): TextChange[];
1005310054
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
10055+
getSupportedCodeFixes(fileName?: string): readonly string[];
1005410056
dispose(): void;
1005510057
}
1005610058
interface JsxClosingTagInfo {
@@ -11033,7 +11035,7 @@ declare namespace ts {
1103311035
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
1103411036
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
1103511037
function getDefaultCompilerOptions(): CompilerOptions;
11036-
function getSupportedCodeFixes(): string[];
11038+
function getSupportedCodeFixes(): readonly string[];
1103711039
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
1103811040
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
1103911041
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
@@ -6191,6 +6191,7 @@ declare namespace ts {
61916191
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
61926192
commentSelection(fileName: string, textRange: TextRange): TextChange[];
61936193
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
6194+
getSupportedCodeFixes(fileName?: string): readonly string[];
61946195
dispose(): void;
61956196
}
61966197
interface JsxClosingTagInfo {
@@ -7173,7 +7174,7 @@ declare namespace ts {
71737174
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
71747175
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
71757176
function getDefaultCompilerOptions(): CompilerOptions;
7176-
function getSupportedCodeFixes(): string[];
7177+
function getSupportedCodeFixes(): readonly string[];
71777178
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
71787179
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
71797180
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry, syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode): LanguageService;

0 commit comments

Comments
 (0)