aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Kolb <[email protected]>2019-02-01 13:44:23 +0000
committerkjeremy <[email protected]>2019-02-04 13:45:33 +0000
commit6ac4cca6c1fc188ae0fda62fb81a9855a51b7530 (patch)
treeff72e9d32f18489fcef72d4ae7d1882d53540748
parent13a2bdb0a89260e978ba8e55abd7a51a003e62a7 (diff)
Implement lens for impls and support resolving lenses.
-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.rs85
-rw-r--r--editors/code/src/extension.ts12
4 files changed, 97 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..946992e15 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},
@@ -616,6 +618,7 @@ pub fn handle_code_lens(
616 618
617 let mut lenses: Vec<CodeLens> = Default::default(); 619 let mut lenses: Vec<CodeLens> = Default::default();
618 620
621 // Gather runnables
619 for runnable in world.analysis().runnables(file_id)? { 622 for runnable in world.analysis().runnables(file_id)? {
620 let title = match &runnable.kind { 623 let title = match &runnable.kind {
621 RunnableKind::Test { name: _ } | RunnableKind::TestMod { path: _ } => { 624 RunnableKind::Test { name: _ } | RunnableKind::TestMod { path: _ } => {
@@ -652,9 +655,87 @@ pub fn handle_code_lens(
652 } 655 }
653 } 656 }
654 657
658 // Handle impls
659 lenses.extend(
660 world
661 .analysis()
662 .file_structure(file_id)
663 .into_iter()
664 .filter(|it| match it.kind {
665 SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true,
666 _ => false,
667 })
668 .map(|it| {
669 let range = it.node_range.conv_with(&line_index);
670 let pos = range.start;
671 let lens_params =
672 req::TextDocumentPositionParams::new(params.text_document.clone(), pos);
673 CodeLens {
674 range,
675 command: None,
676 data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()),
677 }
678 }),
679 );
680
655 return Ok(Some(lenses)); 681 return Ok(Some(lenses));
656} 682}
657 683
684#[derive(Debug, Serialize, Deserialize)]
685#[serde(rename_all = "camelCase")]
686enum CodeLensResolveData {
687 Impls(req::TextDocumentPositionParams),
688}
689
690pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Result<CodeLens> {
691 let data = code_lens.data.unwrap();
692 let resolve = serde_json::from_value(data)?;
693 match resolve {
694 Some(CodeLensResolveData::Impls(lens_params)) => {
695 let locations: Vec<Location> =
696 match handle_goto_implementation(world, lens_params.clone())? {
697 Some(req::GotoDefinitionResponse::Scalar(loc)) => vec![loc],
698 Some(req::GotoDefinitionResponse::Array(locs)) => locs,
699 Some(req::GotoDefinitionResponse::Link(links)) => links
700 .into_iter()
701 .map(|link| Location::new(link.target_uri, link.target_selection_range))
702 .collect(),
703 _ => vec![],
704 };
705
706 let title = if locations.len() == 1 {
707 "1 implementation".into()
708 } else {
709 format!("{} implementations", locations.len())
710 };
711
712 return Ok(CodeLens {
713 range: code_lens.range,
714 command: Some(Command {
715 title,
716 command: "rust-analyzer.showReferences".into(),
717 arguments: Some(vec![
718 to_value(&Ser::new(&lens_params.text_document.uri)).unwrap(),
719 to_value(code_lens.range.start).unwrap(),
720 to_value(locations).unwrap(),
721 ]),
722 }),
723 data: None,
724 });
725 }
726 _ => {
727 return Ok(CodeLens {
728 range: code_lens.range,
729 command: Some(Command {
730 title: "Error".into(),
731 ..Default::default()
732 }),
733 data: None,
734 });
735 }
736 }
737}
738
658pub fn handle_document_highlight( 739pub fn handle_document_highlight(
659 world: ServerWorld, 740 world: ServerWorld,
660 params: req::TextDocumentPositionParams, 741 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