diff options
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_self.snap | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 6 | ||||
-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 | ||||
-rw-r--r-- | editors/code/src/extension.ts | 12 |
6 files changed, 114 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_self.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_self.snap index 84c8b1e90..5c927f5c1 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_self.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_self.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:45:00.052694700+00:00" | 2 | created: "2019-02-04T19:40:48.826936500+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.3 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: crates/ra_hir/src/ty/tests.rs |
6 | --- | 6 | --- |
7 | [34; 38) 'self': &S | 7 | [34; 38) 'self': &S |
8 | [40; 61) '{ ... }': () | 8 | [40; 61) '{ ... }': () |
@@ -10,4 +10,8 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs" | |||
10 | [75; 79) 'self': &S | 10 | [75; 79) 'self': &S |
11 | [88; 109) '{ ... }': () | 11 | [88; 109) '{ ... }': () |
12 | [98; 102) 'self': &S | 12 | [98; 102) 'self': &S |
13 | [133; 153) '{ ... }': S | ||
14 | [143; 147) 'S {}': S | ||
15 | [177; 200) '{ ... }': S | ||
16 | [187; 194) 'Self {}': S | ||
13 | 17 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index cb8d6351d..30da8fc23 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -215,6 +215,12 @@ impl S { | |||
215 | fn test2(self: &Self) { | 215 | fn test2(self: &Self) { |
216 | self; | 216 | self; |
217 | } | 217 | } |
218 | fn test3() -> Self { | ||
219 | S {} | ||
220 | } | ||
221 | fn test4() -> Self { | ||
222 | Self {} | ||
223 | } | ||
218 | } | 224 | } |
219 | "#, | 225 | "#, |
220 | ); | 226 | ); |
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..c25adb8b9 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 | None => { | ||
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, |
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 |