mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
use find_definition in go to
This commit is contained in:
parent
887b7ddc37
commit
569ac5bee1
@ -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, <) {
|
||||
Some(name_class) => {
|
||||
match name_class {
|
||||
NameClass::Definition(def) => def_to_nav(sema.db, def),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
None => reference_definition(&sema, Either::Left(<)),
|
||||
}
|
||||
},
|
||||
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()
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user