Unnamed repository; edit this file 'description' to name the repository.
use find_definition in go to
hamidreza kalbasi 2021-09-22
parent 887b7dd · commit 569ac5b
-rw-r--r--crates/ide/src/goto_definition.rs55
-rw-r--r--crates/ide/src/hover.rs71
-rw-r--r--crates/ide/src/lib.rs2
3 files changed, 64 insertions, 64 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index b2d0fead87..c2fdc8dc7c 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,5 +1,11 @@
use std::{convert::TryInto, iter};
+use crate::hover::find_definition;
+use crate::{
+ display::{ToNav, TryToNav},
+ doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
+ FilePosition, NavigationTarget, RangeInfo,
+};
use either::Either;
use hir::{AsAssocItem, InFile, ModuleDef, Semantics};
use ide_db::{
@@ -11,12 +17,6 @@ use ide_db::{
use itertools::Itertools;
use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T};
-use crate::{
- display::{ToNav, TryToNav},
- doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
- FilePosition, NavigationTarget, RangeInfo,
-};
-
// Feature: Go to Definition
//
// Navigates to the definition of an identifier.
@@ -58,39 +58,22 @@ pub(crate) fn goto_definition(
.into_iter()
.filter_map(|token| {
let parent = token.parent()?;
- let navs = match_ast! {
+ 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::NameRef(name_ref) => {
- reference_definition(&sema, Either::Right(&name_ref))
- },
- ast::Name(name) => {
- match NameClass::classify(&sema, &name)? {
- NameClass::Definition(def) | NameClass::ConstReference(def) => {
- try_find_trait_item_definition(sema.db, &def)
- .unwrap_or_else(|| def_to_nav(sema.db, def))
- }
- NameClass::PatFieldShorthand { local_def, field_ref } => {
- local_and_field_to_nav(sema.db, local_def, field_ref)
- },
- }
- },
- ast::Lifetime(lt) => {
- match NameClass::classify_lifetime(&sema, &lt) {
- Some(name_class) => {
- match name_class {
- NameClass::Definition(def) => def_to_nav(sema.db, def),
- _ => return None,
- }
- }
- None => reference_definition(&sema, Either::Left(&lt)),
- }
- },
ast::TokenTree(tt) =>
- try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
- _ => return None,
+ try_lookup_include_path_or_derive(&sema, tt, token, position.file_id),
+ _ => None
}
- };
- Some(navs)
+ }
})
.flatten()
.unique()
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 0d916acade..a01e272e53 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -1,4 +1,4 @@
-use std::{collections::HashSet, ops::ControlFlow};
+use std::{collections::HashSet, iter, ops::ControlFlow};
use either::Either;
use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
@@ -199,7 +199,7 @@ fn find_hover_result(
// so don't add them to the `seen` duplicate check
let mut add_to_seen_definitions = true;
- let definition = find_definition(sema, node).or_else(|| {
+ let definition = find_definition(sema, node).next().or_else(|| {
// intra-doc links
// FIXME: move comment + attribute special cases somewhere else to simplify control flow,
// hopefully simplifying the return type of this function in the process
@@ -724,34 +724,51 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
def.module(db).map(|module| render_path(db, module, definition_owner_name(db, def)))
}
-pub(crate) fn find_definition(
- sema: &Semantics<RootDatabase>,
+pub(crate) fn find_definition<'a>(
+ sema: &'a Semantics<RootDatabase>,
node: &SyntaxNode,
-) -> Option<Definition> {
- match_ast! {
- match node {
- ast::Name(name) => NameClass::classify(sema, &name).map(|class| match class {
- NameClass::Definition(it) | NameClass::ConstReference(it) => it,
- NameClass::PatFieldShorthand { local_def, field_ref: _ } => Definition::Local(local_def),
- }),
- ast::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref).map(|class| match class {
- NameRefClass::Definition(def) => def,
- NameRefClass::FieldShorthand { local_ref: _, field_ref } => {
- Definition::Field(field_ref)
- }
- }),
- ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime).map_or_else(
- || {
- NameRefClass::classify_lifetime(&sema, &lifetime).and_then(|class| match class {
- NameRefClass::Definition(it) => Some(it),
- _ => None,
- })
+) -> impl Iterator<Item = Definition> + 'a {
+ iter::once(node.clone()).flat_map(move |node| {
+ match_ast! {
+ match node {
+ ast::Name(name) => {
+ let class = if let Some(x) = NameClass::classify(&sema, &name) {
+ x
+ } else {
+ return vec![];
+ };
+ match class {
+ NameClass::Definition(it) | NameClass::ConstReference(it) => vec![it],
+ NameClass::PatFieldShorthand { local_def, field_ref } => vec![Definition::Local(local_def), Definition::Field(field_ref)],
+ }
},
- NameClass::defined,
- ),
- _ => None,
+ ast::NameRef(name_ref) => {
+ let class = if let Some(x) = NameRefClass::classify(sema, &name_ref) {
+ x
+ } else {
+ return vec![];
+ };
+ match class {
+ NameRefClass::Definition(def) => vec![def],
+ NameRefClass::FieldShorthand { local_ref, field_ref } => {
+ vec![Definition::Field(field_ref), Definition::Local(local_ref)]
+ }
+ }
+ },
+ ast::Lifetime(lifetime) => {
+ (if let Some(x) = NameClass::classify_lifetime(&sema, &lifetime) {
+ NameClass::defined(x)
+ } else {
+ NameRefClass::classify_lifetime(&sema, &lifetime).and_then(|class| match class {
+ NameRefClass::Definition(it) => Some(it),
+ _ => None,
+ })
+ }).into_iter().collect()
+ },
+ _ => vec![],
+ }
}
- }
+ })
}
pub(crate) fn hover_for_definition(
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 21872c81d1..9ea0fe171c 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -35,7 +35,7 @@ mod goto_declaration;
mod goto_definition;
mod goto_implementation;
mod goto_type_definition;
-mod hover;
+pub mod hover;
mod inlay_hints;
mod join_lines;
mod markdown_remove;