mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #3428
3428: Move reference classification to ra_ide_db r=matklad a=matklad
Lost some marks along the way :-(
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
5abc45982b
8 changed files with 90 additions and 122 deletions
|
@ -3,7 +3,7 @@
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{original_range, AssocItem, FieldSource, HasSource, InFile, ModuleSource};
|
use hir::{original_range, AssocItem, FieldSource, HasSource, InFile, ModuleSource};
|
||||||
use ra_db::{FileId, SourceDatabase};
|
use ra_db::{FileId, SourceDatabase};
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::{defs::Definition, RootDatabase};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, DocCommentsOwner, NameOwner},
|
ast::{self, DocCommentsOwner, NameOwner},
|
||||||
match_ast, AstNode, SmolStr,
|
match_ast, AstNode, SmolStr,
|
||||||
|
@ -11,11 +11,7 @@ use ra_syntax::{
|
||||||
TextRange,
|
TextRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::FileSymbol;
|
||||||
// expand::original_range,
|
|
||||||
references::Definition,
|
|
||||||
FileSymbol,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::short_label::ShortLabel;
|
use super::short_label::ShortLabel;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use hir::Semantics;
|
use hir::Semantics;
|
||||||
use ra_ide_db::{defs::classify_name, symbol_index, RootDatabase};
|
use ra_ide_db::{
|
||||||
|
defs::{classify_name, classify_name_ref},
|
||||||
|
symbol_index, RootDatabase,
|
||||||
|
};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self},
|
ast::{self},
|
||||||
match_ast, AstNode,
|
match_ast, AstNode,
|
||||||
|
@ -11,7 +14,6 @@ use ra_syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display::{ToNav, TryToNav},
|
display::{ToNav, TryToNav},
|
||||||
references::classify_name_ref,
|
|
||||||
FilePosition, NavigationTarget, RangeInfo,
|
FilePosition, NavigationTarget, RangeInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ pub(crate) fn reference_definition(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::{assert_eq_text, covers};
|
use test_utils::assert_eq_text;
|
||||||
|
|
||||||
use crate::mock_analysis::analysis_and_position;
|
use crate::mock_analysis::analysis_and_position;
|
||||||
|
|
||||||
|
@ -206,7 +208,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_macros() {
|
fn goto_def_for_macros() {
|
||||||
covers!(goto_def_for_macros);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -223,7 +224,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_macros_from_other_crates() {
|
fn goto_def_for_macros_from_other_crates() {
|
||||||
covers!(goto_def_for_macros);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -335,7 +335,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_methods() {
|
fn goto_def_for_methods() {
|
||||||
covers!(goto_def_for_methods);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -355,7 +354,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_fields() {
|
fn goto_def_for_fields() {
|
||||||
covers!(goto_def_for_fields);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -374,7 +372,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_record_fields() {
|
fn goto_def_for_record_fields() {
|
||||||
covers!(goto_def_for_record_fields);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -787,7 +784,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_field_init_shorthand() {
|
fn goto_def_for_field_init_shorthand() {
|
||||||
covers!(goto_def_for_field_init_shorthand);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use hir::{Adt, HasSource, HirDisplay, Semantics};
|
use hir::{Adt, HasSource, HirDisplay, Semantics};
|
||||||
use ra_ide_db::{
|
use ra_ide_db::{
|
||||||
defs::{classify_name, Definition},
|
defs::{classify_name, classify_name_ref, Definition},
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
};
|
};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
|
@ -14,7 +14,6 @@ use ra_syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
|
display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
|
||||||
references::classify_name_ref,
|
|
||||||
FilePosition, RangeInfo,
|
FilePosition, RangeInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,6 @@
|
||||||
test_utils::marks!(
|
test_utils::marks!(
|
||||||
inserts_angle_brackets_for_generics
|
inserts_angle_brackets_for_generics
|
||||||
inserts_parens_for_function_calls
|
inserts_parens_for_function_calls
|
||||||
goto_def_for_macros
|
|
||||||
goto_def_for_methods
|
|
||||||
goto_def_for_fields
|
|
||||||
goto_def_for_record_fields
|
|
||||||
goto_def_for_field_init_shorthand
|
|
||||||
call_info_bad_offset
|
call_info_bad_offset
|
||||||
dont_complete_current_use
|
dont_complete_current_use
|
||||||
test_resolve_parent_module_on_module_decl
|
test_resolve_parent_module_on_module_decl
|
||||||
|
|
|
@ -9,14 +9,16 @@
|
||||||
//! at the index that the match starts at and its tree parent is
|
//! at the index that the match starts at and its tree parent is
|
||||||
//! resolved to the search element definition, we get a reference.
|
//! resolved to the search element definition, we get a reference.
|
||||||
|
|
||||||
mod classify;
|
|
||||||
mod rename;
|
mod rename;
|
||||||
mod search_scope;
|
mod search_scope;
|
||||||
|
|
||||||
use hir::Semantics;
|
use hir::Semantics;
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use ra_db::SourceDatabaseExt;
|
use ra_db::SourceDatabaseExt;
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::{
|
||||||
|
defs::{classify_name, classify_name_ref, Definition},
|
||||||
|
RootDatabase,
|
||||||
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
algo::find_node_at_offset,
|
algo::find_node_at_offset,
|
||||||
|
@ -27,11 +29,7 @@ use test_utils::tested_by;
|
||||||
|
|
||||||
use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
|
use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::rename::rename;
|
||||||
classify::{classify_name_ref, NameRefClass},
|
|
||||||
rename::rename,
|
|
||||||
};
|
|
||||||
pub(crate) use ra_ide_db::defs::{classify_name, Definition};
|
|
||||||
|
|
||||||
pub use self::search_scope::SearchScope;
|
pub use self::search_scope::SearchScope;
|
||||||
|
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
//! Functions that are used to classify an element from its definition or reference.
|
|
||||||
|
|
||||||
use hir::{Local, PathResolution, Semantics};
|
|
||||||
use ra_ide_db::defs::Definition;
|
|
||||||
use ra_ide_db::RootDatabase;
|
|
||||||
use ra_prof::profile;
|
|
||||||
use ra_syntax::{ast, AstNode};
|
|
||||||
use test_utils::tested_by;
|
|
||||||
|
|
||||||
pub enum NameRefClass {
|
|
||||||
Definition(Definition),
|
|
||||||
FieldShorthand { local: Local, field: Definition },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NameRefClass {
|
|
||||||
pub fn definition(self) -> Definition {
|
|
||||||
match self {
|
|
||||||
NameRefClass::Definition(def) => def,
|
|
||||||
NameRefClass::FieldShorthand { local, field: _ } => Definition::Local(local),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn classify_name_ref(
|
|
||||||
sema: &Semantics<RootDatabase>,
|
|
||||||
name_ref: &ast::NameRef,
|
|
||||||
) -> Option<NameRefClass> {
|
|
||||||
let _p = profile("classify_name_ref");
|
|
||||||
|
|
||||||
let parent = name_ref.syntax().parent()?;
|
|
||||||
|
|
||||||
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
|
||||||
tested_by!(goto_def_for_methods);
|
|
||||||
if let Some(func) = sema.resolve_method_call(&method_call) {
|
|
||||||
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
|
|
||||||
tested_by!(goto_def_for_fields);
|
|
||||||
if let Some(field) = sema.resolve_field(&field_expr) {
|
|
||||||
return Some(NameRefClass::Definition(Definition::StructField(field)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
|
|
||||||
tested_by!(goto_def_for_record_fields);
|
|
||||||
tested_by!(goto_def_for_field_init_shorthand);
|
|
||||||
if let Some((field, local)) = sema.resolve_record_field(&record_field) {
|
|
||||||
let field = Definition::StructField(field);
|
|
||||||
let res = match local {
|
|
||||||
None => NameRefClass::Definition(field),
|
|
||||||
Some(local) => NameRefClass::FieldShorthand { field, local },
|
|
||||||
};
|
|
||||||
return Some(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
|
||||||
tested_by!(goto_def_for_macros);
|
|
||||||
if let Some(macro_def) = sema.resolve_macro_call(¯o_call) {
|
|
||||||
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
|
|
||||||
let resolved = sema.resolve_path(&path)?;
|
|
||||||
let res = match resolved {
|
|
||||||
PathResolution::Def(def) => Definition::ModuleDef(def),
|
|
||||||
PathResolution::AssocItem(item) => {
|
|
||||||
let def = match item {
|
|
||||||
hir::AssocItem::Function(it) => it.into(),
|
|
||||||
hir::AssocItem::Const(it) => it.into(),
|
|
||||||
hir::AssocItem::TypeAlias(it) => it.into(),
|
|
||||||
};
|
|
||||||
Definition::ModuleDef(def)
|
|
||||||
}
|
|
||||||
PathResolution::Local(local) => Definition::Local(local),
|
|
||||||
PathResolution::TypeParam(par) => Definition::TypeParam(par),
|
|
||||||
PathResolution::Macro(def) => Definition::Macro(def),
|
|
||||||
PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
|
|
||||||
};
|
|
||||||
Some(NameRefClass::Definition(res))
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ mod tests;
|
||||||
|
|
||||||
use hir::{Name, Semantics};
|
use hir::{Name, Semantics};
|
||||||
use ra_ide_db::{
|
use ra_ide_db::{
|
||||||
defs::{classify_name, Definition, NameClass},
|
defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass},
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
};
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
|
@ -19,11 +19,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{call_info::call_info_for_token, Analysis, FileId};
|
||||||
call_info::call_info_for_token,
|
|
||||||
references::{classify_name_ref, NameRefClass},
|
|
||||||
Analysis, FileId,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) use html::highlight_as_html;
|
pub(crate) use html::highlight_as_html;
|
||||||
pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag};
|
pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag};
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
|
// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
|
||||||
|
|
||||||
use hir::{
|
use hir::{
|
||||||
Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Name, Semantics,
|
Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
|
||||||
StructField, TypeParam,
|
Semantics, StructField, TypeParam,
|
||||||
};
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
|
@ -117,6 +117,8 @@ impl NameClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
|
pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
|
||||||
|
let _p = profile("classify_name");
|
||||||
|
|
||||||
if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
|
if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
|
||||||
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
|
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
|
||||||
return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
|
return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
|
||||||
|
@ -127,7 +129,6 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
|
||||||
}
|
}
|
||||||
|
|
||||||
fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
|
fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
|
||||||
let _p = profile("classify_name");
|
|
||||||
let parent = name.syntax().parent()?;
|
let parent = name.syntax().parent()?;
|
||||||
|
|
||||||
match_ast! {
|
match_ast! {
|
||||||
|
@ -192,3 +193,74 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum NameRefClass {
|
||||||
|
Definition(Definition),
|
||||||
|
FieldShorthand { local: Local, field: Definition },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NameRefClass {
|
||||||
|
pub fn definition(self) -> Definition {
|
||||||
|
match self {
|
||||||
|
NameRefClass::Definition(def) => def,
|
||||||
|
NameRefClass::FieldShorthand { local, field: _ } => Definition::Local(local),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn classify_name_ref(
|
||||||
|
sema: &Semantics<RootDatabase>,
|
||||||
|
name_ref: &ast::NameRef,
|
||||||
|
) -> Option<NameRefClass> {
|
||||||
|
let _p = profile("classify_name_ref");
|
||||||
|
|
||||||
|
let parent = name_ref.syntax().parent()?;
|
||||||
|
|
||||||
|
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
||||||
|
if let Some(func) = sema.resolve_method_call(&method_call) {
|
||||||
|
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
|
||||||
|
if let Some(field) = sema.resolve_field(&field_expr) {
|
||||||
|
return Some(NameRefClass::Definition(Definition::StructField(field)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
|
||||||
|
if let Some((field, local)) = sema.resolve_record_field(&record_field) {
|
||||||
|
let field = Definition::StructField(field);
|
||||||
|
let res = match local {
|
||||||
|
None => NameRefClass::Definition(field),
|
||||||
|
Some(local) => NameRefClass::FieldShorthand { field, local },
|
||||||
|
};
|
||||||
|
return Some(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
||||||
|
if let Some(macro_def) = sema.resolve_macro_call(¯o_call) {
|
||||||
|
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
|
||||||
|
let resolved = sema.resolve_path(&path)?;
|
||||||
|
let res = match resolved {
|
||||||
|
PathResolution::Def(def) => Definition::ModuleDef(def),
|
||||||
|
PathResolution::AssocItem(item) => {
|
||||||
|
let def = match item {
|
||||||
|
hir::AssocItem::Function(it) => it.into(),
|
||||||
|
hir::AssocItem::Const(it) => it.into(),
|
||||||
|
hir::AssocItem::TypeAlias(it) => it.into(),
|
||||||
|
};
|
||||||
|
Definition::ModuleDef(def)
|
||||||
|
}
|
||||||
|
PathResolution::Local(local) => Definition::Local(local),
|
||||||
|
PathResolution::TypeParam(par) => Definition::TypeParam(par),
|
||||||
|
PathResolution::Macro(def) => Definition::Macro(def),
|
||||||
|
PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
|
||||||
|
};
|
||||||
|
Some(NameRefClass::Definition(res))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue