From 8e65b773874909985b6ffc9247ea9dfbaac6a02b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 15:50:16 +0100 Subject: Dedupe from_source impls --- crates/ra_hir/src/from_source.rs | 111 ++++++++++++--------------------------- 1 file changed, 34 insertions(+), 77 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f7411c5cf..7abb4bd75 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -1,7 +1,8 @@ //! FIXME: write short doc here use hir_def::{ - child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, EnumVariantId, - GenericDefId, ModuleId, VariantId, + child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, + ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId, + TraitId, TypeAliasId, UnionId, VariantId, }; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ @@ -20,81 +21,47 @@ pub trait FromSource: Sized { fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option; } -impl FromSource for Struct { - type Ast = ast::StructDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STRUCT] - .get(&src) - .copied() - .map(Struct::from) - } -} -impl FromSource for Union { - type Ast = ast::UnionDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::UNION] - .get(&src) - .copied() - .map(Union::from) - } -} -impl FromSource for Enum { - type Ast = ast::EnumDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::ENUM] - .get(&src) - .copied() - .map(Enum::from) - } -} -impl FromSource for Trait { - type Ast = ast::TraitDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TRAIT] - .get(&src) - .copied() - .map(Trait::from) - } -} -impl FromSource for Function { - type Ast = ast::FnDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::FUNCTION] - .get(&src) - .copied() - .map(Function::from) - } +pub trait FromSourceByContainer: Sized { + type Ast: AstNode + 'static; + type Id: Copy + 'static; + const KEY: Key; } -impl FromSource for Const { - type Ast = ast::ConstDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::CONST] - .get(&src) - .copied() - .map(Const::from) - } -} -impl FromSource for Static { - type Ast = ast::StaticDef; +impl FromSource for T +where + T: From<::Id>, +{ + type Ast = ::Ast; fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STATIC] + analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] .get(&src) .copied() - .map(Static::from) + .map(Self::from) } } -impl FromSource for TypeAlias { - type Ast = ast::TypeAliasDef; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TYPE_ALIAS] - .get(&src) - .copied() - .map(TypeAlias::from) - } +macro_rules! from_source_by_container_impls { + ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$( + impl FromSourceByContainer for $hir { + type Ast = $ast; + type Id = $id; + const KEY: Key = $key; + } + )*} } +from_source_by_container_impls![ + (Struct, StructId, ast::StructDef, keys::STRUCT), + (Union, UnionId, ast::UnionDef, keys::UNION), + (Enum, EnumId, ast::EnumDef, keys::ENUM), + (Trait, TraitId, ast::TraitDef, keys::TRAIT), + (Function, FunctionId, ast::FnDef, keys::FUNCTION), + (Static, StaticId, ast::StaticDef, keys::STATIC), + (Const, ConstId, ast::ConstDef, keys::CONST), + (TypeAlias, TypeAliasId, ast::TypeAliasDef, keys::TYPE_ALIAS), + (ImplBlock, ImplId, ast::ImplBlock, keys::IMPL), +]; + impl FromSource for MacroDef { type Ast = ast::MacroCall; fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { @@ -111,16 +78,6 @@ impl FromSource for MacroDef { } } -impl FromSource for ImplBlock { - type Ast = ast::ImplBlock; - fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { - analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::IMPL] - .get(&src) - .copied() - .map(ImplBlock::from) - } -} - impl FromSource for EnumVariant { type Ast = ast::EnumVariant; fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile) -> Option { -- cgit v1.2.3