Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
| -rw-r--r-- | crates/ide/src/goto_definition.rs | 83 |
1 files changed, 36 insertions, 47 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index ec5d462da2..4c01231f4a 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -1,6 +1,5 @@ use std::convert::TryInto; -use crate::hover::find_definition; use crate::{ display::TryToNav, doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def}, @@ -10,11 +9,11 @@ use hir::{AsAssocItem, InFile, ModuleDef, Semantics}; use ide_db::{ base_db::{AnchoredPath, FileId, FileLoader}, defs::Definition, - helpers::{pick_best_token, try_resolve_derive_input_at}, + helpers::pick_best_token, RootDatabase, }; use itertools::Itertools; -use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T}; +use syntax::{ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T}; // Feature: Go to Definition // @@ -57,22 +56,22 @@ pub(crate) fn goto_definition( .into_iter() .filter_map(|token| { let parent = token.parent()?; - let result = find_definition(&sema, &parent) - .flat_map(|def| { - try_find_trait_item_definition(sema.db, &def) - .unwrap_or_else(|| def_to_nav(sema.db, def)) - }) - .collect::<Vec<_>>(); - if !result.is_empty() { - return Some(result); - } - match_ast! { - match parent { - ast::TokenTree(tt) => - try_lookup_include_path_or_derive(&sema, tt, token, position.file_id), - _ => None + if let Some(tt) = ast::TokenTree::cast(parent.clone()) { + if let x @ Some(_) = + try_lookup_include_path(&sema, tt, token.clone(), position.file_id) + { + return x; } } + Some( + Definition::from_node(&sema, &token) + .into_iter() + .flat_map(|def| { + try_find_trait_item_definition(sema.db, &def) + .unwrap_or_else(|| def_to_nav(sema.db, def)) + }) + .collect::<Vec<_>>(), + ) }) .flatten() .unique() @@ -81,41 +80,31 @@ pub(crate) fn goto_definition( Some(RangeInfo::new(original_token.text_range(), navs)) } -fn try_lookup_include_path_or_derive( +fn try_lookup_include_path( sema: &Semantics<RootDatabase>, tt: ast::TokenTree, token: SyntaxToken, file_id: FileId, ) -> Option<Vec<NavigationTarget>> { - match ast::String::cast(token.clone()) { - Some(token) => { - let path = token.value()?.into_owned(); - let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; - let name = macro_call.path()?.segment()?.name_ref()?; - if !matches!(&*name.text(), "include" | "include_str" | "include_bytes") { - return None; - } - let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?; - let size = sema.db.file_text(file_id).len().try_into().ok()?; - Some(vec![NavigationTarget { - file_id, - full_range: TextRange::new(0.into(), size), - name: path.into(), - focus_range: None, - kind: None, - container_name: None, - description: None, - docs: None, - }]) - } - None => try_resolve_derive_input_at( - sema, - &tt.syntax().ancestors().nth(2).and_then(ast::Attr::cast)?, - &token, - ) - .and_then(|it| it.try_to_nav(sema.db)) - .map(|it| vec![it]), - } + let token = ast::String::cast(token.clone())?; + let path = token.value()?.into_owned(); + let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; + let name = macro_call.path()?.segment()?.name_ref()?; + if !matches!(&*name.text(), "include" | "include_str" | "include_bytes") { + return None; + } + let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?; + let size = sema.db.file_text(file_id).len().try_into().ok()?; + Some(vec![NavigationTarget { + file_id, + full_range: TextRange::new(0.into(), size), + name: path.into(), + focus_range: None, + kind: None, + container_name: None, + description: None, + docs: None, + }]) } /// finds the trait definition of an impl'd item |