aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-04 15:42:29 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-04 15:42:29 +0000
commit88702a758f031f33452e9acac621841552ec9f8a (patch)
treefc1450350a842925120a7d0485f96eb973f54b08 /crates/ra_lsp_server/src/main_loop
parent13a2bdb0a89260e978ba8e55abd7a51a003e62a7 (diff)
parent0f7a714c6306e545157f3ef94fe8db5957007efa (diff)
Merge #738
738: Implement lens for impls and support resolving lenses. r=matklad a=kjeremy Closes #620 Co-authored-by: Jeremy Kolb <[email protected]> Co-authored-by: kjeremy <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs89
1 files changed, 87 insertions, 2 deletions
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};
10use ra_ide_api::{ 10use 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};
13use ra_syntax::{AstNode, TextUnit}; 13use ra_syntax::{AstNode, SyntaxKind, TextUnit};
14use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
15use serde::{Serialize, Deserialize};
15use serde_json::to_value; 16use serde_json::to_value;
16use std::io::Write; 17use std::io::Write;
18use url_serde::Ser;
17 19
18use crate::{ 20use 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")]
690enum CodeLensResolveData {
691 Impls(req::TextDocumentPositionParams),
692}
693
694pub 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
658pub fn handle_document_highlight( 743pub fn handle_document_highlight(
659 world: ServerWorld, 744 world: ServerWorld,
660 params: req::TextDocumentPositionParams, 745 params: req::TextDocumentPositionParams,