]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/src/lsp_ext.rs
Auto merge of #13320 - Veykril:ty-alias-hover, r=Veykril
[rust.git] / crates / rust-analyzer / src / lsp_ext.rs
1 //! rust-analyzer extensions to the LSP.
2
3 use std::{collections::HashMap, path::PathBuf};
4
5 use lsp_types::request::Request;
6 use lsp_types::{
7     notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
8     PartialResultParams, Position, Range, TextDocumentIdentifier, WorkDoneProgressParams,
9 };
10 use serde::{Deserialize, Serialize};
11
12 pub enum AnalyzerStatus {}
13
14 impl Request for AnalyzerStatus {
15     type Params = AnalyzerStatusParams;
16     type Result = String;
17     const METHOD: &'static str = "rust-analyzer/analyzerStatus";
18 }
19
20 #[derive(Deserialize, Serialize, Debug)]
21 #[serde(rename_all = "camelCase")]
22 pub struct AnalyzerStatusParams {
23     pub text_document: Option<TextDocumentIdentifier>,
24 }
25
26 pub enum MemoryUsage {}
27
28 impl Request for MemoryUsage {
29     type Params = ();
30     type Result = String;
31     const METHOD: &'static str = "rust-analyzer/memoryUsage";
32 }
33
34 pub enum ShuffleCrateGraph {}
35
36 impl Request for ShuffleCrateGraph {
37     type Params = ();
38     type Result = ();
39     const METHOD: &'static str = "rust-analyzer/shuffleCrateGraph";
40 }
41
42 pub enum ReloadWorkspace {}
43
44 impl Request for ReloadWorkspace {
45     type Params = ();
46     type Result = ();
47     const METHOD: &'static str = "rust-analyzer/reloadWorkspace";
48 }
49
50 pub enum SyntaxTree {}
51
52 impl Request for SyntaxTree {
53     type Params = SyntaxTreeParams;
54     type Result = String;
55     const METHOD: &'static str = "rust-analyzer/syntaxTree";
56 }
57
58 #[derive(Deserialize, Serialize, Debug)]
59 #[serde(rename_all = "camelCase")]
60 pub struct SyntaxTreeParams {
61     pub text_document: TextDocumentIdentifier,
62     pub range: Option<Range>,
63 }
64
65 pub enum ViewHir {}
66
67 impl Request for ViewHir {
68     type Params = lsp_types::TextDocumentPositionParams;
69     type Result = String;
70     const METHOD: &'static str = "rust-analyzer/viewHir";
71 }
72
73 pub enum ViewFileText {}
74
75 impl Request for ViewFileText {
76     type Params = lsp_types::TextDocumentIdentifier;
77     type Result = String;
78     const METHOD: &'static str = "rust-analyzer/viewFileText";
79 }
80
81 #[derive(Deserialize, Serialize, Debug)]
82 #[serde(rename_all = "camelCase")]
83 pub struct ViewCrateGraphParams {
84     /// Include *all* crates, not just crates in the workspace.
85     pub full: bool,
86 }
87
88 pub enum ViewCrateGraph {}
89
90 impl Request for ViewCrateGraph {
91     type Params = ViewCrateGraphParams;
92     type Result = String;
93     const METHOD: &'static str = "rust-analyzer/viewCrateGraph";
94 }
95
96 #[derive(Deserialize, Serialize, Debug)]
97 #[serde(rename_all = "camelCase")]
98 pub struct ViewItemTreeParams {
99     pub text_document: TextDocumentIdentifier,
100 }
101
102 pub enum ViewItemTree {}
103
104 impl Request for ViewItemTree {
105     type Params = ViewItemTreeParams;
106     type Result = String;
107     const METHOD: &'static str = "rust-analyzer/viewItemTree";
108 }
109
110 pub enum ExpandMacro {}
111
112 impl Request for ExpandMacro {
113     type Params = ExpandMacroParams;
114     type Result = Option<ExpandedMacro>;
115     const METHOD: &'static str = "rust-analyzer/expandMacro";
116 }
117
118 #[derive(Deserialize, Serialize, Debug)]
119 #[serde(rename_all = "camelCase")]
120 pub struct ExpandMacroParams {
121     pub text_document: TextDocumentIdentifier,
122     pub position: Position,
123 }
124
125 #[derive(Deserialize, Serialize, Debug)]
126 #[serde(rename_all = "camelCase")]
127 pub struct ExpandedMacro {
128     pub name: String,
129     pub expansion: String,
130 }
131
132 pub enum CancelFlycheck {}
133
134 impl Request for CancelFlycheck {
135     type Params = ();
136     type Result = ();
137     const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
138 }
139
140 pub enum MatchingBrace {}
141
142 impl Request for MatchingBrace {
143     type Params = MatchingBraceParams;
144     type Result = Vec<Position>;
145     const METHOD: &'static str = "experimental/matchingBrace";
146 }
147
148 #[derive(Deserialize, Serialize, Debug)]
149 #[serde(rename_all = "camelCase")]
150 pub struct MatchingBraceParams {
151     pub text_document: TextDocumentIdentifier,
152     pub positions: Vec<Position>,
153 }
154
155 pub enum ParentModule {}
156
157 impl Request for ParentModule {
158     type Params = lsp_types::TextDocumentPositionParams;
159     type Result = Option<lsp_types::GotoDefinitionResponse>;
160     const METHOD: &'static str = "experimental/parentModule";
161 }
162
163 pub enum JoinLines {}
164
165 impl Request for JoinLines {
166     type Params = JoinLinesParams;
167     type Result = Vec<lsp_types::TextEdit>;
168     const METHOD: &'static str = "experimental/joinLines";
169 }
170
171 #[derive(Deserialize, Serialize, Debug)]
172 #[serde(rename_all = "camelCase")]
173 pub struct JoinLinesParams {
174     pub text_document: TextDocumentIdentifier,
175     pub ranges: Vec<Range>,
176 }
177
178 pub enum OnEnter {}
179
180 impl Request for OnEnter {
181     type Params = lsp_types::TextDocumentPositionParams;
182     type Result = Option<Vec<SnippetTextEdit>>;
183     const METHOD: &'static str = "experimental/onEnter";
184 }
185
186 pub enum Runnables {}
187
188 impl Request for Runnables {
189     type Params = RunnablesParams;
190     type Result = Vec<Runnable>;
191     const METHOD: &'static str = "experimental/runnables";
192 }
193
194 #[derive(Serialize, Deserialize, Debug)]
195 #[serde(rename_all = "camelCase")]
196 pub struct RunnablesParams {
197     pub text_document: TextDocumentIdentifier,
198     pub position: Option<Position>,
199 }
200
201 #[derive(Deserialize, Serialize, Debug)]
202 #[serde(rename_all = "camelCase")]
203 pub struct Runnable {
204     pub label: String,
205     #[serde(skip_serializing_if = "Option::is_none")]
206     pub location: Option<lsp_types::LocationLink>,
207     pub kind: RunnableKind,
208     pub args: CargoRunnable,
209 }
210
211 #[derive(Serialize, Deserialize, Debug)]
212 #[serde(rename_all = "lowercase")]
213 pub enum RunnableKind {
214     Cargo,
215 }
216
217 #[derive(Deserialize, Serialize, Debug)]
218 #[serde(rename_all = "camelCase")]
219 pub struct CargoRunnable {
220     // command to be executed instead of cargo
221     pub override_cargo: Option<String>,
222     #[serde(skip_serializing_if = "Option::is_none")]
223     pub workspace_root: Option<PathBuf>,
224     // command, --package and --lib stuff
225     pub cargo_args: Vec<String>,
226     // user-specified additional cargo args, like `--release`.
227     pub cargo_extra_args: Vec<String>,
228     // stuff after --
229     pub executable_args: Vec<String>,
230     #[serde(skip_serializing_if = "Option::is_none")]
231     pub expect_test: Option<bool>,
232 }
233
234 pub enum RelatedTests {}
235
236 impl Request for RelatedTests {
237     type Params = lsp_types::TextDocumentPositionParams;
238     type Result = Vec<TestInfo>;
239     const METHOD: &'static str = "rust-analyzer/relatedTests";
240 }
241
242 #[derive(Debug, Deserialize, Serialize)]
243 pub struct TestInfo {
244     pub runnable: Runnable,
245 }
246
247 #[derive(Serialize, Deserialize, Debug)]
248 #[serde(rename_all = "camelCase")]
249 pub struct InlayHintsParams {
250     pub text_document: TextDocumentIdentifier,
251     pub range: Option<lsp_types::Range>,
252 }
253
254 pub enum Ssr {}
255
256 impl Request for Ssr {
257     type Params = SsrParams;
258     type Result = lsp_types::WorkspaceEdit;
259     const METHOD: &'static str = "experimental/ssr";
260 }
261
262 #[derive(Debug, Deserialize, Serialize)]
263 #[serde(rename_all = "camelCase")]
264 pub struct SsrParams {
265     pub query: String,
266     pub parse_only: bool,
267
268     /// File position where SSR was invoked. Paths in `query` will be resolved relative to this
269     /// position.
270     #[serde(flatten)]
271     pub position: lsp_types::TextDocumentPositionParams,
272
273     /// Current selections. Search/replace will be restricted to these if non-empty.
274     pub selections: Vec<lsp_types::Range>,
275 }
276
277 pub enum ServerStatusNotification {}
278
279 impl Notification for ServerStatusNotification {
280     type Params = ServerStatusParams;
281     const METHOD: &'static str = "experimental/serverStatus";
282 }
283
284 #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)]
285 pub struct ServerStatusParams {
286     pub health: Health,
287     pub quiescent: bool,
288     pub message: Option<String>,
289 }
290
291 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
292 #[serde(rename_all = "camelCase")]
293 pub enum Health {
294     Ok,
295     Warning,
296     Error,
297 }
298
299 pub enum CodeActionRequest {}
300
301 impl Request for CodeActionRequest {
302     type Params = lsp_types::CodeActionParams;
303     type Result = Option<Vec<CodeAction>>;
304     const METHOD: &'static str = "textDocument/codeAction";
305 }
306
307 pub enum CodeActionResolveRequest {}
308 impl Request for CodeActionResolveRequest {
309     type Params = CodeAction;
310     type Result = CodeAction;
311     const METHOD: &'static str = "codeAction/resolve";
312 }
313
314 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
315 #[serde(rename_all = "camelCase")]
316 pub struct CodeAction {
317     pub title: String,
318     #[serde(skip_serializing_if = "Option::is_none")]
319     pub group: Option<String>,
320     #[serde(skip_serializing_if = "Option::is_none")]
321     pub kind: Option<CodeActionKind>,
322     #[serde(skip_serializing_if = "Option::is_none")]
323     pub command: Option<lsp_types::Command>,
324     #[serde(skip_serializing_if = "Option::is_none")]
325     pub edit: Option<SnippetWorkspaceEdit>,
326     #[serde(skip_serializing_if = "Option::is_none")]
327     pub is_preferred: Option<bool>,
328
329     #[serde(skip_serializing_if = "Option::is_none")]
330     pub data: Option<CodeActionData>,
331 }
332
333 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
334 #[serde(rename_all = "camelCase")]
335 pub struct CodeActionData {
336     pub code_action_params: lsp_types::CodeActionParams,
337     pub id: String,
338 }
339
340 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
341 #[serde(rename_all = "camelCase")]
342 pub struct SnippetWorkspaceEdit {
343     #[serde(skip_serializing_if = "Option::is_none")]
344     pub changes: Option<HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>,
345     #[serde(skip_serializing_if = "Option::is_none")]
346     pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>,
347     #[serde(skip_serializing_if = "Option::is_none")]
348     pub change_annotations:
349         Option<HashMap<lsp_types::ChangeAnnotationIdentifier, lsp_types::ChangeAnnotation>>,
350 }
351
352 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
353 #[serde(untagged, rename_all = "lowercase")]
354 pub enum SnippetDocumentChangeOperation {
355     Op(lsp_types::ResourceOp),
356     Edit(SnippetTextDocumentEdit),
357 }
358
359 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
360 #[serde(rename_all = "camelCase")]
361 pub struct SnippetTextDocumentEdit {
362     pub text_document: lsp_types::OptionalVersionedTextDocumentIdentifier,
363     pub edits: Vec<SnippetTextEdit>,
364 }
365
366 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
367 #[serde(rename_all = "camelCase")]
368 pub struct SnippetTextEdit {
369     pub range: Range,
370     pub new_text: String,
371     #[serde(skip_serializing_if = "Option::is_none")]
372     pub insert_text_format: Option<lsp_types::InsertTextFormat>,
373     /// The annotation id if this is an annotated
374     #[serde(skip_serializing_if = "Option::is_none")]
375     pub annotation_id: Option<lsp_types::ChangeAnnotationIdentifier>,
376 }
377
378 pub enum HoverRequest {}
379
380 impl Request for HoverRequest {
381     type Params = HoverParams;
382     type Result = Option<Hover>;
383     const METHOD: &'static str = "textDocument/hover";
384 }
385
386 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
387 #[serde(rename_all = "camelCase")]
388 pub struct HoverParams {
389     pub text_document: TextDocumentIdentifier,
390     pub position: PositionOrRange,
391
392     #[serde(flatten)]
393     pub work_done_progress_params: WorkDoneProgressParams,
394 }
395
396 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
397 #[serde(untagged)]
398 pub enum PositionOrRange {
399     Position(lsp_types::Position),
400     Range(lsp_types::Range),
401 }
402
403 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
404 pub struct Hover {
405     #[serde(flatten)]
406     pub hover: lsp_types::Hover,
407     #[serde(skip_serializing_if = "Vec::is_empty")]
408     pub actions: Vec<CommandLinkGroup>,
409 }
410
411 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
412 pub struct CommandLinkGroup {
413     #[serde(skip_serializing_if = "Option::is_none")]
414     pub title: Option<String>,
415     pub commands: Vec<CommandLink>,
416 }
417
418 // LSP v3.15 Command does not have a `tooltip` field, vscode supports one.
419 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
420 pub struct CommandLink {
421     #[serde(flatten)]
422     pub command: lsp_types::Command,
423     #[serde(skip_serializing_if = "Option::is_none")]
424     pub tooltip: Option<String>,
425 }
426
427 pub enum ExternalDocs {}
428
429 impl Request for ExternalDocs {
430     type Params = lsp_types::TextDocumentPositionParams;
431     type Result = Option<lsp_types::Url>;
432     const METHOD: &'static str = "experimental/externalDocs";
433 }
434
435 pub enum OpenCargoToml {}
436
437 impl Request for OpenCargoToml {
438     type Params = OpenCargoTomlParams;
439     type Result = Option<lsp_types::GotoDefinitionResponse>;
440     const METHOD: &'static str = "experimental/openCargoToml";
441 }
442
443 #[derive(Serialize, Deserialize, Debug)]
444 #[serde(rename_all = "camelCase")]
445 pub struct OpenCargoTomlParams {
446     pub text_document: TextDocumentIdentifier,
447 }
448
449 /// Information about CodeLens, that is to be resolved.
450 #[derive(Debug, Serialize, Deserialize)]
451 #[serde(rename_all = "camelCase")]
452 pub(crate) enum CodeLensResolveData {
453     Impls(lsp_types::request::GotoImplementationParams),
454     References(lsp_types::TextDocumentPositionParams),
455 }
456
457 pub fn supports_utf8(caps: &lsp_types::ClientCapabilities) -> bool {
458     caps.offset_encoding.as_deref().unwrap_or_default().iter().any(|it| it == "utf-8")
459 }
460
461 pub enum MoveItem {}
462
463 impl Request for MoveItem {
464     type Params = MoveItemParams;
465     type Result = Vec<SnippetTextEdit>;
466     const METHOD: &'static str = "experimental/moveItem";
467 }
468
469 #[derive(Serialize, Deserialize, Debug)]
470 #[serde(rename_all = "camelCase")]
471 pub struct MoveItemParams {
472     pub direction: MoveItemDirection,
473     pub text_document: TextDocumentIdentifier,
474     pub range: Range,
475 }
476
477 #[derive(Serialize, Deserialize, Debug)]
478 pub enum MoveItemDirection {
479     Up,
480     Down,
481 }
482
483 #[derive(Debug)]
484 pub enum WorkspaceSymbol {}
485
486 impl Request for WorkspaceSymbol {
487     type Params = WorkspaceSymbolParams;
488     type Result = Option<Vec<lsp_types::SymbolInformation>>;
489     const METHOD: &'static str = "workspace/symbol";
490 }
491
492 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
493 #[serde(rename_all = "camelCase")]
494 pub struct WorkspaceSymbolParams {
495     #[serde(flatten)]
496     pub partial_result_params: PartialResultParams,
497
498     #[serde(flatten)]
499     pub work_done_progress_params: WorkDoneProgressParams,
500
501     /// A non-empty query string
502     pub query: String,
503
504     pub search_scope: Option<WorkspaceSymbolSearchScope>,
505
506     pub search_kind: Option<WorkspaceSymbolSearchKind>,
507 }
508
509 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
510 #[serde(rename_all = "camelCase")]
511 pub enum WorkspaceSymbolSearchScope {
512     Workspace,
513     WorkspaceAndDependencies,
514 }
515
516 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
517 #[serde(rename_all = "camelCase")]
518 pub enum WorkspaceSymbolSearchKind {
519     OnlyTypes,
520     AllSymbols,
521 }
522
523 /// The document on type formatting request is sent from the client to
524 /// the server to format parts of the document during typing.  This is
525 /// almost same as lsp_types::request::OnTypeFormatting, but the
526 /// result has SnippetTextEdit in it instead of TextEdit.
527 #[derive(Debug)]
528 pub enum OnTypeFormatting {}
529
530 impl Request for OnTypeFormatting {
531     type Params = DocumentOnTypeFormattingParams;
532     type Result = Option<Vec<SnippetTextEdit>>;
533     const METHOD: &'static str = "textDocument/onTypeFormatting";
534 }
535
536 #[derive(Debug, Serialize, Deserialize)]
537 pub struct CompletionResolveData {
538     pub position: lsp_types::TextDocumentPositionParams,
539     pub imports: Vec<CompletionImport>,
540 }
541
542 #[derive(Debug, Serialize, Deserialize)]
543 pub struct InlayHintResolveData {
544     pub text_document: TextDocumentIdentifier,
545     pub position: PositionOrRange,
546 }
547
548 #[derive(Debug, Serialize, Deserialize)]
549 pub struct CompletionImport {
550     pub full_import_path: String,
551     pub imported_name: String,
552 }
553
554 #[derive(Debug, Deserialize, Default)]
555 pub struct ClientCommandOptions {
556     pub commands: Vec<String>,
557 }