Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/compiler"
---

[LSP] Fix code fixes often not running when selected
4 changes: 0 additions & 4 deletions packages/compiler/src/server/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@ export const serverOptions: CompilerOptions = {
docs: true,
},
};

export const Commands = {
APPLY_CODE_FIX: "typespec.applyCodeFix",
};
2 changes: 1 addition & 1 deletion packages/compiler/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ function main() {
connection.onHover(profile(s.getHover));
connection.onSignatureHelp(profile(s.getSignatureHelp));
connection.onCodeAction(profile(s.getCodeActions));
connection.onExecuteCommand(profile(s.executeCommand));
connection.onCodeActionResolve(profile(s.resolveCodeAction));
connection.languages.semanticTokens.on(profile(s.buildSemanticTokens));
connection.workspace.onDidRenameFiles(profile(s.renameFiles));

Expand Down
50 changes: 21 additions & 29 deletions packages/compiler/src/server/serverlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
DocumentHighlightParams,
DocumentSymbol,
DocumentSymbolParams,
ExecuteCommandParams,
FileChangeType,
FoldingRange,
FoldingRangeParams,
Expand Down Expand Up @@ -104,7 +103,6 @@ import { getSemanticTokens } from "./classify.js";
import { ClientConfigProvider } from "./client-config-provider.js";
import { createCompileService } from "./compile-service.js";
import { resolveCompletion } from "./completion.js";
import { Commands } from "./constants.js";
import { convertDiagnosticToLsp } from "./diagnostics.js";
import { createFileService } from "./file-service.js";
import { createFileSystemCache } from "./file-system-cache.js";
Expand Down Expand Up @@ -177,7 +175,7 @@ export function createServer(
log,
clientConfigsProvider,
});
const currentDiagnosticIndex = new Map<number, Diagnostic>();
let currentDiagnosticIndex = new Map<number, Diagnostic>();
let diagnosticIdCounter = 0;

let workspaceFolders: ServerWorkspaceFolder[] = [];
Expand Down Expand Up @@ -214,7 +212,7 @@ export function createServer(
getSignatureHelp,
getDocumentSymbols,
getCodeActions,
executeCommand,
resolveCodeAction,
log,
reportDiagnostics,

Expand Down Expand Up @@ -283,9 +281,7 @@ export function createServer(
},
codeActionProvider: {
codeActionKinds: ["quickfix"],
},
executeCommandProvider: {
commands: [Commands.APPLY_CODE_FIX],
resolveProvider: true,
},
};

Expand Down Expand Up @@ -716,7 +712,7 @@ export function createServer(
if (!document) return undefined;
if (isTspConfigFile(document)) return undefined;

currentDiagnosticIndex.clear();
const newDiagnosticIndex = new Map<number, Diagnostic>();
// Group diagnostics by file.
//
// Initialize diagnostics for all source files in program to empty array
Expand Down Expand Up @@ -789,10 +785,14 @@ export function createServer(
"Diagnostic reported against a source file that was not added to the program.",
);
diagnostics.push(diagnostic);
currentDiagnosticIndex.set(diagnostic.data.id, each);
newDiagnosticIndex.set(diagnostic.data.id, each);
}
}

// Atomically swap the diagnostic index so that in-flight code action resolves
// referencing old diagnostic IDs can still find their entries until new diagnostics are sent.
currentDiagnosticIndex = newDiagnosticIndex;

for (const [document, diagnostics] of diagnosticMap) {
sendDiagnostics(document, diagnostics);
}
Expand Down Expand Up @@ -1303,16 +1303,10 @@ export function createServer(

for (const fix of tspDiag.codefixes ?? []) {
const codeAction: CodeAction = {
...CodeAction.create(
fix.label,
{
title: fix.label,
command: Commands.APPLY_CODE_FIX,
arguments: [params.textDocument.uri, vsDiag.data?.id, fix.id],
},
CodeActionKind.QuickFix,
),
title: fix.label,
kind: CodeActionKind.QuickFix,
diagnostics: [vsDiag],
data: { diagId: vsDiag.data?.id, fixId: fix.id },
};
actions.push(codeAction);
}
Expand All @@ -1321,19 +1315,17 @@ export function createServer(
return actions;
}

async function executeCommand(params: ExecuteCommandParams) {
if (params.command === Commands.APPLY_CODE_FIX) {
const [, diagId, fixId] = params.arguments ?? [];
if (diagId && fixId) {
const diag = currentDiagnosticIndex.get(diagId);
const codeFix = diag?.codefixes?.find((x) => x.id === fixId);
if (codeFix) {
const edits = await resolveCodeFix(codeFix);
const vsEdits = convertCodeFixEdits(edits);
await host.applyEdit({ documentChanges: vsEdits });
}
async function resolveCodeAction(codeAction: CodeAction): Promise<CodeAction> {
const { diagId, fixId } = codeAction.data ?? {};
if (diagId !== undefined && fixId) {
const diag = currentDiagnosticIndex.get(diagId);
const codeFix = diag?.codefixes?.find((x) => x.id === fixId);
if (codeFix) {
const edits = await resolveCodeFix(codeFix);
codeAction.edit = { documentChanges: convertCodeFixEdits(edits) };
}
}
return codeAction;
}

function convertCodeFixEdits(edits: CodeFixEdit[]) {
Expand Down
3 changes: 1 addition & 2 deletions packages/compiler/src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
DocumentHighlightParams,
DocumentSymbol,
DocumentSymbolParams,
ExecuteCommandParams,
FoldingRange,
FoldingRangeParams,
Hover,
Expand Down Expand Up @@ -126,7 +125,7 @@ export interface Server {
documentClosed(change: TextDocumentChangeEvent<TextDocument>): void;
documentOpened(change: TextDocumentChangeEvent<TextDocument>): void;
getCodeActions(params: CodeActionParams): Promise<CodeAction[]>;
executeCommand(params: ExecuteCommandParams): Promise<void>;
resolveCodeAction(codeAction: CodeAction): Promise<CodeAction>;
reportDiagnostics({ program, document, optionsFromConfig }: CompileResult): void;
log(log: ServerLog): void;

Expand Down
Loading