diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/caps.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 89 |
3 files changed, 89 insertions, 3 deletions
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 254624487..39992788d 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs | |||
@@ -33,7 +33,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
33 | workspace_symbol_provider: Some(true), | 33 | workspace_symbol_provider: Some(true), |
34 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), | 34 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), |
35 | code_lens_provider: Some(CodeLensOptions { | 35 | code_lens_provider: Some(CodeLensOptions { |
36 | resolve_provider: None, | 36 | resolve_provider: Some(true), |
37 | }), | 37 | }), |
38 | document_formatting_provider: Some(true), | 38 | document_formatting_provider: Some(true), |
39 | document_range_formatting_provider: None, | 39 | document_range_formatting_provider: None, |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index df390c19e..26b6fe54a 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -312,6 +312,7 @@ fn on_request( | |||
312 | .on::<req::Completion>(handlers::handle_completion)? | 312 | .on::<req::Completion>(handlers::handle_completion)? |
313 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? | 313 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? |
314 | .on::<req::CodeLensRequest>(handlers::handle_code_lens)? | 314 | .on::<req::CodeLensRequest>(handlers::handle_code_lens)? |
315 | .on::<req::CodeLensResolve>(handlers::handle_code_lens_resolve)? | ||
315 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? | 316 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? |
316 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? | 317 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? |
317 | .on::<req::HoverRequest>(handlers::handle_hover)? | 318 | .on::<req::HoverRequest>(handlers::handle_hover)? |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 0bec57e84..9e2cc8ffc 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -5,15 +5,17 @@ use lsp_types::{ | |||
5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, | 5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, |
6 | MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, | 6 | MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, |
7 | RenameParams, SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, | 7 | RenameParams, SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, |
8 | WorkspaceEdit | 8 | WorkspaceEdit, |
9 | }; | 9 | }; |
10 | use ra_ide_api::{ | 10 | use ra_ide_api::{ |
11 | FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, RunnableKind, Severity, Cancelable, | 11 | FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, RunnableKind, Severity, Cancelable, |
12 | }; | 12 | }; |
13 | use ra_syntax::{AstNode, TextUnit}; | 13 | use ra_syntax::{AstNode, SyntaxKind, TextUnit}; |
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
15 | use serde::{Serialize, Deserialize}; | ||
15 | use serde_json::to_value; | 16 | use serde_json::to_value; |
16 | use std::io::Write; | 17 | use std::io::Write; |
18 | use url_serde::Ser; | ||
17 | 19 | ||
18 | use crate::{ | 20 | use crate::{ |
19 | cargo_target_spec::{runnable_args, CargoTargetSpec}, | 21 | cargo_target_spec::{runnable_args, CargoTargetSpec}, |
@@ -596,6 +598,10 @@ pub fn handle_code_action( | |||
596 | for source_edit in assists.chain(fixes) { | 598 | for source_edit in assists.chain(fixes) { |
597 | let title = source_edit.label.clone(); | 599 | let title = source_edit.label.clone(); |
598 | let edit = source_edit.try_conv_with(&world)?; | 600 | let edit = source_edit.try_conv_with(&world)?; |
601 | |||
602 | // We cannot use the 'editor.action.showReferences' command directly | ||
603 | // because that command requires vscode types which we convert in the handler | ||
604 | // on the client side. | ||
599 | let cmd = Command { | 605 | let cmd = Command { |
600 | title, | 606 | title, |
601 | command: "rust-analyzer.applySourceChange".to_string(), | 607 | command: "rust-analyzer.applySourceChange".to_string(), |
@@ -616,6 +622,7 @@ pub fn handle_code_lens( | |||
616 | 622 | ||
617 | let mut lenses: Vec<CodeLens> = Default::default(); | 623 | let mut lenses: Vec<CodeLens> = Default::default(); |
618 | 624 | ||
625 | // Gather runnables | ||
619 | for runnable in world.analysis().runnables(file_id)? { | 626 | for runnable in world.analysis().runnables(file_id)? { |
620 | let title = match &runnable.kind { | 627 | let title = match &runnable.kind { |
621 | RunnableKind::Test { name: _ } | RunnableKind::TestMod { path: _ } => { | 628 | RunnableKind::Test { name: _ } | RunnableKind::TestMod { path: _ } => { |
@@ -652,9 +659,87 @@ pub fn handle_code_lens( | |||
652 | } | 659 | } |
653 | } | 660 | } |
654 | 661 | ||
662 | // Handle impls | ||
663 | lenses.extend( | ||
664 | world | ||
665 | .analysis() | ||
666 | .file_structure(file_id) | ||
667 | .into_iter() | ||
668 | .filter(|it| match it.kind { | ||
669 | SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, | ||
670 | _ => false, | ||
671 | }) | ||
672 | .map(|it| { | ||
673 | let range = it.node_range.conv_with(&line_index); | ||
674 | let pos = range.start; | ||
675 | let lens_params = | ||
676 | req::TextDocumentPositionParams::new(params.text_document.clone(), pos); | ||
677 | CodeLens { | ||
678 | range, | ||
679 | command: None, | ||
680 | data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), | ||
681 | } | ||
682 | }), | ||
683 | ); | ||
684 | |||
655 | return Ok(Some(lenses)); | 685 | return Ok(Some(lenses)); |
656 | } | 686 | } |
657 | 687 | ||
688 | #[derive(Debug, Serialize, Deserialize)] | ||
689 | #[serde(rename_all = "camelCase")] | ||
690 | enum CodeLensResolveData { | ||
691 | Impls(req::TextDocumentPositionParams), | ||
692 | } | ||
693 | |||
694 | pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Result<CodeLens> { | ||
695 | let data = code_lens.data.unwrap(); | ||
696 | let resolve = serde_json::from_value(data)?; | ||
697 | match resolve { | ||
698 | Some(CodeLensResolveData::Impls(lens_params)) => { | ||
699 | let locations: Vec<Location> = | ||
700 | match handle_goto_implementation(world, lens_params.clone())? { | ||
701 | Some(req::GotoDefinitionResponse::Scalar(loc)) => vec![loc], | ||
702 | Some(req::GotoDefinitionResponse::Array(locs)) => locs, | ||
703 | Some(req::GotoDefinitionResponse::Link(links)) => links | ||
704 | .into_iter() | ||
705 | .map(|link| Location::new(link.target_uri, link.target_selection_range)) | ||
706 | .collect(), | ||
707 | _ => vec![], | ||
708 | }; | ||
709 | |||
710 | let title = if locations.len() == 1 { | ||
711 | "1 implementation".into() | ||
712 | } else { | ||
713 | format!("{} implementations", locations.len()) | ||
714 | }; | ||
715 | |||
716 | return Ok(CodeLens { | ||
717 | range: code_lens.range, | ||
718 | command: Some(Command { | ||
719 | title, | ||
720 | command: "rust-analyzer.showReferences".into(), | ||
721 | arguments: Some(vec![ | ||
722 | to_value(&Ser::new(&lens_params.text_document.uri)).unwrap(), | ||
723 | to_value(code_lens.range.start).unwrap(), | ||
724 | to_value(locations).unwrap(), | ||
725 | ]), | ||
726 | }), | ||
727 | data: None, | ||
728 | }); | ||
729 | } | ||
730 | _ => { | ||
731 | return Ok(CodeLens { | ||
732 | range: code_lens.range, | ||
733 | command: Some(Command { | ||
734 | title: "Error".into(), | ||
735 | ..Default::default() | ||
736 | }), | ||
737 | data: None, | ||
738 | }); | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | |||
658 | pub fn handle_document_highlight( | 743 | pub fn handle_document_highlight( |
659 | world: ServerWorld, | 744 | world: ServerWorld, |
660 | params: req::TextDocumentPositionParams, | 745 | params: req::TextDocumentPositionParams, |