From 9a6c26e34806a05260170029ace4b64adf484a23 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Jan 2020 16:53:11 +0100 Subject: Move module to SourceBinder --- crates/ra_hir/src/from_source.rs | 38 +++++---------------------- crates/ra_hir/src/source_binder.rs | 44 +++++++++++++++++++++++++++++--- crates/ra_ide/src/goto_definition.rs | 38 +++++++++++++-------------- crates/ra_ide/src/references/classify.rs | 2 +- crates/ra_ide/src/references/rename.rs | 2 +- 5 files changed, 69 insertions(+), 55 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index c766c3f0b..eb76aecb1 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -2,46 +2,22 @@ //! file. use hir_def::{nameres::ModuleSource, ModuleId}; -use hir_expand::name::AsName; use ra_db::FileId; use ra_prof::profile; -use ra_syntax::ast::{self, AstNode, NameOwner}; -use crate::{db::DefDatabase, InFile, Module}; +use crate::{ + db::{DefDatabase, HirDatabase}, + InFile, Module, +}; impl Module { - pub fn from_declaration(db: &impl DefDatabase, src: InFile) -> Option { - let _p = profile("Module::from_declaration"); - let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); - - let parent_module = match parent_declaration { - Some(parent_declaration) => { - let src_parent = InFile { file_id: src.file_id, value: parent_declaration }; - Module::from_declaration(db, src_parent) - } - None => { - let source_file = db.parse(src.file_id.original_file(db)).tree(); - let src_parent = - InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) }; - Module::from_definition(db, src_parent) - } - }?; - - let child_name = src.value.name()?.as_name(); - let def_map = db.crate_def_map(parent_module.id.krate); - let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?; - Some(parent_module.with_module_id(*child_id)) - } - - pub fn from_definition(db: &impl DefDatabase, src: InFile) -> Option { + pub fn from_definition(db: &impl HirDatabase, src: InFile) -> Option { let _p = profile("Module::from_definition"); + let mut sb = crate::SourceBinder::new(db); match src.value { ModuleSource::Module(ref module) => { assert!(!module.has_semi()); - return Module::from_declaration( - db, - InFile { file_id: src.file_id, value: module.clone() }, - ); + return sb.to_def(InFile { file_id: src.file_id, value: module.clone() }); } ModuleSource::SourceFile(_) => (), }; diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 00f48177b..26eedbb2c 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -11,12 +11,15 @@ use hir_def::{ ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, }; -use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind}; +use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind}; use ra_prof::profile; -use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; +use ra_syntax::{ + ast::{self, NameOwner}, + match_ast, AstNode, SyntaxNode, TextUnit, +}; use rustc_hash::FxHashMap; -use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam}; +use crate::{db::HirDatabase, Local, Module, ModuleSource, SourceAnalyzer, TypeParam}; pub struct SourceBinder<'a, DB> { pub db: &'a DB, @@ -306,3 +309,38 @@ impl ToDef for ast::TypeParam { Some(TypeParam { id }) } } + +impl ToDef for ast::Module { + type Def = Module; + + fn to_def( + sb: &mut SourceBinder<'_, DB>, + src: InFile, + ) -> Option { + { + let _p = profile("ast::Module::to_def"); + let parent_declaration = + src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); + + let parent_module = match parent_declaration { + Some(parent_declaration) => { + let src_parent = InFile { file_id: src.file_id, value: parent_declaration }; + sb.to_def(src_parent) + } + None => { + let source_file = sb.db.parse(src.file_id.original_file(sb.db)).tree(); + let src_parent = InFile { + file_id: src.file_id, + value: ModuleSource::SourceFile(source_file), + }; + Module::from_definition(sb.db, src_parent) + } + }?; + + let child_name = src.value.name()?.as_name(); + let def_map = sb.db.crate_def_map(parent_module.id.krate); + let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?; + Some(parent_module.with_module_id(*child_id)) + } + } +} diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index f2b5af321..5a12a619c 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs @@ -24,13 +24,14 @@ pub(crate) fn goto_definition( let original_token = pick_best(file.token_at_offset(position.offset))?; let token = descend_into_macros(db, position.file_id, original_token.clone()); + let mut sb = SourceBinder::new(db); let nav_targets = match_ast! { match (token.value.parent()) { ast::NameRef(name_ref) => { - reference_definition(db, token.with_value(&name_ref)).to_vec() + reference_definition(&mut sb, token.with_value(&name_ref)).to_vec() }, ast::Name(name) => { - name_definition(db, token.with_value(&name))? + name_definition(&mut sb, token.with_value(&name))? }, _ => return None, } @@ -67,20 +68,19 @@ impl ReferenceResult { } pub(crate) fn reference_definition( - db: &RootDatabase, + sb: &mut SourceBinder, name_ref: InFile<&ast::NameRef>, ) -> ReferenceResult { use self::ReferenceResult::*; - let mut sb = SourceBinder::new(db); - let name_kind = classify_name_ref(&mut sb, name_ref).map(|d| d.kind); + let name_kind = classify_name_ref(sb, name_ref).map(|d| d.kind); match name_kind { - Some(Macro(it)) => return Exact(it.to_nav(db)), - Some(Field(it)) => return Exact(it.to_nav(db)), - Some(TypeParam(it)) => return Exact(it.to_nav(db)), - Some(AssocItem(it)) => return Exact(it.to_nav(db)), - Some(Local(it)) => return Exact(it.to_nav(db)), - Some(Def(def)) => match NavigationTarget::from_def(db, def) { + Some(Macro(it)) => return Exact(it.to_nav(sb.db)), + Some(Field(it)) => return Exact(it.to_nav(sb.db)), + Some(TypeParam(it)) => return Exact(it.to_nav(sb.db)), + Some(AssocItem(it)) => return Exact(it.to_nav(sb.db)), + Some(Local(it)) => return Exact(it.to_nav(sb.db)), + Some(Def(def)) => match NavigationTarget::from_def(sb.db, def) { Some(nav) => return Exact(nav), None => return Approximate(vec![]), }, @@ -88,21 +88,21 @@ pub(crate) fn reference_definition( // FIXME: ideally, this should point to the type in the impl, and // not at the whole impl. And goto **type** definition should bring // us to the actual type - return Exact(imp.to_nav(db)); + return Exact(imp.to_nav(sb.db)); } None => {} }; // Fallback index based approach: - let navs = crate::symbol_index::index_resolve(db, name_ref.value) + let navs = crate::symbol_index::index_resolve(sb.db, name_ref.value) .into_iter() - .map(|s| s.to_nav(db)) + .map(|s| s.to_nav(sb.db)) .collect(); Approximate(navs) } -pub(crate) fn name_definition( - db: &RootDatabase, +fn name_definition( + sb: &mut SourceBinder, name: InFile<&ast::Name>, ) -> Option> { let parent = name.value.syntax().parent()?; @@ -110,14 +110,14 @@ pub(crate) fn name_definition( if let Some(module) = ast::Module::cast(parent.clone()) { if module.has_semi() { let src = name.with_value(module); - if let Some(child_module) = hir::Module::from_declaration(db, src) { - let nav = child_module.to_nav(db); + if let Some(child_module) = sb.to_def(src) { + let nav = child_module.to_nav(sb.db); return Some(vec![nav]); } } } - if let Some(nav) = named_target(db, name.with_value(&parent)) { + if let Some(nav) = named_target(sb.db, name.with_value(&parent)) { return Some(vec![nav]); } diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index 82a18a0a5..cb7da1fff 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs @@ -42,7 +42,7 @@ pub(crate) fn classify_name( hir::Module::from_definition(sb.db, src) } else { let src = name.with_value(it); - hir::Module::from_declaration(sb.db, src) + sb.to_def(src) } }?; Some(from_module_def(sb.db, def.into(), None)) diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index e02985dcd..626efb603 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -63,7 +63,7 @@ fn rename_mod( let mut source_file_edits = Vec::new(); let mut file_system_edits = Vec::new(); let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() }; - if let Some(module) = hir::Module::from_declaration(db, module_src) { + if let Some(module) = hir::SourceBinder::new(db).to_def(module_src) { let src = module.definition_source(db); let file_id = src.file_id.original_file(db); match src.value { -- cgit v1.2.3