From 2716a1fa3f8a7410248724a6ce5d4c28837db682 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 2 Mar 2020 19:00:38 +0100 Subject: More principled approach for gotodef for field shorhand Callers can now decide for themselves if they should prefer field or local definition. By default, it's the local. --- crates/ra_ide/src/references/classify.rs | 35 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'crates/ra_ide/src/references') diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index fdd07d8d1..e837ca8a3 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs @@ -1,6 +1,6 @@ //! Functions that are used to classify an element from its definition or reference. -use hir::{PathResolution, Semantics}; +use hir::{Local, PathResolution, Semantics}; use ra_ide_db::defs::NameDefinition; use ra_ide_db::RootDatabase; use ra_prof::profile; @@ -9,10 +9,24 @@ use test_utils::tested_by; pub use ra_ide_db::defs::{from_module_def, from_struct_field}; +pub enum NameRefClass { + NameDefinition(NameDefinition), + FieldShorthand { local: Local, field: NameDefinition }, +} + +impl NameRefClass { + pub fn definition(self) -> NameDefinition { + match self { + NameRefClass::NameDefinition(def) => def, + NameRefClass::FieldShorthand { local, field: _ } => NameDefinition::Local(local), + } + } +} + pub(crate) fn classify_name_ref( sema: &Semantics, name_ref: &ast::NameRef, -) -> Option { +) -> Option { let _p = profile("classify_name_ref"); let parent = name_ref.syntax().parent()?; @@ -20,29 +34,34 @@ pub(crate) fn classify_name_ref( 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(from_module_def(func.into())); + return Some(NameRefClass::NameDefinition(NameDefinition::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(from_struct_field(field)); + return Some(NameRefClass::NameDefinition(NameDefinition::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_def) = sema.resolve_record_field(&record_field) { - return Some(from_struct_field(field_def)); + if let Some((field, local)) = sema.resolve_record_field(&record_field) { + let field = NameDefinition::StructField(field); + let res = match local { + None => NameRefClass::NameDefinition(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(NameDefinition::Macro(macro_def)); + return Some(NameRefClass::NameDefinition(NameDefinition::Macro(macro_def))); } } @@ -63,5 +82,5 @@ pub(crate) fn classify_name_ref( PathResolution::Macro(def) => NameDefinition::Macro(def), PathResolution::SelfType(impl_def) => NameDefinition::SelfType(impl_def), }; - Some(res) + Some(NameRefClass::NameDefinition(res)) } -- cgit v1.2.3