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_hir/src/semantics.rs | 7 +++++-- crates/ra_hir/src/source_analyzer.rs | 27 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index a0853957c..afc7f7ee7 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -107,8 +107,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.analyze(field.syntax()).resolve_field(field) } - pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option { - self.analyze(field.syntax()).resolve_record_field(field) + pub fn resolve_record_field( + &self, + field: &ast::RecordField, + ) -> Option<(StructField, Option)> { + self.analyze(field.syntax()).resolve_record_field(self.db, field) } pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option { diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 4c121eb73..015389fb0 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs @@ -5,7 +5,7 @@ //! //! So, this modules should not be used during hir construction, it exists //! purely for "IDE needs". -use std::sync::Arc; +use std::{iter::once, sync::Arc}; use either::Either; use hir_def::{ @@ -25,8 +25,8 @@ use ra_syntax::{ }; use crate::{ - db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static, - Struct, Trait, Type, TypeAlias, TypeParam, + db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModPath, ModuleDef, Path, + PathKind, Static, Struct, Trait, Type, TypeAlias, TypeParam, }; /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of @@ -162,16 +162,27 @@ impl SourceAnalyzer { pub(crate) fn resolve_record_field( &self, + db: &impl HirDatabase, field: &ast::RecordField, - ) -> Option { - let expr_id = match field.expr() { - Some(it) => self.expr_id(&it)?, + ) -> Option<(crate::StructField, Option)> { + let (expr_id, local) = match field.expr() { + Some(it) => (self.expr_id(&it)?, None), None => { let src = InFile { file_id: self.file_id, value: field }; - self.body_source_map.as_ref()?.field_init_shorthand_expr(src)? + let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?; + let local_name = field.name_ref()?.as_name(); + let path = ModPath::from_segments(PathKind::Plain, once(local_name)); + let local = match self.resolver.resolve_path_in_value_ns_fully(db, &path) { + Some(ValueNs::LocalBinding(pat_id)) => { + Some(Local { pat_id, parent: self.resolver.body_owner()? }) + } + _ => None, + }; + (expr_id, local) } }; - self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) + let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?; + Some((struct_field.into(), local)) } pub(crate) fn resolve_record_literal( -- cgit v1.2.3