diff options
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 23 | ||||
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/imp.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 38 | ||||
-rw-r--r-- | crates/ra_ide_api/src/navigation_target.rs | 112 |
5 files changed, 98 insertions, 94 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index eaddd5083..4706dc733 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_db::{FileId, Cancelable, SyntaxDatabase}; | 1 | use ra_db::{FileId, Cancelable, SyntaxDatabase}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | TextRange, AstNode, ast, SyntaxKind::{NAME, MODULE}, | 3 | AstNode, ast, |
4 | algo::find_node_at_offset, | 4 | algo::find_node_at_offset, |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -32,13 +32,7 @@ pub(crate) fn reference_definition( | |||
32 | let scope = fn_descr.scopes(db)?; | 32 | let scope = fn_descr.scopes(db)?; |
33 | // First try to resolve the symbol locally | 33 | // First try to resolve the symbol locally |
34 | if let Some(entry) = scope.resolve_local_name(name_ref) { | 34 | if let Some(entry) = scope.resolve_local_name(name_ref) { |
35 | let nav = NavigationTarget { | 35 | let nav = NavigationTarget::from_scope_entry(file_id, &entry); |
36 | file_id, | ||
37 | name: entry.name().to_string().into(), | ||
38 | range: entry.ptr().range(), | ||
39 | kind: NAME, | ||
40 | ptr: None, | ||
41 | }; | ||
42 | return Ok(vec![nav]); | 36 | return Ok(vec![nav]); |
43 | }; | 37 | }; |
44 | } | 38 | } |
@@ -79,18 +73,7 @@ fn name_definition( | |||
79 | if let Some(child_module) = | 73 | if let Some(child_module) = |
80 | hir::source_binder::module_from_declaration(db, file_id, module)? | 74 | hir::source_binder::module_from_declaration(db, file_id, module)? |
81 | { | 75 | { |
82 | let (file_id, _) = child_module.definition_source(db)?; | 76 | let nav = NavigationTarget::from_module(db, child_module)?; |
83 | let name = match child_module.name(db)? { | ||
84 | Some(name) => name.to_string().into(), | ||
85 | None => "".into(), | ||
86 | }; | ||
87 | let nav = NavigationTarget { | ||
88 | file_id, | ||
89 | name, | ||
90 | range: TextRange::offset_len(0.into(), 0.into()), | ||
91 | kind: MODULE, | ||
92 | ptr: None, | ||
93 | }; | ||
94 | return Ok(Some(vec![nav])); | 77 | return Ok(Some(vec![nav])); |
95 | } | 78 | } |
96 | } | 79 | } |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 41309e756..9b06a0e58 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -88,11 +88,11 @@ fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Cancelable<Option<S | |||
88 | 88 | ||
89 | impl NavigationTarget { | 89 | impl NavigationTarget { |
90 | fn node(&self, db: &RootDatabase) -> Option<TreePtr<SyntaxNode>> { | 90 | fn node(&self, db: &RootDatabase) -> Option<TreePtr<SyntaxNode>> { |
91 | let source_file = db.source_file(self.file_id); | 91 | let source_file = db.source_file(self.file_id()); |
92 | let source_file = source_file.syntax(); | 92 | let source_file = source_file.syntax(); |
93 | let node = source_file | 93 | let node = source_file |
94 | .descendants() | 94 | .descendants() |
95 | .find(|node| node.kind() == self.kind && node.range() == self.range)? | 95 | .find(|node| node.kind() == self.kind() && node.range() == self.range())? |
96 | .to_owned(); | 96 | .to_owned(); |
97 | Some(node) | 97 | Some(node) |
98 | } | 98 | } |
diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 7c60ab7d6..12bfe1761 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs | |||
@@ -11,7 +11,6 @@ use ra_syntax::{ | |||
11 | TextRange, AstNode, SourceFile, | 11 | TextRange, AstNode, SourceFile, |
12 | ast::{self, NameOwner}, | 12 | ast::{self, NameOwner}, |
13 | algo::find_node_at_offset, | 13 | algo::find_node_at_offset, |
14 | SyntaxKind::*, | ||
15 | }; | 14 | }; |
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
@@ -109,18 +108,8 @@ impl db::RootDatabase { | |||
109 | None => return Ok(Vec::new()), | 108 | None => return Ok(Vec::new()), |
110 | Some(it) => it, | 109 | Some(it) => it, |
111 | }; | 110 | }; |
112 | let (file_id, ast_module) = match module.declaration_source(self)? { | 111 | let nav = NavigationTarget::from_module(self, module)?; |
113 | None => return Ok(Vec::new()), | 112 | Ok(vec![nav]) |
114 | Some(it) => it, | ||
115 | }; | ||
116 | let name = ast_module.name().unwrap(); | ||
117 | Ok(vec![NavigationTarget { | ||
118 | file_id, | ||
119 | name: name.text().clone(), | ||
120 | range: name.syntax().range(), | ||
121 | kind: MODULE, | ||
122 | ptr: None, | ||
123 | }]) | ||
124 | } | 113 | } |
125 | /// Returns `Vec` for the same reason as `parent_module` | 114 | /// Returns `Vec` for the same reason as `parent_module` |
126 | pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 115 | pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 9c5a82187..2873bab36 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -34,9 +34,9 @@ mod syntax_highlighting; | |||
34 | 34 | ||
35 | use std::{fmt, sync::Arc}; | 35 | use std::{fmt, sync::Arc}; |
36 | 36 | ||
37 | use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit}; | 37 | use ra_syntax::{SourceFile, TreePtr, TextRange, TextUnit}; |
38 | use ra_text_edit::TextEdit; | 38 | use ra_text_edit::TextEdit; |
39 | use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase}; | 39 | use ra_db::{SyntaxDatabase, FilesDatabase, BaseDatabase}; |
40 | use rayon::prelude::*; | 40 | use rayon::prelude::*; |
41 | use relative_path::RelativePathBuf; | 41 | use relative_path::RelativePathBuf; |
42 | use rustc_hash::FxHashMap; | 42 | use rustc_hash::FxHashMap; |
@@ -50,6 +50,7 @@ use crate::{ | |||
50 | pub use crate::{ | 50 | pub use crate::{ |
51 | completion::{CompletionItem, CompletionItemKind, InsertText}, | 51 | completion::{CompletionItem, CompletionItemKind, InsertText}, |
52 | runnables::{Runnable, RunnableKind}, | 52 | runnables::{Runnable, RunnableKind}, |
53 | navigation_target::NavigationTarget, | ||
53 | }; | 54 | }; |
54 | pub use ra_ide_api_light::{ | 55 | pub use ra_ide_api_light::{ |
55 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, | 56 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, |
@@ -243,39 +244,6 @@ impl Query { | |||
243 | } | 244 | } |
244 | } | 245 | } |
245 | 246 | ||
246 | /// `NavigationTarget` represents and element in the editor's UI which you can | ||
247 | /// click on to navigate to a particular piece of code. | ||
248 | /// | ||
249 | /// Typically, a `NavigationTarget` corresponds to some element in the source | ||
250 | /// code, like a function or a struct, but this is not strictly required. | ||
251 | #[derive(Debug, Clone)] | ||
252 | pub struct NavigationTarget { | ||
253 | file_id: FileId, | ||
254 | name: SmolStr, | ||
255 | kind: SyntaxKind, | ||
256 | range: TextRange, | ||
257 | // Should be DefId ideally | ||
258 | ptr: Option<LocalSyntaxPtr>, | ||
259 | } | ||
260 | |||
261 | impl NavigationTarget { | ||
262 | pub fn name(&self) -> &SmolStr { | ||
263 | &self.name | ||
264 | } | ||
265 | |||
266 | pub fn kind(&self) -> SyntaxKind { | ||
267 | self.kind | ||
268 | } | ||
269 | |||
270 | pub fn file_id(&self) -> FileId { | ||
271 | self.file_id | ||
272 | } | ||
273 | |||
274 | pub fn range(&self) -> TextRange { | ||
275 | self.range | ||
276 | } | ||
277 | } | ||
278 | |||
279 | #[derive(Debug)] | 247 | #[derive(Debug)] |
280 | pub struct RangeInfo<T> { | 248 | pub struct RangeInfo<T> { |
281 | pub range: TextRange, | 249 | pub range: TextRange, |
diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 09a723d68..943e62eb8 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs | |||
@@ -1,27 +1,98 @@ | |||
1 | use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; | 1 | use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | SyntaxNode, AstNode, SmolStr, | 3 | SyntaxNode, AstNode, SmolStr, TextRange, ast, |
4 | ast | 4 | SyntaxKind::{self, NAME}, |
5 | }; | 5 | }; |
6 | use hir::{Def, ModuleSource}; | 6 | use hir::{Def, ModuleSource}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{FileSymbol, db::RootDatabase}; |
9 | NavigationTarget, | 9 | |
10 | FileSymbol, | 10 | /// `NavigationTarget` represents and element in the editor's UI which you can |
11 | db::RootDatabase, | 11 | /// click on to navigate to a particular piece of code. |
12 | }; | 12 | /// |
13 | /// Typically, a `NavigationTarget` corresponds to some element in the source | ||
14 | /// code, like a function or a struct, but this is not strictly required. | ||
15 | #[derive(Debug, Clone)] | ||
16 | pub struct NavigationTarget { | ||
17 | file_id: FileId, | ||
18 | name: SmolStr, | ||
19 | kind: SyntaxKind, | ||
20 | range: TextRange, | ||
21 | focus_range: Option<TextRange>, | ||
22 | // Should be DefId ideally | ||
23 | ptr: Option<LocalSyntaxPtr>, | ||
24 | } | ||
13 | 25 | ||
14 | impl NavigationTarget { | 26 | impl NavigationTarget { |
27 | pub fn name(&self) -> &SmolStr { | ||
28 | &self.name | ||
29 | } | ||
30 | |||
31 | pub fn kind(&self) -> SyntaxKind { | ||
32 | self.kind | ||
33 | } | ||
34 | |||
35 | pub fn file_id(&self) -> FileId { | ||
36 | self.file_id | ||
37 | } | ||
38 | |||
39 | pub fn range(&self) -> TextRange { | ||
40 | self.range | ||
41 | } | ||
42 | |||
43 | /// A "most interesting" range withing the `range`. | ||
44 | /// | ||
45 | /// Typically, `range` is the whole syntax node, including doc comments, and | ||
46 | /// `focus_range` is the range of the identifier. | ||
47 | pub fn focus_range(&self) -> Option<TextRange> { | ||
48 | self.focus_range | ||
49 | } | ||
50 | |||
15 | pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget { | 51 | pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget { |
16 | NavigationTarget { | 52 | NavigationTarget { |
17 | file_id: symbol.file_id, | 53 | file_id: symbol.file_id, |
18 | name: symbol.name.clone(), | 54 | name: symbol.name.clone(), |
19 | kind: symbol.ptr.kind(), | 55 | kind: symbol.ptr.kind(), |
20 | range: symbol.ptr.range(), | 56 | range: symbol.ptr.range(), |
57 | focus_range: None, | ||
21 | ptr: Some(symbol.ptr.clone()), | 58 | ptr: Some(symbol.ptr.clone()), |
22 | } | 59 | } |
23 | } | 60 | } |
24 | 61 | ||
62 | pub(crate) fn from_scope_entry( | ||
63 | file_id: FileId, | ||
64 | entry: &hir::ScopeEntryWithSyntax, | ||
65 | ) -> NavigationTarget { | ||
66 | NavigationTarget { | ||
67 | file_id, | ||
68 | name: entry.name().to_string().into(), | ||
69 | range: entry.ptr().range(), | ||
70 | focus_range: None, | ||
71 | kind: NAME, | ||
72 | ptr: None, | ||
73 | } | ||
74 | } | ||
75 | |||
76 | pub(crate) fn from_module( | ||
77 | db: &RootDatabase, | ||
78 | module: hir::Module, | ||
79 | ) -> Cancelable<NavigationTarget> { | ||
80 | let (file_id, source) = module.definition_source(db)?; | ||
81 | let name = module | ||
82 | .name(db)? | ||
83 | .map(|it| it.to_string().into()) | ||
84 | .unwrap_or_default(); | ||
85 | let res = match source { | ||
86 | ModuleSource::SourceFile(node) => { | ||
87 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) | ||
88 | } | ||
89 | ModuleSource::Module(node) => { | ||
90 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) | ||
91 | } | ||
92 | }; | ||
93 | Ok(res) | ||
94 | } | ||
95 | |||
25 | // TODO once Def::Item is gone, this should be able to always return a NavigationTarget | 96 | // TODO once Def::Item is gone, this should be able to always return a NavigationTarget |
26 | pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable<Option<NavigationTarget>> { | 97 | pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable<Option<NavigationTarget>> { |
27 | let res = match def { | 98 | let res = match def { |
@@ -41,21 +112,7 @@ impl NavigationTarget { | |||
41 | let (file_id, node) = f.source(db)?; | 112 | let (file_id, node) = f.source(db)?; |
42 | NavigationTarget::from_named(file_id.original_file(db), &*node) | 113 | NavigationTarget::from_named(file_id.original_file(db), &*node) |
43 | } | 114 | } |
44 | Def::Module(m) => { | 115 | Def::Module(m) => NavigationTarget::from_module(db, m)?, |
45 | let (file_id, source) = m.definition_source(db)?; | ||
46 | let name = m | ||
47 | .name(db)? | ||
48 | .map(|it| it.to_string().into()) | ||
49 | .unwrap_or_default(); | ||
50 | match source { | ||
51 | ModuleSource::SourceFile(node) => { | ||
52 | NavigationTarget::from_syntax(file_id, name, node.syntax()) | ||
53 | } | ||
54 | ModuleSource::Module(node) => { | ||
55 | NavigationTarget::from_syntax(file_id, name, node.syntax()) | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | Def::Item => return Ok(None), | 116 | Def::Item => return Ok(None), |
60 | }; | 117 | }; |
61 | Ok(Some(res)) | 118 | Ok(Some(res)) |
@@ -63,15 +120,22 @@ impl NavigationTarget { | |||
63 | 120 | ||
64 | fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { | 121 | fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { |
65 | let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); | 122 | let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); |
66 | NavigationTarget::from_syntax(file_id, name, node.syntax()) | 123 | let focus_range = node.name().map(|it| it.syntax().range()); |
124 | NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax()) | ||
67 | } | 125 | } |
68 | 126 | ||
69 | fn from_syntax(file_id: FileId, name: SmolStr, node: &SyntaxNode) -> NavigationTarget { | 127 | fn from_syntax( |
128 | file_id: FileId, | ||
129 | name: SmolStr, | ||
130 | focus_range: Option<TextRange>, | ||
131 | node: &SyntaxNode, | ||
132 | ) -> NavigationTarget { | ||
70 | NavigationTarget { | 133 | NavigationTarget { |
71 | file_id, | 134 | file_id, |
72 | name, | 135 | name, |
73 | kind: node.kind(), | 136 | kind: node.kind(), |
74 | range: node.range(), | 137 | range: node.range(), |
138 | focus_range, | ||
75 | ptr: Some(LocalSyntaxPtr::new(node)), | 139 | ptr: Some(LocalSyntaxPtr::new(node)), |
76 | } | 140 | } |
77 | } | 141 | } |