diff options
author | Edwin Cheng <[email protected]> | 2019-11-03 17:49:41 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2019-11-04 17:38:20 +0000 |
commit | e8741b9d75eb4edd711c6516c3b17c87c0431166 (patch) | |
tree | 49c2f6a78a35fcf7399a40b96805caa68aec6172 /crates/ra_ide_api/src/display | |
parent | 67226ebc8288b9489867ea2454f9d976b65ff15e (diff) |
Use new expansion feature in goto_definition
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 122 |
1 files changed, 90 insertions, 32 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 5cb67fb95..0c3e25ce6 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -29,6 +29,20 @@ pub struct NavigationTarget { | |||
29 | docs: Option<String>, | 29 | docs: Option<String>, |
30 | } | 30 | } |
31 | 31 | ||
32 | fn find_range_from_node( | ||
33 | db: &RootDatabase, | ||
34 | src: hir::HirFileId, | ||
35 | node: &SyntaxNode, | ||
36 | ) -> (FileId, TextRange) { | ||
37 | let text_range = node.text_range(); | ||
38 | let (file_id, text_range) = src | ||
39 | .parent_expansion(db) | ||
40 | .and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files)) | ||
41 | .unwrap_or((src, text_range)); | ||
42 | |||
43 | (file_id.original_file(db), text_range) | ||
44 | } | ||
45 | |||
32 | impl NavigationTarget { | 46 | impl NavigationTarget { |
33 | /// When `focus_range` is specified, returns it. otherwise | 47 | /// When `focus_range` is specified, returns it. otherwise |
34 | /// returns `full_range` | 48 | /// returns `full_range` |
@@ -72,8 +86,12 @@ impl NavigationTarget { | |||
72 | self.focus_range | 86 | self.focus_range |
73 | } | 87 | } |
74 | 88 | ||
75 | pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget { | 89 | pub(crate) fn from_bind_pat( |
76 | NavigationTarget::from_named(file_id, pat, None, None) | 90 | db: &RootDatabase, |
91 | file_id: FileId, | ||
92 | pat: &ast::BindPat, | ||
93 | ) -> NavigationTarget { | ||
94 | NavigationTarget::from_named(db, file_id.into(), pat, None, None) | ||
77 | } | 95 | } |
78 | 96 | ||
79 | pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { | 97 | pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { |
@@ -96,7 +114,7 @@ impl NavigationTarget { | |||
96 | ) -> NavigationTarget { | 114 | ) -> NavigationTarget { |
97 | let parse = db.parse(file_id); | 115 | let parse = db.parse(file_id); |
98 | let pat = pat.to_node(parse.tree().syntax()); | 116 | let pat = pat.to_node(parse.tree().syntax()); |
99 | NavigationTarget::from_bind_pat(file_id, &pat) | 117 | NavigationTarget::from_bind_pat(db, file_id, &pat) |
100 | } | 118 | } |
101 | 119 | ||
102 | pub(crate) fn from_self_param( | 120 | pub(crate) fn from_self_param( |
@@ -119,31 +137,47 @@ impl NavigationTarget { | |||
119 | 137 | ||
120 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 138 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
121 | let src = module.definition_source(db); | 139 | let src = module.definition_source(db); |
122 | let file_id = src.file_id.original_file(db); | ||
123 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 140 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
141 | |||
124 | match src.ast { | 142 | match src.ast { |
125 | ModuleSource::SourceFile(node) => { | 143 | ModuleSource::SourceFile(node) => { |
126 | NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None) | 144 | let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); |
145 | |||
146 | NavigationTarget::from_syntax( | ||
147 | file_id, | ||
148 | name, | ||
149 | None, | ||
150 | text_range, | ||
151 | node.syntax(), | ||
152 | None, | ||
153 | None, | ||
154 | ) | ||
155 | } | ||
156 | ModuleSource::Module(node) => { | ||
157 | let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); | ||
158 | |||
159 | NavigationTarget::from_syntax( | ||
160 | file_id, | ||
161 | name, | ||
162 | None, | ||
163 | text_range, | ||
164 | node.syntax(), | ||
165 | node.doc_comment_text(), | ||
166 | node.short_label(), | ||
167 | ) | ||
127 | } | 168 | } |
128 | ModuleSource::Module(node) => NavigationTarget::from_syntax( | ||
129 | file_id, | ||
130 | name, | ||
131 | None, | ||
132 | node.syntax(), | ||
133 | node.doc_comment_text(), | ||
134 | node.short_label(), | ||
135 | ), | ||
136 | } | 169 | } |
137 | } | 170 | } |
138 | 171 | ||
139 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 172 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
140 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 173 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
141 | if let Some(src) = module.declaration_source(db) { | 174 | if let Some(src) = module.declaration_source(db) { |
142 | let file_id = src.file_id.original_file(db); | 175 | let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); |
143 | return NavigationTarget::from_syntax( | 176 | return NavigationTarget::from_syntax( |
144 | file_id, | 177 | file_id, |
145 | name, | 178 | name, |
146 | None, | 179 | None, |
180 | text_range, | ||
147 | src.ast.syntax(), | 181 | src.ast.syntax(), |
148 | src.ast.doc_comment_text(), | 182 | src.ast.doc_comment_text(), |
149 | src.ast.short_label(), | 183 | src.ast.short_label(), |
@@ -154,13 +188,25 @@ impl NavigationTarget { | |||
154 | 188 | ||
155 | pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { | 189 | pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { |
156 | let src = field.source(db); | 190 | let src = field.source(db); |
157 | let file_id = src.file_id.original_file(db); | ||
158 | match src.ast { | 191 | match src.ast { |
159 | FieldSource::Named(it) => { | 192 | FieldSource::Named(it) => NavigationTarget::from_named( |
160 | NavigationTarget::from_named(file_id, &it, it.doc_comment_text(), it.short_label()) | 193 | db, |
161 | } | 194 | src.file_id, |
195 | &it, | ||
196 | it.doc_comment_text(), | ||
197 | it.short_label(), | ||
198 | ), | ||
162 | FieldSource::Pos(it) => { | 199 | FieldSource::Pos(it) => { |
163 | NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax(), None, None) | 200 | let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax()); |
201 | NavigationTarget::from_syntax( | ||
202 | file_id, | ||
203 | "".into(), | ||
204 | None, | ||
205 | text_range, | ||
206 | it.syntax(), | ||
207 | None, | ||
208 | None, | ||
209 | ) | ||
164 | } | 210 | } |
165 | } | 211 | } |
166 | } | 212 | } |
@@ -172,7 +218,8 @@ impl NavigationTarget { | |||
172 | { | 218 | { |
173 | let src = def.source(db); | 219 | let src = def.source(db); |
174 | NavigationTarget::from_named( | 220 | NavigationTarget::from_named( |
175 | src.file_id.original_file(db), | 221 | db, |
222 | src.file_id, | ||
176 | &src.ast, | 223 | &src.ast, |
177 | src.ast.doc_comment_text(), | 224 | src.ast.doc_comment_text(), |
178 | src.ast.short_label(), | 225 | src.ast.short_label(), |
@@ -212,10 +259,13 @@ impl NavigationTarget { | |||
212 | impl_block: hir::ImplBlock, | 259 | impl_block: hir::ImplBlock, |
213 | ) -> NavigationTarget { | 260 | ) -> NavigationTarget { |
214 | let src = impl_block.source(db); | 261 | let src = impl_block.source(db); |
262 | let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); | ||
263 | |||
215 | NavigationTarget::from_syntax( | 264 | NavigationTarget::from_syntax( |
216 | src.file_id.original_file(db), | 265 | file_id, |
217 | "impl".into(), | 266 | "impl".into(), |
218 | None, | 267 | None, |
268 | text_range, | ||
219 | src.ast.syntax(), | 269 | src.ast.syntax(), |
220 | None, | 270 | None, |
221 | None, | 271 | None, |
@@ -236,12 +286,7 @@ impl NavigationTarget { | |||
236 | pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { | 286 | pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { |
237 | let src = macro_call.source(db); | 287 | let src = macro_call.source(db); |
238 | log::debug!("nav target {:#?}", src.ast.syntax()); | 288 | log::debug!("nav target {:#?}", src.ast.syntax()); |
239 | NavigationTarget::from_named( | 289 | NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None) |
240 | src.file_id.original_file(db), | ||
241 | &src.ast, | ||
242 | src.ast.doc_comment_text(), | ||
243 | None, | ||
244 | ) | ||
245 | } | 290 | } |
246 | 291 | ||
247 | #[cfg(test)] | 292 | #[cfg(test)] |
@@ -270,21 +315,35 @@ impl NavigationTarget { | |||
270 | 315 | ||
271 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 316 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
272 | pub(crate) fn from_named( | 317 | pub(crate) fn from_named( |
273 | file_id: FileId, | 318 | db: &RootDatabase, |
319 | file_id: hir::HirFileId, | ||
274 | node: &impl ast::NameOwner, | 320 | node: &impl ast::NameOwner, |
275 | docs: Option<String>, | 321 | docs: Option<String>, |
276 | description: Option<String>, | 322 | description: Option<String>, |
277 | ) -> NavigationTarget { | 323 | ) -> NavigationTarget { |
278 | //FIXME: use `_` instead of empty string | 324 | //FIXME: use `_` instead of empty string |
279 | let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); | 325 | let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); |
280 | let focus_range = node.name().map(|it| it.syntax().text_range()); | 326 | |
281 | NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description) | 327 | let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1); |
328 | |||
329 | let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax()); | ||
330 | |||
331 | NavigationTarget::from_syntax( | ||
332 | file_id, | ||
333 | name, | ||
334 | focus_range, | ||
335 | full_range, | ||
336 | node.syntax(), | ||
337 | docs, | ||
338 | description, | ||
339 | ) | ||
282 | } | 340 | } |
283 | 341 | ||
284 | fn from_syntax( | 342 | fn from_syntax( |
285 | file_id: FileId, | 343 | file_id: FileId, |
286 | name: SmolStr, | 344 | name: SmolStr, |
287 | focus_range: Option<TextRange>, | 345 | focus_range: Option<TextRange>, |
346 | full_range: TextRange, | ||
288 | node: &SyntaxNode, | 347 | node: &SyntaxNode, |
289 | docs: Option<String>, | 348 | docs: Option<String>, |
290 | description: Option<String>, | 349 | description: Option<String>, |
@@ -293,9 +352,8 @@ impl NavigationTarget { | |||
293 | file_id, | 352 | file_id, |
294 | name, | 353 | name, |
295 | kind: node.kind(), | 354 | kind: node.kind(), |
296 | full_range: node.text_range(), | 355 | full_range, |
297 | focus_range, | 356 | focus_range, |
298 | // ptr: Some(LocalSyntaxPtr::new(node)), | ||
299 | container_name: None, | 357 | container_name: None, |
300 | description, | 358 | description, |
301 | docs, | 359 | docs, |