aboutsummaryrefslogtreecommitdiff
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
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]>
-rw-r--r--crates/ra_lsp_server/src/caps.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs1
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs89
-rw-r--r--editors/code/src/extension.ts12
4 files changed, 101 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};
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,
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts
index 0b2a6095b..a0be70202 100644
--- a/editors/code/src/extension.ts
+++ b/editors/code/src/extension.ts
@@ -70,6 +70,18 @@ export function activate(context: vscode.ExtensionContext) {
70 'rust-analyzer.applySourceChange', 70 'rust-analyzer.applySourceChange',
71 commands.applySourceChange.handle 71 commands.applySourceChange.handle
72 ); 72 );
73 registerCommand(
74 'rust-analyzer.showReferences',
75 (uri: string, position: lc.Position, locations: lc.Location[]) => {
76 vscode.commands.executeCommand(
77 'editor.action.showReferences',
78 vscode.Uri.parse(uri),
79 Server.client.protocol2CodeConverter.asPosition(position),
80 locations.map(Server.client.protocol2CodeConverter.asLocation)
81 );
82 }
83 );
84
73 overrideCommand('type', commands.onEnter.handle); 85 overrideCommand('type', commands.onEnter.handle);
74 86
75 // Notifications are events triggered by the language server 87 // Notifications are events triggered by the language server