aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs99
1 files changed, 44 insertions, 55 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index f7ad08515..b30ef8e05 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -1,16 +1,17 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{AssocItem, Either, FieldSource, HasSource, ModuleSource}; 3use hir::{AssocItem, Either, FieldSource, HasSource, ModuleSource, Source};
4use ra_db::{FileId, SourceDatabase}; 4use ra_db::{FileId, SourceDatabase};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, DocCommentsOwner, NameOwner}, 6 ast::{self, DocCommentsOwner, NameOwner},
7 match_ast, AstNode, SmolStr, 7 match_ast, AstNode, SmolStr,
8 SyntaxKind::{self, BIND_PAT}, 8 SyntaxKind::{self, BIND_PAT},
9 SyntaxNode, TextRange, 9 TextRange,
10}; 10};
11 11
12use crate::{db::RootDatabase, expand::original_range, FileSymbol};
13
12use super::short_label::ShortLabel; 14use super::short_label::ShortLabel;
13use crate::{db::RootDatabase, FileSymbol};
14 15
15/// `NavigationTarget` represents and element in the editor's UI which you can 16/// `NavigationTarget` represents and element in the editor's UI which you can
16/// click on to navigate to a particular piece of code. 17/// click on to navigate to a particular piece of code.
@@ -79,13 +80,13 @@ impl NavigationTarget {
79 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { 80 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
80 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 81 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
81 if let Some(src) = module.declaration_source(db) { 82 if let Some(src) = module.declaration_source(db) {
82 let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); 83 let frange = original_range(db, src.as_ref().map(|it| it.syntax()));
83 return NavigationTarget::from_syntax( 84 return NavigationTarget::from_syntax(
84 file_id, 85 frange.file_id,
85 name, 86 name,
86 None, 87 None,
87 text_range, 88 frange.range,
88 src.ast.syntax(), 89 src.ast.syntax().kind(),
89 src.ast.doc_comment_text(), 90 src.ast.doc_comment_text(),
90 src.ast.short_label(), 91 src.ast.short_label(),
91 ); 92 );
@@ -140,22 +141,22 @@ impl NavigationTarget {
140 /// Allows `NavigationTarget` to be created from a `NameOwner` 141 /// Allows `NavigationTarget` to be created from a `NameOwner`
141 pub(crate) fn from_named( 142 pub(crate) fn from_named(
142 db: &RootDatabase, 143 db: &RootDatabase,
143 file_id: hir::HirFileId, 144 node: Source<&dyn ast::NameOwner>,
144 node: &impl ast::NameOwner,
145 docs: Option<String>, 145 docs: Option<String>,
146 description: Option<String>, 146 description: Option<String>,
147 ) -> NavigationTarget { 147 ) -> NavigationTarget {
148 //FIXME: use `_` instead of empty string 148 //FIXME: use `_` instead of empty string
149 let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); 149 let name = node.ast.name().map(|it| it.text().clone()).unwrap_or_default();
150 let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1); 150 let focus_range =
151 let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax()); 151 node.ast.name().map(|it| original_range(db, node.with_ast(it.syntax())).range);
152 let frange = original_range(db, node.map(|it| it.syntax()));
152 153
153 NavigationTarget::from_syntax( 154 NavigationTarget::from_syntax(
154 file_id, 155 frange.file_id,
155 name, 156 name,
156 focus_range, 157 focus_range,
157 full_range, 158 frange.range,
158 node.syntax(), 159 node.ast.syntax().kind(),
159 docs, 160 docs,
160 description, 161 description,
161 ) 162 )
@@ -166,14 +167,14 @@ impl NavigationTarget {
166 name: SmolStr, 167 name: SmolStr,
167 focus_range: Option<TextRange>, 168 focus_range: Option<TextRange>,
168 full_range: TextRange, 169 full_range: TextRange,
169 node: &SyntaxNode, 170 kind: SyntaxKind,
170 docs: Option<String>, 171 docs: Option<String>,
171 description: Option<String>, 172 description: Option<String>,
172 ) -> NavigationTarget { 173 ) -> NavigationTarget {
173 NavigationTarget { 174 NavigationTarget {
174 file_id, 175 file_id,
175 name, 176 name,
176 kind: node.kind(), 177 kind,
177 full_range, 178 full_range,
178 focus_range, 179 focus_range,
179 container_name: None, 180 container_name: None,
@@ -218,8 +219,7 @@ where
218 let src = self.source(db); 219 let src = self.source(db);
219 NavigationTarget::from_named( 220 NavigationTarget::from_named(
220 db, 221 db,
221 src.file_id, 222 src.as_ref().map(|it| it as &dyn ast::NameOwner),
222 &src.ast,
223 src.ast.doc_comment_text(), 223 src.ast.doc_comment_text(),
224 src.ast.short_label(), 224 src.ast.short_label(),
225 ) 225 )
@@ -230,29 +230,29 @@ impl ToNav for hir::Module {
230 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 230 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
231 let src = self.definition_source(db); 231 let src = self.definition_source(db);
232 let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 232 let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default();
233 match src.ast { 233 match &src.ast {
234 ModuleSource::SourceFile(node) => { 234 ModuleSource::SourceFile(node) => {
235 let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); 235 let frange = original_range(db, src.with_ast(node.syntax()));
236 236
237 NavigationTarget::from_syntax( 237 NavigationTarget::from_syntax(
238 file_id, 238 frange.file_id,
239 name, 239 name,
240 None, 240 None,
241 text_range, 241 frange.range,
242 node.syntax(), 242 node.syntax().kind(),
243 None, 243 None,
244 None, 244 None,
245 ) 245 )
246 } 246 }
247 ModuleSource::Module(node) => { 247 ModuleSource::Module(node) => {
248 let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); 248 let frange = original_range(db, src.with_ast(node.syntax()));
249 249
250 NavigationTarget::from_syntax( 250 NavigationTarget::from_syntax(
251 file_id, 251 frange.file_id,
252 name, 252 name,
253 None, 253 None,
254 text_range, 254 frange.range,
255 node.syntax(), 255 node.syntax().kind(),
256 node.doc_comment_text(), 256 node.doc_comment_text(),
257 node.short_label(), 257 node.short_label(),
258 ) 258 )
@@ -264,14 +264,14 @@ impl ToNav for hir::Module {
264impl ToNav for hir::ImplBlock { 264impl ToNav for hir::ImplBlock {
265 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 265 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
266 let src = self.source(db); 266 let src = self.source(db);
267 let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); 267 let frange = original_range(db, src.as_ref().map(|it| it.syntax()));
268 268
269 NavigationTarget::from_syntax( 269 NavigationTarget::from_syntax(
270 file_id, 270 frange.file_id,
271 "impl".into(), 271 "impl".into(),
272 None, 272 None,
273 text_range, 273 frange.range,
274 src.ast.syntax(), 274 src.ast.syntax().kind(),
275 None, 275 None,
276 None, 276 None,
277 ) 277 )
@@ -282,22 +282,21 @@ impl ToNav for hir::StructField {
282 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 282 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
283 let src = self.source(db); 283 let src = self.source(db);
284 284
285 match src.ast { 285 match &src.ast {
286 FieldSource::Named(it) => NavigationTarget::from_named( 286 FieldSource::Named(it) => NavigationTarget::from_named(
287 db, 287 db,
288 src.file_id, 288 src.with_ast(it),
289 &it,
290 it.doc_comment_text(), 289 it.doc_comment_text(),
291 it.short_label(), 290 it.short_label(),
292 ), 291 ),
293 FieldSource::Pos(it) => { 292 FieldSource::Pos(it) => {
294 let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax()); 293 let frange = original_range(db, src.with_ast(it.syntax()));
295 NavigationTarget::from_syntax( 294 NavigationTarget::from_syntax(
296 file_id, 295 frange.file_id,
297 "".into(), 296 "".into(),
298 None, 297 None,
299 text_range, 298 frange.range,
300 it.syntax(), 299 it.syntax().kind(),
301 None, 300 None,
302 None, 301 None,
303 ) 302 )
@@ -310,7 +309,12 @@ impl ToNav for hir::MacroDef {
310 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 309 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
311 let src = self.source(db); 310 let src = self.source(db);
312 log::debug!("nav target {:#?}", src.ast.syntax()); 311 log::debug!("nav target {:#?}", src.ast.syntax());
313 NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None) 312 NavigationTarget::from_named(
313 db,
314 src.as_ref().map(|it| it as &dyn ast::NameOwner),
315 src.ast.doc_comment_text(),
316 None,
317 )
314 } 318 }
315} 319}
316 320
@@ -360,21 +364,6 @@ impl ToNav for hir::Local {
360 } 364 }
361} 365}
362 366
363fn find_range_from_node(
364 db: &RootDatabase,
365 src: hir::HirFileId,
366 node: &SyntaxNode,
367) -> (FileId, TextRange) {
368 let text_range = node.text_range();
369 let (file_id, text_range) = src
370 .expansion_info(db)
371 .and_then(|expansion_info| expansion_info.find_range(text_range))
372 .unwrap_or((src, text_range));
373
374 // FIXME: handle recursive macro generated macro
375 (file_id.original_file(db), text_range)
376}
377
378pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> { 367pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
379 let parse = db.parse(symbol.file_id); 368 let parse = db.parse(symbol.file_id);
380 let node = symbol.ptr.to_node(parse.tree().syntax()); 369 let node = symbol.ptr.to_node(parse.tree().syntax());