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/source_binder.rs | 73 +++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir/src/source_binder.rs') 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 }) + } +} -- cgit v1.2.3