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