aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/display.rs2
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs66
-rw-r--r--crates/ra_ide/src/goto_definition.rs149
-rw-r--r--crates/ra_ide/src/references.rs12
4 files changed, 58 insertions, 171 deletions
diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs
index fbe89841b..1c26a8697 100644
--- a/crates/ra_ide/src/display.rs
+++ b/crates/ra_ide/src/display.rs
@@ -15,7 +15,7 @@ pub use function_signature::FunctionSignature;
15pub use navigation_target::NavigationTarget; 15pub use navigation_target::NavigationTarget;
16pub use structure::{file_structure, StructureNode}; 16pub use structure::{file_structure, StructureNode};
17 17
18pub(crate) use navigation_target::ToNav; 18pub(crate) use navigation_target::{ToNav, TryToNav};
19pub(crate) use short_label::ShortLabel; 19pub(crate) use short_label::ShortLabel;
20 20
21pub(crate) fn function_label(node: &ast::FnDef) -> String { 21pub(crate) fn function_label(node: &ast::FnDef) -> String {
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index 096c41c81..b42cb477e 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -11,7 +11,7 @@ use ra_syntax::{
11 TextRange, 11 TextRange,
12}; 12};
13 13
14use crate::{expand::original_range, FileSymbol}; 14use crate::{expand::original_range, references::NameDefinition, FileSymbol};
15 15
16use super::short_label::ShortLabel; 16use super::short_label::ShortLabel;
17 17
@@ -36,6 +36,10 @@ pub(crate) trait ToNav {
36 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; 36 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget;
37} 37}
38 38
39pub(crate) trait TryToNav {
40 fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget>;
41}
42
39impl NavigationTarget { 43impl NavigationTarget {
40 /// When `focus_range` is specified, returns it. otherwise 44 /// When `focus_range` is specified, returns it. otherwise
41 /// returns `full_range` 45 /// returns `full_range`
@@ -96,26 +100,6 @@ impl NavigationTarget {
96 module.to_nav(db) 100 module.to_nav(db)
97 } 101 }
98 102
99 pub(crate) fn from_def(
100 db: &RootDatabase,
101 module_def: hir::ModuleDef,
102 ) -> Option<NavigationTarget> {
103 let nav = match module_def {
104 hir::ModuleDef::Module(module) => module.to_nav(db),
105 hir::ModuleDef::Function(it) => it.to_nav(db),
106 hir::ModuleDef::Adt(it) => it.to_nav(db),
107 hir::ModuleDef::Const(it) => it.to_nav(db),
108 hir::ModuleDef::Static(it) => it.to_nav(db),
109 hir::ModuleDef::EnumVariant(it) => it.to_nav(db),
110 hir::ModuleDef::Trait(it) => it.to_nav(db),
111 hir::ModuleDef::TypeAlias(it) => it.to_nav(db),
112 hir::ModuleDef::BuiltinType(..) => {
113 return None;
114 }
115 };
116 Some(nav)
117 }
118
119 #[cfg(test)] 103 #[cfg(test)]
120 pub(crate) fn assert_match(&self, expected: &str) { 104 pub(crate) fn assert_match(&self, expected: &str) {
121 let actual = self.debug_render(); 105 let actual = self.debug_render();
@@ -201,6 +185,36 @@ impl ToNav for FileSymbol {
201 } 185 }
202} 186}
203 187
188impl TryToNav for NameDefinition {
189 fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
190 match self {
191 NameDefinition::Macro(it) => Some(it.to_nav(db)),
192 NameDefinition::StructField(it) => Some(it.to_nav(db)),
193 NameDefinition::ModuleDef(it) => it.try_to_nav(db),
194 NameDefinition::SelfType(it) => Some(it.to_nav(db)),
195 NameDefinition::Local(it) => Some(it.to_nav(db)),
196 NameDefinition::TypeParam(it) => Some(it.to_nav(db)),
197 }
198 }
199}
200
201impl TryToNav for hir::ModuleDef {
202 fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
203 let res = match self {
204 hir::ModuleDef::Module(it) => it.to_nav(db),
205 hir::ModuleDef::Function(it) => it.to_nav(db),
206 hir::ModuleDef::Adt(it) => it.to_nav(db),
207 hir::ModuleDef::EnumVariant(it) => it.to_nav(db),
208 hir::ModuleDef::Const(it) => it.to_nav(db),
209 hir::ModuleDef::Static(it) => it.to_nav(db),
210 hir::ModuleDef::Trait(it) => it.to_nav(db),
211 hir::ModuleDef::TypeAlias(it) => it.to_nav(db),
212 hir::ModuleDef::BuiltinType(_) => return None,
213 };
214 Some(res)
215 }
216}
217
204pub(crate) trait ToNavFromAst {} 218pub(crate) trait ToNavFromAst {}
205impl ToNavFromAst for hir::Function {} 219impl ToNavFromAst for hir::Function {}
206impl ToNavFromAst for hir::Const {} 220impl ToNavFromAst for hir::Const {}
@@ -232,15 +246,17 @@ impl ToNav for hir::Module {
232 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 246 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
233 let src = self.definition_source(db); 247 let src = self.definition_source(db);
234 let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 248 let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default();
235 let syntax = match &src.value { 249 let (syntax, focus) = match &src.value {
236 ModuleSource::SourceFile(node) => node.syntax(), 250 ModuleSource::SourceFile(node) => (node.syntax(), None),
237 ModuleSource::Module(node) => node.syntax(), 251 ModuleSource::Module(node) => {
252 (node.syntax(), node.name().map(|it| it.syntax().text_range()))
253 }
238 }; 254 };
239 let frange = original_range(db, src.with_value(syntax)); 255 let frange = original_range(db, src.with_value(syntax));
240 NavigationTarget::from_syntax( 256 NavigationTarget::from_syntax(
241 frange.file_id, 257 frange.file_id,
242 name, 258 name,
243 None, 259 focus,
244 frange.range, 260 frange.range,
245 syntax.kind(), 261 syntax.kind(),
246 None, 262 None,
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index cce539e56..feff1ec3f 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -1,18 +1,18 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::AstDatabase, InFile, SourceBinder}; 3use hir::{db::AstDatabase, InFile, SourceBinder};
4use ra_ide_db::{defs::NameDefinition, symbol_index, RootDatabase}; 4use ra_ide_db::{symbol_index, RootDatabase};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, DocCommentsOwner}, 6 ast::{self},
7 match_ast, AstNode, 7 match_ast, AstNode,
8 SyntaxKind::*, 8 SyntaxKind::*,
9 SyntaxNode, SyntaxToken, TokenAtOffset, 9 SyntaxToken, TokenAtOffset,
10}; 10};
11 11
12use crate::{ 12use crate::{
13 display::{ShortLabel, ToNav}, 13 display::{ToNav, TryToNav},
14 expand::descend_into_macros, 14 expand::descend_into_macros,
15 references::classify_name_ref, 15 references::{classify_name, classify_name_ref},
16 FilePosition, NavigationTarget, RangeInfo, 16 FilePosition, NavigationTarget, RangeInfo,
17}; 17};
18 18
@@ -74,23 +74,12 @@ pub(crate) fn reference_definition(
74 use self::ReferenceResult::*; 74 use self::ReferenceResult::*;
75 75
76 let name_kind = classify_name_ref(sb, name_ref); 76 let name_kind = classify_name_ref(sb, name_ref);
77 match name_kind { 77 if let Some(def) = name_kind {
78 Some(NameDefinition::Macro(it)) => return Exact(it.to_nav(sb.db)), 78 return match def.try_to_nav(sb.db) {
79 Some(NameDefinition::StructField(it)) => return Exact(it.to_nav(sb.db)), 79 Some(nav) => ReferenceResult::Exact(nav),
80 Some(NameDefinition::TypeParam(it)) => return Exact(it.to_nav(sb.db)), 80 None => ReferenceResult::Approximate(Vec::new()),
81 Some(NameDefinition::Local(it)) => return Exact(it.to_nav(sb.db)), 81 };
82 Some(NameDefinition::ModuleDef(def)) => match NavigationTarget::from_def(sb.db, def) { 82 }
83 Some(nav) => return Exact(nav),
84 None => return Approximate(vec![]),
85 },
86 Some(NameDefinition::SelfType(imp)) => {
87 // FIXME: ideally, this should point to the type in the impl, and
88 // not at the whole impl. And goto **type** definition should bring
89 // us to the actual type
90 return Exact(imp.to_nav(sb.db));
91 }
92 None => {}
93 };
94 83
95 // Fallback index based approach: 84 // Fallback index based approach:
96 let navs = symbol_index::index_resolve(sb.db, name_ref.value) 85 let navs = symbol_index::index_resolve(sb.db, name_ref.value)
@@ -104,119 +93,9 @@ fn name_definition(
104 sb: &mut SourceBinder<RootDatabase>, 93 sb: &mut SourceBinder<RootDatabase>,
105 name: InFile<&ast::Name>, 94 name: InFile<&ast::Name>,
106) -> Option<Vec<NavigationTarget>> { 95) -> Option<Vec<NavigationTarget>> {
107 let parent = name.value.syntax().parent()?; 96 let def = classify_name(sb, name)?;
108 97 let nav = def.try_to_nav(sb.db)?;
109 if let Some(module) = ast::Module::cast(parent.clone()) { 98 Some(vec![nav])
110 if module.has_semi() {
111 let src = name.with_value(module);
112 if let Some(child_module) = sb.to_def(src) {
113 let nav = child_module.to_nav(sb.db);
114 return Some(vec![nav]);
115 }
116 }
117 }
118
119 if let Some(nav) = named_target(sb.db, name.with_value(&parent)) {
120 return Some(vec![nav]);
121 }
122
123 None
124}
125
126fn named_target(db: &RootDatabase, node: InFile<&SyntaxNode>) -> Option<NavigationTarget> {
127 match_ast! {
128 match (node.value) {
129 ast::StructDef(it) => {
130 Some(NavigationTarget::from_named(
131 db,
132 node.with_value(&it),
133 it.doc_comment_text(),
134 it.short_label(),
135 ))
136 },
137 ast::EnumDef(it) => {
138 Some(NavigationTarget::from_named(
139 db,
140 node.with_value(&it),
141 it.doc_comment_text(),
142 it.short_label(),
143 ))
144 },
145 ast::EnumVariant(it) => {
146 Some(NavigationTarget::from_named(
147 db,
148 node.with_value(&it),
149 it.doc_comment_text(),
150 it.short_label(),
151 ))
152 },
153 ast::FnDef(it) => {
154 Some(NavigationTarget::from_named(
155 db,
156 node.with_value(&it),
157 it.doc_comment_text(),
158 it.short_label(),
159 ))
160 },
161 ast::TypeAliasDef(it) => {
162 Some(NavigationTarget::from_named(
163 db,
164 node.with_value(&it),
165 it.doc_comment_text(),
166 it.short_label(),
167 ))
168 },
169 ast::ConstDef(it) => {
170 Some(NavigationTarget::from_named(
171 db,
172 node.with_value(&it),
173 it.doc_comment_text(),
174 it.short_label(),
175 ))
176 },
177 ast::StaticDef(it) => {
178 Some(NavigationTarget::from_named(
179 db,
180 node.with_value(&it),
181 it.doc_comment_text(),
182 it.short_label(),
183 ))
184 },
185 ast::TraitDef(it) => {
186 Some(NavigationTarget::from_named(
187 db,
188 node.with_value(&it),
189 it.doc_comment_text(),
190 it.short_label(),
191 ))
192 },
193 ast::RecordFieldDef(it) => {
194 Some(NavigationTarget::from_named(
195 db,
196 node.with_value(&it),
197 it.doc_comment_text(),
198 it.short_label(),
199 ))
200 },
201 ast::Module(it) => {
202 Some(NavigationTarget::from_named(
203 db,
204 node.with_value(&it),
205 it.doc_comment_text(),
206 it.short_label(),
207 ))
208 },
209 ast::MacroCall(it) => {
210 Some(NavigationTarget::from_named(
211 db,
212 node.with_value(&it),
213 it.doc_comment_text(),
214 None,
215 ))
216 },
217 _ => None,
218 }
219 }
220} 99}
221 100
222#[cfg(test)] 101#[cfg(test)]
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 7f790a62d..aadc2dbcb 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -25,7 +25,7 @@ use ra_syntax::{
25 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset, 25 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset,
26}; 26};
27 27
28use crate::{display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; 28use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
29 29
30pub(crate) use self::{ 30pub(crate) use self::{
31 classify::{classify_name, classify_name_ref}, 31 classify::{classify_name, classify_name_ref},
@@ -125,15 +125,7 @@ pub(crate) fn find_all_refs(
125 }; 125 };
126 126
127 let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?; 127 let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?;
128 128 let declaration = def.try_to_nav(db)?;
129 let declaration = match def {
130 NameDefinition::Macro(mac) => mac.to_nav(db),
131 NameDefinition::StructField(field) => field.to_nav(db),
132 NameDefinition::ModuleDef(def) => NavigationTarget::from_def(db, def)?,
133 NameDefinition::SelfType(imp) => imp.to_nav(db),
134 NameDefinition::Local(local) => local.to_nav(db),
135 NameDefinition::TypeParam(_) => return None,
136 };
137 129
138 let search_scope = { 130 let search_scope = {
139 let base = SearchScope::for_def(&def, db); 131 let base = SearchScope::for_def(&def, db);