From 7aa627fe582e8811e9e98b58c8a6da80054ba2e3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Jan 2020 16:37:51 +0100 Subject: Move more stuff to SourceBinder --- crates/ra_hir/src/from_source.rs | 59 ++------------------------ crates/ra_hir/src/source_binder.rs | 73 ++++++++++++++++++++++++++++---- crates/ra_ide/src/references/classify.rs | 4 +- 3 files changed, 70 insertions(+), 66 deletions(-) diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index caaff012a..c766c3f0b 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -1,66 +1,13 @@ //! Finds a corresponding hir data structure for a syntax node in a specific //! file. -use hir_def::{ - child_by_source::ChildBySource, keys, nameres::ModuleSource, GenericDefId, ModuleId, -}; +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}, - match_ast, -}; +use ra_syntax::ast::{self, AstNode, NameOwner}; -use crate::{ - db::{DefDatabase, HirDatabase}, - DefWithBody, InFile, Local, Module, SourceBinder, TypeParam, -}; - -impl Local { - pub fn from_source(db: &impl HirDatabase, src: InFile) -> Option { - let mut sb = SourceBinder::new(db); - let file_id = src.file_id; - let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { - let res = match_ast! { - match it { - ast::ConstDef(value) => { sb.to_def(InFile { value, file_id})?.into() }, - ast::StaticDef(value) => { sb.to_def(InFile { value, file_id})?.into() }, - ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.into() }, - _ => return None, - } - }; - Some(res) - })?; - let (_body, source_map) = db.body_with_source_map(parent.into()); - let src = src.map(ast::Pat::from); - let pat_id = source_map.node_pat(src.as_ref())?; - Some(Local { parent, pat_id }) - } -} - -impl TypeParam { - pub fn from_source(db: &impl HirDatabase, src: InFile) -> Option { - let mut sb = SourceBinder::new(db); - let file_id = src.file_id; - let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { - let res = match_ast! { - match it { - ast::FnDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - ast::StructDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - ast::EnumDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - ast::TraitDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - ast::TypeAliasDef(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - ast::ImplBlock(value) => { sb.to_def(InFile { value, file_id})?.id.into() }, - _ => return None, - } - }; - Some(res) - })?; - let &id = parent.child_by_source(db)[keys::TYPE_PARAM].get(&src)?; - Some(TypeParam { id }) - } -} +use crate::{db::DefDatabase, InFile, Module}; impl Module { pub fn from_declaration(db: &impl DefDatabase, src: InFile) -> Option { diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c02175c06..97e3aef34 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -8,15 +8,15 @@ use hir_def::{ dyn_map::DynMap, keys::{self, Key}, resolver::{HasResolver, Resolver}, - ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ImplId, ModuleId, StaticId, - StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, + ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, + StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, }; use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind}; use ra_prof::profile; use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; use rustc_hash::FxHashMap; -use crate::{db::HirDatabase, ModuleSource, SourceAnalyzer}; +use crate::{db::HirDatabase, Local, ModuleSource, SourceAnalyzer, TypeParam}; pub struct SourceBinder<'a, DB> { pub db: &'a DB, @@ -53,8 +53,7 @@ impl SourceBinder<'_, DB> { } pub fn to_def(&mut self, src: InFile) -> Option { - let id: T::ID = self.to_id(src)?; - Some(id.into()) + T::to_def(self, src) } fn to_id(&mut self, src: InFile) -> Option { @@ -110,20 +109,27 @@ impl SourceBinder<'_, DB> { } } -pub trait ToId: Sized + AstNode + 'static { +pub trait ToId: Sized { type ID: Sized + Copy + 'static; fn to_id(sb: &mut SourceBinder<'_, DB>, src: InFile) -> Option; } -pub trait ToDef: ToId { - type Def: From; +pub trait ToDef: Sized + AstNode + 'static { + type Def; + fn to_def( + sb: &mut SourceBinder<'_, DB>, + src: InFile, + ) -> Option; } macro_rules! to_def_impls { ($(($def:path, $ast:path)),* ,) => {$( impl ToDef for $ast { type Def = $def; + fn to_def(sb: &mut SourceBinder<'_, DB>, src: InFile) + -> Option + { sb.to_id(src).map(Into::into) } } )*} } @@ -230,3 +236,54 @@ impl ToId for ast::MacroCall { Some(MacroDefId { krate, ast_id, kind }) } } + +impl ToDef for ast::BindPat { + type Def = Local; + + fn to_def(sb: &mut SourceBinder<'_, DB>, src: InFile) -> Option { + let file_id = src.file_id; + let parent: DefWithBodyId = src.value.syntax().ancestors().find_map(|it| { + let res = match_ast! { + match it { + ast::ConstDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::StaticDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::FnDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + _ => return None, + } + }; + Some(res) + })?; + let (_body, source_map) = sb.db.body_with_source_map(parent); + let src = src.map(ast::Pat::from); + let pat_id = source_map.node_pat(src.as_ref())?; + Some(Local { parent: parent.into(), pat_id }) + } +} + +impl ToDef for ast::TypeParam { + type Def = TypeParam; + + fn to_def( + sb: &mut SourceBinder<'_, DB>, + src: InFile, + ) -> Option { + let mut sb = SourceBinder::new(sb.db); + let file_id = src.file_id; + let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { + let res = match_ast! { + match it { + ast::FnDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::StructDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::EnumDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::TraitDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::TypeAliasDef(value) => { sb.to_id(InFile { value, file_id})?.into() }, + ast::ImplBlock(value) => { sb.to_id(InFile { value, file_id})?.into() }, + _ => return None, + } + }; + Some(res) + })?; + let &id = parent.child_by_source(sb.db)[keys::TYPE_PARAM].get(&src)?; + Some(TypeParam { id }) + } +} diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index dcffc3df2..82a18a0a5 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs @@ -22,7 +22,7 @@ pub(crate) fn classify_name( match parent { ast::BindPat(it) => { let src = name.with_value(it); - let local = hir::Local::from_source(sb.db, src)?; + let local = sb.to_def(src)?; Some(NameDefinition { visibility: None, container: local.module(sb.db), @@ -114,7 +114,7 @@ pub(crate) fn classify_name( }, ast::TypeParam(it) => { let src = name.with_value(it); - let def = hir::TypeParam::from_source(sb.db, src)?; + let def = sb.to_def(src)?; Some(NameDefinition { visibility: None, container: def.module(sb.db), -- cgit v1.2.3