mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 15:14:32 +00:00
Merge #3299
3299: vscode: migrate to request type api r=matklad a=Veetaha More type-safety to the god of type-safety. Co-authored-by: Veetaha <gerzoh1@gmail.com>
This commit is contained in:
commit
5e6f4ca690
15 changed files with 202 additions and 197 deletions
|
@ -1,5 +1,6 @@
|
|||
import * as vscode from 'vscode';
|
||||
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
// Shows status of rust-analyzer (for debugging)
|
||||
|
@ -50,10 +51,7 @@ class TextDocumentContentProvider
|
|||
const client = this.ctx.client;
|
||||
if (!editor || !client) return '';
|
||||
|
||||
return client.sendRequest<string>(
|
||||
'rust-analyzer/analyzerStatus',
|
||||
null,
|
||||
);
|
||||
return client.sendRequest(ra.analyzerStatus, null);
|
||||
}
|
||||
|
||||
get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
|
@ -26,12 +26,7 @@ export function expandMacro(ctx: Ctx): Cmd {
|
|||
};
|
||||
}
|
||||
|
||||
interface ExpandedMacro {
|
||||
name: string;
|
||||
expansion: string;
|
||||
}
|
||||
|
||||
function codeFormat(expanded: ExpandedMacro): string {
|
||||
function codeFormat(expanded: ra.ExpandedMacro): string {
|
||||
let result = `// Recursive expansion of ${expanded.name}! macro\n`;
|
||||
result += '// ' + '='.repeat(result.length - 3);
|
||||
result += '\n\n';
|
||||
|
@ -54,14 +49,11 @@ class TextDocumentContentProvider
|
|||
if (!editor || !client) return '';
|
||||
|
||||
const position = editor.selection.active;
|
||||
const request: lc.TextDocumentPositionParams = {
|
||||
|
||||
const expanded = await client.sendRequest(ra.expandMacro, {
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
position,
|
||||
};
|
||||
const expanded = await client.sendRequest<ExpandedMacro>(
|
||||
'rust-analyzer/expandMacro',
|
||||
request,
|
||||
);
|
||||
});
|
||||
|
||||
if (expanded == null) return 'Not available';
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
import * as sourceChange from '../source_change';
|
||||
|
@ -16,9 +17,7 @@ export * from './ssr';
|
|||
export * from './server_version';
|
||||
|
||||
export function collectGarbage(ctx: Ctx): Cmd {
|
||||
return async () => {
|
||||
await ctx.client?.sendRequest<null>('rust-analyzer/collectGarbage', null);
|
||||
};
|
||||
return async () => ctx.client.sendRequest(ra.collectGarbage, null);
|
||||
}
|
||||
|
||||
export function showReferences(ctx: Ctx): Cmd {
|
||||
|
@ -36,13 +35,13 @@ export function showReferences(ctx: Ctx): Cmd {
|
|||
}
|
||||
|
||||
export function applySourceChange(ctx: Ctx): Cmd {
|
||||
return async (change: sourceChange.SourceChange) => {
|
||||
return async (change: ra.SourceChange) => {
|
||||
await sourceChange.applySourceChange(ctx, change);
|
||||
};
|
||||
}
|
||||
|
||||
export function selectAndApplySourceChange(ctx: Ctx): Cmd {
|
||||
return async (changes: sourceChange.SourceChange[]) => {
|
||||
return async (changes: ra.SourceChange[]) => {
|
||||
if (changes.length === 1) {
|
||||
await sourceChange.applySourceChange(ctx, changes[0]);
|
||||
} else if (changes.length > 0) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
import { applySourceChange, SourceChange } from '../source_change';
|
||||
import { applySourceChange } from '../source_change';
|
||||
|
||||
export function joinLines(ctx: Ctx): Cmd {
|
||||
return async () => {
|
||||
|
@ -9,19 +9,10 @@ export function joinLines(ctx: Ctx): Cmd {
|
|||
const client = ctx.client;
|
||||
if (!editor || !client) return;
|
||||
|
||||
const request: JoinLinesParams = {
|
||||
const change = await client.sendRequest(ra.joinLines, {
|
||||
range: client.code2ProtocolConverter.asRange(editor.selection),
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
};
|
||||
const change = await client.sendRequest<SourceChange>(
|
||||
'rust-analyzer/joinLines',
|
||||
request,
|
||||
);
|
||||
});
|
||||
await applySourceChange(ctx, change);
|
||||
};
|
||||
}
|
||||
|
||||
interface JoinLinesParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
range: lc.Range;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
|
@ -9,16 +9,12 @@ export function matchingBrace(ctx: Ctx): Cmd {
|
|||
const client = ctx.client;
|
||||
if (!editor || !client) return;
|
||||
|
||||
const request: FindMatchingBraceParams = {
|
||||
const response = await client.sendRequest(ra.findMatchingBrace, {
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
offsets: editor.selections.map(s =>
|
||||
client.code2ProtocolConverter.asPosition(s.active),
|
||||
),
|
||||
};
|
||||
const response = await client.sendRequest<lc.Position[]>(
|
||||
'rust-analyzer/findMatchingBrace',
|
||||
request,
|
||||
);
|
||||
});
|
||||
editor.selections = editor.selections.map((sel, idx) => {
|
||||
const active = client.protocol2CodeConverter.asPosition(
|
||||
response[idx],
|
||||
|
@ -29,8 +25,3 @@ export function matchingBrace(ctx: Ctx): Cmd {
|
|||
editor.revealRange(editor.selection);
|
||||
};
|
||||
}
|
||||
|
||||
interface FindMatchingBraceParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
offsets: lc.Position[];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { applySourceChange, SourceChange } from '../source_change';
|
||||
import { applySourceChange } from '../source_change';
|
||||
import { Cmd, Ctx } from '../ctx';
|
||||
|
||||
async function handleKeypress(ctx: Ctx) {
|
||||
|
@ -10,22 +10,15 @@ async function handleKeypress(ctx: Ctx) {
|
|||
|
||||
if (!editor || !client) return false;
|
||||
|
||||
const request: lc.TextDocumentPositionParams = {
|
||||
const change = await client.sendRequest(ra.onEnter, {
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
position: client.code2ProtocolConverter.asPosition(
|
||||
editor.selection.active,
|
||||
),
|
||||
};
|
||||
const change = await client.sendRequest<undefined | SourceChange>(
|
||||
'rust-analyzer/onEnter',
|
||||
request,
|
||||
).catch(
|
||||
(_error: any) => {
|
||||
// FIXME: switch to the more modern (?) typed request infrastructure
|
||||
// client.logFailedRequest(OnEnterRequest.type, error);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
);
|
||||
}).catch(_error => {
|
||||
// client.logFailedRequest(OnEnterRequest.type, error);
|
||||
return null;
|
||||
});
|
||||
if (!change) return false;
|
||||
|
||||
await applySourceChange(ctx, change);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
|
@ -9,16 +9,12 @@ export function parentModule(ctx: Ctx): Cmd {
|
|||
const client = ctx.client;
|
||||
if (!editor || !client) return;
|
||||
|
||||
const request: lc.TextDocumentPositionParams = {
|
||||
const response = await client.sendRequest(ra.parentModule, {
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
position: client.code2ProtocolConverter.asPosition(
|
||||
editor.selection.active,
|
||||
),
|
||||
};
|
||||
const response = await client.sendRequest<lc.Location[]>(
|
||||
'rust-analyzer/parentModule',
|
||||
request,
|
||||
);
|
||||
});
|
||||
const loc = response[0];
|
||||
if (loc == null) return;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
|
@ -14,16 +15,13 @@ export function run(ctx: Ctx): Cmd {
|
|||
const textDocument: lc.TextDocumentIdentifier = {
|
||||
uri: editor.document.uri.toString(),
|
||||
};
|
||||
const params: RunnablesParams = {
|
||||
|
||||
const runnables = await client.sendRequest(ra.runnables, {
|
||||
textDocument,
|
||||
position: client.code2ProtocolConverter.asPosition(
|
||||
editor.selection.active,
|
||||
),
|
||||
};
|
||||
const runnables = await client.sendRequest<Runnable[]>(
|
||||
'rust-analyzer/runnables',
|
||||
params,
|
||||
);
|
||||
});
|
||||
const items: RunnableQuickPick[] = [];
|
||||
if (prevRunnable) {
|
||||
items.push(prevRunnable);
|
||||
|
@ -48,7 +46,7 @@ export function run(ctx: Ctx): Cmd {
|
|||
}
|
||||
|
||||
export function runSingle(ctx: Ctx): Cmd {
|
||||
return async (runnable: Runnable) => {
|
||||
return async (runnable: ra.Runnable) => {
|
||||
const editor = ctx.activeRustEditor;
|
||||
if (!editor) return;
|
||||
|
||||
|
@ -64,26 +62,13 @@ export function runSingle(ctx: Ctx): Cmd {
|
|||
};
|
||||
}
|
||||
|
||||
interface RunnablesParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
position?: lc.Position;
|
||||
}
|
||||
|
||||
interface Runnable {
|
||||
label: string;
|
||||
bin: string;
|
||||
args: string[];
|
||||
env: { [index: string]: string };
|
||||
cwd?: string;
|
||||
}
|
||||
|
||||
class RunnableQuickPick implements vscode.QuickPickItem {
|
||||
public label: string;
|
||||
public description?: string | undefined;
|
||||
public detail?: string | undefined;
|
||||
public picked?: boolean | undefined;
|
||||
|
||||
constructor(public runnable: Runnable) {
|
||||
constructor(public runnable: ra.Runnable) {
|
||||
this.label = runnable.label;
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +81,7 @@ interface CargoTaskDefinition extends vscode.TaskDefinition {
|
|||
env?: { [key: string]: string };
|
||||
}
|
||||
|
||||
function createTask(spec: Runnable): vscode.Task {
|
||||
function createTask(spec: ra.Runnable): vscode.Task {
|
||||
const TASK_SOURCE = 'Rust';
|
||||
const definition: CargoTaskDefinition = {
|
||||
type: 'cargo',
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Ctx, Cmd } from '../ctx';
|
||||
import { applySourceChange, SourceChange } from '../source_change';
|
||||
import * as vscode from 'vscode';
|
||||
import * as ra from "../rust-analyzer-api";
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
import { applySourceChange } from '../source_change';
|
||||
|
||||
export function ssr(ctx: Ctx): Cmd {
|
||||
return async () => {
|
||||
|
@ -21,16 +23,8 @@ export function ssr(ctx: Ctx): Cmd {
|
|||
|
||||
if (!request) return;
|
||||
|
||||
const ssrRequest: SsrRequest = { arg: request };
|
||||
const change = await client.sendRequest<SourceChange>(
|
||||
'rust-analyzer/ssr',
|
||||
ssrRequest,
|
||||
);
|
||||
const change = await client.sendRequest(ra.ssr, { arg: request });
|
||||
|
||||
await applySourceChange(ctx, change);
|
||||
};
|
||||
}
|
||||
|
||||
interface SsrRequest {
|
||||
arg: string;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from '../rust-analyzer-api';
|
||||
|
||||
import { Ctx, Cmd } from '../ctx';
|
||||
|
||||
|
@ -61,13 +61,8 @@ function afterLs(f: () => void) {
|
|||
setTimeout(f, 10);
|
||||
}
|
||||
|
||||
interface SyntaxTreeParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
range?: lc.Range;
|
||||
}
|
||||
|
||||
class TextDocumentContentProvider
|
||||
implements vscode.TextDocumentContentProvider {
|
||||
class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
||||
uri = vscode.Uri.parse('rust-analyzer://syntaxtree');
|
||||
eventEmitter = new vscode.EventEmitter<vscode.Uri>();
|
||||
|
||||
|
@ -79,23 +74,15 @@ class TextDocumentContentProvider
|
|||
const client = this.ctx.client;
|
||||
if (!editor || !client) return '';
|
||||
|
||||
let range: lc.Range | undefined;
|
||||
|
||||
// When the range based query is enabled we take the range of the selection
|
||||
if (uri.query === 'range=true') {
|
||||
range = editor.selection.isEmpty
|
||||
? undefined
|
||||
: client.code2ProtocolConverter.asRange(editor.selection);
|
||||
}
|
||||
const range = uri.query === 'range=true' && !editor.selection.isEmpty
|
||||
? client.code2ProtocolConverter.asRange(editor.selection)
|
||||
: null;
|
||||
|
||||
const request: SyntaxTreeParams = {
|
||||
return client.sendRequest(ra.syntaxTree, {
|
||||
textDocument: { uri: editor.document.uri.toString() },
|
||||
range,
|
||||
};
|
||||
return client.sendRequest<string>(
|
||||
'rust-analyzer/syntaxTree',
|
||||
request,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from './rust-analyzer-api';
|
||||
|
||||
import { ColorTheme, TextMateRuleSettings } from './color_theme';
|
||||
|
||||
|
@ -8,29 +8,25 @@ import { sendRequestWithRetry } from './util';
|
|||
|
||||
export function activateHighlighting(ctx: Ctx) {
|
||||
const highlighter = new Highlighter(ctx);
|
||||
const client = ctx.client;
|
||||
if (client != null) {
|
||||
client.onNotification(
|
||||
'rust-analyzer/publishDecorations',
|
||||
(params: PublishDecorationsParams) => {
|
||||
if (!ctx.config.highlightingOn) return;
|
||||
|
||||
const targetEditor = vscode.window.visibleTextEditors.find(
|
||||
editor => {
|
||||
const unescapedUri = unescape(
|
||||
editor.document.uri.toString(),
|
||||
);
|
||||
// Unescaped URI looks like:
|
||||
// file:///c:/Workspace/ra-test/src/main.rs
|
||||
return unescapedUri === params.uri;
|
||||
},
|
||||
ctx.client.onNotification(ra.publishDecorations, params => {
|
||||
if (!ctx.config.highlightingOn) return;
|
||||
|
||||
const targetEditor = vscode.window.visibleTextEditors.find(
|
||||
editor => {
|
||||
const unescapedUri = unescape(
|
||||
editor.document.uri.toString(),
|
||||
);
|
||||
if (!targetEditor) return;
|
||||
|
||||
highlighter.setHighlights(targetEditor, params.decorations);
|
||||
// Unescaped URI looks like:
|
||||
// file:///c:/Workspace/ra-test/src/main.rs
|
||||
return unescapedUri === params.uri;
|
||||
},
|
||||
);
|
||||
}
|
||||
if (!targetEditor) return;
|
||||
|
||||
highlighter.setHighlights(targetEditor, params.decorations);
|
||||
});
|
||||
|
||||
|
||||
vscode.workspace.onDidChangeConfiguration(
|
||||
_ => highlighter.removeHighlights(),
|
||||
|
@ -45,13 +41,10 @@ export function activateHighlighting(ctx: Ctx) {
|
|||
const client = ctx.client;
|
||||
if (!client) return;
|
||||
|
||||
const params: lc.TextDocumentIdentifier = {
|
||||
uri: editor.document.uri.toString(),
|
||||
};
|
||||
const decorations = await sendRequestWithRetry<Decoration[]>(
|
||||
const decorations = await sendRequestWithRetry(
|
||||
client,
|
||||
'rust-analyzer/decorationsRequest',
|
||||
params,
|
||||
ra.decorationsRequest,
|
||||
{ uri: editor.document.uri.toString() },
|
||||
);
|
||||
highlighter.setHighlights(editor, decorations);
|
||||
},
|
||||
|
@ -60,17 +53,6 @@ export function activateHighlighting(ctx: Ctx) {
|
|||
);
|
||||
}
|
||||
|
||||
interface PublishDecorationsParams {
|
||||
uri: string;
|
||||
decorations: Decoration[];
|
||||
}
|
||||
|
||||
interface Decoration {
|
||||
range: lc.Range;
|
||||
tag: string;
|
||||
bindingHash?: string;
|
||||
}
|
||||
|
||||
// Based on this HSL-based color generator: https://gist.github.com/bendc/76c48ce53299e6078a76
|
||||
function fancify(seed: string, shade: 'light' | 'dark') {
|
||||
const random = randomU32Numbers(hashString(seed));
|
||||
|
@ -108,7 +90,7 @@ class Highlighter {
|
|||
this.decorations = null;
|
||||
}
|
||||
|
||||
public setHighlights(editor: vscode.TextEditor, highlights: Decoration[]) {
|
||||
public setHighlights(editor: vscode.TextEditor, highlights: ra.Decoration[]) {
|
||||
const client = this.ctx.client;
|
||||
if (!client) return;
|
||||
// Initialize decorations if necessary
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from './rust-analyzer-api';
|
||||
|
||||
import { Ctx } from './ctx';
|
||||
import { log, sendRequestWithRetry } from './util';
|
||||
|
@ -39,16 +39,6 @@ export function activateInlayHints(ctx: Ctx) {
|
|||
void hintsUpdater.setEnabled(ctx.config.displayInlayHints);
|
||||
}
|
||||
|
||||
interface InlayHintsParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
}
|
||||
|
||||
interface InlayHint {
|
||||
range: vscode.Range;
|
||||
kind: "TypeHint" | "ParameterHint";
|
||||
label: string;
|
||||
}
|
||||
|
||||
const typeHintDecorationType = vscode.window.createTextEditorDecorationType({
|
||||
after: {
|
||||
color: new vscode.ThemeColor('rust_analyzer.inlayHint'),
|
||||
|
@ -107,9 +97,9 @@ class HintsUpdater {
|
|||
if (newHints == null) return;
|
||||
|
||||
const newTypeDecorations = newHints
|
||||
.filter(hint => hint.kind === 'TypeHint')
|
||||
.filter(hint => hint.kind === ra.InlayKind.TypeHint)
|
||||
.map(hint => ({
|
||||
range: hint.range,
|
||||
range: this.ctx.client.protocol2CodeConverter.asRange(hint.range),
|
||||
renderOptions: {
|
||||
after: {
|
||||
contentText: `: ${hint.label}`,
|
||||
|
@ -119,9 +109,9 @@ class HintsUpdater {
|
|||
this.setTypeDecorations(editor, newTypeDecorations);
|
||||
|
||||
const newParameterDecorations = newHints
|
||||
.filter(hint => hint.kind === 'ParameterHint')
|
||||
.filter(hint => hint.kind === ra.InlayKind.ParameterHint)
|
||||
.map(hint => ({
|
||||
range: hint.range,
|
||||
range: this.ctx.client.protocol2CodeConverter.asRange(hint.range),
|
||||
renderOptions: {
|
||||
before: {
|
||||
contentText: `${hint.label}: `,
|
||||
|
@ -151,20 +141,15 @@ class HintsUpdater {
|
|||
);
|
||||
}
|
||||
|
||||
private async queryHints(documentUri: string): Promise<InlayHint[] | null> {
|
||||
private async queryHints(documentUri: string): Promise<ra.InlayHint[] | null> {
|
||||
this.pending.get(documentUri)?.cancel();
|
||||
|
||||
const tokenSource = new vscode.CancellationTokenSource();
|
||||
this.pending.set(documentUri, tokenSource);
|
||||
|
||||
const request: InlayHintsParams = { textDocument: { uri: documentUri } };
|
||||
const request = { textDocument: { uri: documentUri } };
|
||||
|
||||
return sendRequestWithRetry<InlayHint[]>(
|
||||
this.ctx.client,
|
||||
'rust-analyzer/inlayHints',
|
||||
request,
|
||||
tokenSource.token
|
||||
)
|
||||
return sendRequestWithRetry(this.ctx.client, ra.inlayHints, request, tokenSource.token)
|
||||
.catch(_ => null)
|
||||
.finally(() => {
|
||||
if (!tokenSource.token.isCancellationRequested) {
|
||||
|
|
117
editors/code/src/rust-analyzer-api.ts
Normal file
117
editors/code/src/rust-analyzer-api.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* This file mirrors `crates/rust-analyzer/src/req.rs` declarations.
|
||||
*/
|
||||
|
||||
import * as lc from "vscode-languageclient";
|
||||
|
||||
type Option<T> = null | T;
|
||||
type Vec<T> = T[];
|
||||
type FxHashMap<K extends PropertyKey, V> = Record<K, V>;
|
||||
|
||||
function request<TParams, TResult>(method: string) {
|
||||
return new lc.RequestType<TParams, TResult, unknown>(`rust-analyzer/${method}`);
|
||||
}
|
||||
function notification<TParam>(method: string) {
|
||||
return new lc.NotificationType<TParam>(method);
|
||||
}
|
||||
|
||||
|
||||
export const analyzerStatus = request<null, string>("analyzerStatus");
|
||||
|
||||
|
||||
export const collectGarbage = request<null, null>("collectGarbage");
|
||||
|
||||
|
||||
export interface SyntaxTreeParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
range: Option<lc.Range>;
|
||||
}
|
||||
export const syntaxTree = request<SyntaxTreeParams, string>("syntaxTree");
|
||||
|
||||
|
||||
export interface ExpandMacroParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
position: Option<lc.Position>;
|
||||
}
|
||||
export interface ExpandedMacro {
|
||||
name: string;
|
||||
expansion: string;
|
||||
}
|
||||
export const expandMacro = request<ExpandMacroParams, Option<ExpandedMacro>>("expandMacro");
|
||||
|
||||
|
||||
export interface FindMatchingBraceParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
offsets: Vec<lc.Position>;
|
||||
}
|
||||
export const findMatchingBrace = request<FindMatchingBraceParams, Vec<lc.Position>>("findMatchingBrace");
|
||||
|
||||
|
||||
export interface PublishDecorationsParams {
|
||||
uri: string;
|
||||
decorations: Vec<Decoration>;
|
||||
}
|
||||
export interface Decoration {
|
||||
range: lc.Range;
|
||||
tag: string;
|
||||
bindingHash: Option<string>;
|
||||
}
|
||||
export const decorationsRequest = request<lc.TextDocumentIdentifier, Vec<Decoration>>("decorationsRequest");
|
||||
|
||||
|
||||
export const parentModule = request<lc.TextDocumentPositionParams, Vec<lc.Location>>("parentModule");
|
||||
|
||||
|
||||
export interface JoinLinesParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
range: lc.Range;
|
||||
}
|
||||
export const joinLines = request<JoinLinesParams, SourceChange>("joinLines");
|
||||
|
||||
|
||||
export const onEnter = request<lc.TextDocumentPositionParams, Option<SourceChange>>("onEnter");
|
||||
|
||||
export interface RunnablesParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
position: Option<lc.Position>;
|
||||
}
|
||||
export interface Runnable {
|
||||
range: lc.Range;
|
||||
label: string;
|
||||
bin: string;
|
||||
args: Vec<string>;
|
||||
env: FxHashMap<string, string>;
|
||||
cwd: Option<string>;
|
||||
}
|
||||
export const runnables = request<RunnablesParams, Vec<Runnable>>("runnables");
|
||||
|
||||
|
||||
export const enum InlayKind {
|
||||
TypeHint = "TypeHint",
|
||||
ParameterHint = "ParameterHint",
|
||||
}
|
||||
export interface InlayHint {
|
||||
range: lc.Range;
|
||||
kind: InlayKind;
|
||||
label: string;
|
||||
}
|
||||
export interface InlayHintsParams {
|
||||
textDocument: lc.TextDocumentIdentifier;
|
||||
}
|
||||
export const inlayHints = request<InlayHintsParams, Vec<InlayHint>>("inlayHints");
|
||||
|
||||
|
||||
export interface SsrParams {
|
||||
arg: string;
|
||||
}
|
||||
export const ssr = request<SsrParams, SourceChange>("ssr");
|
||||
|
||||
|
||||
export const publishDecorations = notification<PublishDecorationsParams>("publishDecorations");
|
||||
|
||||
|
||||
export interface SourceChange {
|
||||
label: string;
|
||||
workspaceEdit: lc.WorkspaceEdit;
|
||||
cursorPosition: Option<lc.TextDocumentPositionParams>;
|
||||
}
|
|
@ -1,15 +1,10 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as lc from 'vscode-languageclient';
|
||||
import * as ra from './rust-analyzer-api';
|
||||
|
||||
import { Ctx } from './ctx';
|
||||
|
||||
export interface SourceChange {
|
||||
label: string;
|
||||
workspaceEdit: lc.WorkspaceEdit;
|
||||
cursorPosition?: lc.TextDocumentPositionParams;
|
||||
}
|
||||
|
||||
export async function applySourceChange(ctx: Ctx, change: SourceChange) {
|
||||
export async function applySourceChange(ctx: Ctx, change: ra.SourceChange) {
|
||||
const client = ctx.client;
|
||||
if (!client) return;
|
||||
|
||||
|
|
|
@ -20,21 +20,21 @@ export const log = {
|
|||
}
|
||||
};
|
||||
|
||||
export async function sendRequestWithRetry<R>(
|
||||
export async function sendRequestWithRetry<TParam, TRet>(
|
||||
client: lc.LanguageClient,
|
||||
method: string,
|
||||
param: unknown,
|
||||
reqType: lc.RequestType<TParam, TRet, unknown>,
|
||||
param: TParam,
|
||||
token?: vscode.CancellationToken,
|
||||
): Promise<R> {
|
||||
): Promise<TRet> {
|
||||
for (const delay of [2, 4, 6, 8, 10, null]) {
|
||||
try {
|
||||
return await (token
|
||||
? client.sendRequest(method, param, token)
|
||||
: client.sendRequest(method, param)
|
||||
? client.sendRequest(reqType, param, token)
|
||||
: client.sendRequest(reqType, param)
|
||||
);
|
||||
} catch (error) {
|
||||
if (delay === null) {
|
||||
log.error("LSP request timed out", { method, param, error });
|
||||
log.error("LSP request timed out", { method: reqType.method, param, error });
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ export async function sendRequestWithRetry<R>(
|
|||
}
|
||||
|
||||
if (error.code !== lc.ErrorCodes.ContentModified) {
|
||||
log.error("LSP request failed", { method, param, error });
|
||||
log.error("LSP request failed", { method: reqType.method, param, error });
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue