Make getSupportedCodeFixes on LS so it can be proxied by plugins (#51769)

Fixes #28966
This commit is contained in:
Sheetal Nandi
2022-12-08 09:52:25 -08:00
committed by GitHub
parent 52203dbc46
commit 3716ffe748
11 changed files with 4117 additions and 8 deletions
+5
View File
@@ -31,6 +31,7 @@ import {
FormatCodeOptions,
FormatCodeSettings,
getSnapshotText,
getSupportedCodeFixes,
identity,
ImplementationLocation,
InlayHint,
@@ -950,6 +951,10 @@ export class SessionClient implements LanguageService {
return response.body.map(item => this.convertCallHierarchyOutgoingCall(fileName, item));
}
getSupportedCodeFixes(): readonly string[] {
return getSupportedCodeFixes();
}
getProgram(): Program {
throw new Error("Program objects are not serializable through the server protocol.");
}
+3
View File
@@ -600,6 +600,9 @@ class LanguageServiceShimProxy implements ts.LanguageService {
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan {
return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine));
}
getSupportedCodeFixes(): never {
throw new Error("Not supported on the shim.");
}
getCodeFixesAtPosition(): never {
throw new Error("Not supported on the shim.");
}
+1
View File
@@ -840,6 +840,7 @@ export interface FileLocationRequest extends FileRequest {
*/
export interface GetSupportedCodeFixesRequest extends Request {
command: CommandTypes.GetSupportedCodeFixes;
arguments?: Partial<FileRequestArgs>;
}
/**
+11 -4
View File
@@ -2640,8 +2640,15 @@ export class Session<TMessage = string> implements EventSender {
}
}
private getSupportedCodeFixes(): string[] {
return getSupportedCodeFixes();
private getSupportedCodeFixes(args: Partial<protocol.FileRequestArgs> | undefined): readonly string[] {
if (!args) return getSupportedCodeFixes(); // Compatibility
if (args.file) {
const { file, project } = this.getFileAndProject(args as protocol.FileRequestArgs);
return project.getLanguageService().getSupportedCodeFixes(file);
}
const project = this.getProject(args.projectFileName);
if (!project) Errors.ThrowNoProject();
return project.getLanguageService().getSupportedCodeFixes();
}
private isLocation(locationOrSpan: protocol.FileLocationOrRangeRequestArgs): locationOrSpan is protocol.FileLocationRequestArgs {
@@ -3419,8 +3426,8 @@ export class Session<TMessage = string> implements EventSender {
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
},
[CommandNames.GetSupportedCodeFixes]: () => {
return this.requiredResponse(this.getSupportedCodeFixes());
[CommandNames.GetSupportedCodeFixes]: (request: protocol.GetSupportedCodeFixesRequest) => {
return this.requiredResponse(this.getSupportedCodeFixes(request.arguments));
},
[CommandNames.GetApplicableRefactors]: (request: protocol.GetApplicableRefactorsRequest) => {
return this.requiredResponse(this.getApplicableRefactors(request.arguments));
+1 -1
View File
@@ -61,7 +61,7 @@ export function registerCodeFix(reg: CodeFixRegistration) {
}
/** @internal */
export function getSupportedErrorCodes(): string[] {
export function getSupportedErrorCodes(): readonly string[] {
return arrayFrom(errorCodeToFixes.keys());
}
+3 -1
View File
@@ -1512,7 +1512,8 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[]
"prepareCallHierarchy",
"provideCallHierarchyIncomingCalls",
"provideCallHierarchyOutgoingCalls",
"provideInlayHints"
"provideInlayHints",
"getSupportedCodeFixes",
];
const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [
@@ -3046,6 +3047,7 @@ export function createLanguageService(
commentSelection,
uncommentSelection,
provideInlayHints,
getSupportedCodeFixes,
};
switch (languageServiceMode) {
+2
View File
@@ -657,6 +657,8 @@ export interface LanguageService {
commentSelection(fileName: string, textRange: TextRange): TextChange[];
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
getSupportedCodeFixes(fileName?: string): readonly string[];
dispose(): void;
}
@@ -159,4 +159,73 @@ describe("unittests:: tsserver:: plugins loading", () => {
baselineTsserverLogs("plugins", "gets external files with config file reload", session);
});
});
describe("unittests:: tsserver:: plugins overriding getSupportedCodeFixes", () => {
it("getSupportedCodeFixes can be proxied", () => {
const aTs: File = {
path: "/a.ts",
content: `class c { prop = "hello"; foo() { const x = 0; } }`
};
const bTs: File = {
path: "/b.ts",
content: aTs.content
};
const cTs: File = {
path: "/c.ts",
content: aTs.content
};
const config: File = {
path: "/tsconfig.json",
content: JSON.stringify({
compilerOptions: { plugins: [{ name: "myplugin" }] }
})
};
const host = createServerHost([aTs, bTs, cTs, config, libFile]);
host.require = () => {
return {
module: () => ({
create(info: ts.server.PluginCreateInfo) {
const proxy = Harness.LanguageService.makeDefaultProxy(info);
proxy.getSupportedCodeFixes = (fileName) => {
switch (fileName) {
case "/a.ts":
return ["a"];
case "/b.ts":
return ["b"];
default:
return info.languageService.getSupportedCodeFixes(fileName);
}
};
return proxy;
}
}),
error: undefined
};
};
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
openFilesForSession([aTs, bTs, cTs], session);
// Without arguments
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
});
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
arguments: { file: aTs.path }
});
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
arguments: { file: bTs.path }
});
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
arguments: { file: cTs.path }
});
session.executeCommandSeq<ts.server.protocol.GetSupportedCodeFixesRequest>({
command: ts.server.protocol.CommandTypes.GetSupportedCodeFixes,
arguments: { projectFileName: config.path }
});
baselineTsserverLogs("plugins", "getSupportedCodeFixes can be proxied", session);
});
});
+3 -1
View File
@@ -691,6 +691,7 @@ declare namespace ts {
*/
interface GetSupportedCodeFixesRequest extends Request {
command: CommandTypes.GetSupportedCodeFixes;
arguments?: Partial<FileRequestArgs>;
}
/**
* A response for GetSupportedCodeFixesRequest request.
@@ -10051,6 +10052,7 @@ declare namespace ts {
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
commentSelection(fileName: string, textRange: TextRange): TextChange[];
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
getSupportedCodeFixes(fileName?: string): readonly string[];
dispose(): void;
}
interface JsxClosingTagInfo {
@@ -11033,7 +11035,7 @@ declare namespace ts {
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
function getDefaultCompilerOptions(): CompilerOptions;
function getSupportedCodeFixes(): string[];
function getSupportedCodeFixes(): readonly string[];
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry, syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode): LanguageService;
+2 -1
View File
@@ -6191,6 +6191,7 @@ declare namespace ts {
toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[];
commentSelection(fileName: string, textRange: TextRange): TextChange[];
uncommentSelection(fileName: string, textRange: TextRange): TextChange[];
getSupportedCodeFixes(fileName?: string): readonly string[];
dispose(): void;
}
interface JsxClosingTagInfo {
@@ -7173,7 +7174,7 @@ declare namespace ts {
function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings;
function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string;
function getDefaultCompilerOptions(): CompilerOptions;
function getSupportedCodeFixes(): string[];
function getSupportedCodeFixes(): readonly string[];
function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile;
function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile;
function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry, syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode): LanguageService;