We are so precise that the fallback creates more confusion, when you can
goto def on an unresolved reference.
use hir::{HasAttrs, ModuleDef, Semantics};
use ide_db::{
defs::{Definition, NameClass, NameRefClass},
use hir::{HasAttrs, ModuleDef, Semantics};
use ide_db::{
defs::{Definition, NameClass, NameRefClass},
- symbol_index, RootDatabase,
};
use syntax::{
ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextSize, TokenAtOffset, T,
};
use crate::{
};
use syntax::{
ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextSize, TokenAtOffset, T,
};
use crate::{
- display::{ToNav, TryToNav},
- doc_links::extract_definitions_from_markdown,
- runnables::doc_owner_to_def,
+ display::TryToNav, doc_links::extract_definitions_from_markdown, runnables::doc_owner_to_def,
FilePosition, NavigationTarget, RangeInfo,
};
FilePosition, NavigationTarget, RangeInfo,
};
return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
}
return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
}
- let nav_targets = match_ast! {
match parent {
ast::NameRef(name_ref) => {
match parent {
ast::NameRef(name_ref) => {
- reference_definition(&sema, Either::Right(&name_ref)).to_vec()
+ reference_definition(&sema, Either::Right(&name_ref))
},
ast::Name(name) => {
let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
},
ast::Name(name) => {
let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
- let nav = def.try_to_nav(sema.db)?;
- vec![nav]
+ def.try_to_nav(sema.db)
},
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
let def = name_class.referenced_or_defined(sema.db);
},
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
let def = name_class.referenced_or_defined(sema.db);
- let nav = def.try_to_nav(sema.db)?;
- vec![nav]
+ def.try_to_nav(sema.db)
- reference_definition(&sema, Either::Left(<)).to_vec()
+ reference_definition(&sema, Either::Left(<))
},
_ => return None,
}
};
},
_ => return None,
}
};
- Some(RangeInfo::new(original_token.text_range(), nav_targets))
+ Some(RangeInfo::new(original_token.text_range(), nav.into_iter().collect()))
}
fn def_for_doc_comment(
}
fn def_for_doc_comment(
-#[derive(Debug)]
-pub(crate) enum ReferenceResult {
- Exact(NavigationTarget),
- Approximate(Vec<NavigationTarget>),
-}
-
-impl ReferenceResult {
- fn to_vec(self) -> Vec<NavigationTarget> {
- match self {
- ReferenceResult::Exact(target) => vec![target],
- ReferenceResult::Approximate(vec) => vec,
- }
- }
-}
-
pub(crate) fn reference_definition(
sema: &Semantics<RootDatabase>,
name_ref: Either<&ast::Lifetime, &ast::NameRef>,
pub(crate) fn reference_definition(
sema: &Semantics<RootDatabase>,
name_ref: Either<&ast::Lifetime, &ast::NameRef>,
+) -> Option<NavigationTarget> {
let name_kind = name_ref.either(
|lifetime| NameRefClass::classify_lifetime(sema, lifetime),
|name_ref| NameRefClass::classify(sema, name_ref),
let name_kind = name_ref.either(
|lifetime| NameRefClass::classify_lifetime(sema, lifetime),
|name_ref| NameRefClass::classify(sema, name_ref),
- );
- if let Some(def) = name_kind {
- let def = def.referenced(sema.db);
- return match def.try_to_nav(sema.db) {
- Some(nav) => ReferenceResult::Exact(nav),
- None => ReferenceResult::Approximate(Vec::new()),
- };
- }
-
- // Fallback index based approach:
- let name = name_ref.either(ast::Lifetime::text, ast::NameRef::text);
- let navs =
- symbol_index::index_resolve(sema.db, name).into_iter().map(|s| s.to_nav(sema.db)).collect();
- ReferenceResult::Approximate(navs)
+ )?;
+ let def = name_kind.referenced(sema.db);
+ def.try_to_nav(sema.db)
fn goto_def_for_macros_from_other_crates() {
check(
r#"
fn goto_def_for_macros_from_other_crates() {
check(
r#"
+//- /lib.rs crate:main deps:foo
use foo::foo;
fn bar() {
$0foo!();
}
use foo::foo;
fn bar() {
$0foo!();
}
+//- /foo/lib.rs crate:foo
#[macro_export]
macro_rules! foo { () => { () } }
//^^^
#[macro_export]
macro_rules! foo { () => { () } }
//^^^
fn goto_def_for_macros_in_use_tree() {
check(
r#"
fn goto_def_for_macros_in_use_tree() {
check(
r#"
+//- /lib.rs crate:main deps:foo
+//- /foo/lib.rs crate:foo
#[macro_export]
macro_rules! foo { () => { () } }
//^^^
#[macro_export]
macro_rules! foo { () => { () } }
//^^^
fn goto_def_for_macro_container() {
check(
r#"
fn goto_def_for_macro_container() {
check(
r#"
+//- /lib.rs crate:main deps:foo
+//- /foo/lib.rs crate:foo
pub mod module {
//^^^^^^
#[macro_export]
pub mod module {
//^^^^^^
#[macro_export]