Dedupe from_source impls

This commit is contained in:
Aleksey Kladov 2019-12-12 15:50:16 +01:00
parent 7a255a2f93
commit 8e65b77387
2 changed files with 35 additions and 78 deletions

View file

@ -1,7 +1,8 @@
//! FIXME: write short doc here //! FIXME: write short doc here
use hir_def::{ use hir_def::{
child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, EnumVariantId, child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource,
GenericDefId, ModuleId, VariantId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId,
TraitId, TypeAliasId, UnionId, VariantId,
}; };
use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
use ra_syntax::{ use ra_syntax::{
@ -20,80 +21,46 @@ pub trait FromSource: Sized {
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>;
} }
impl FromSource for Struct { pub trait FromSourceByContainer: Sized {
type Ast = ast::StructDef; type Ast: AstNode + 'static;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { type Id: Copy + 'static;
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STRUCT] const KEY: Key<Self::Ast, Self::Id>;
.get(&src)
.copied()
.map(Struct::from)
}
} }
impl FromSource for Union {
type Ast = ast::UnionDef; impl<T: FromSourceByContainer> FromSource for T
where
T: From<<T as FromSourceByContainer>::Id>,
{
type Ast = <T as FromSourceByContainer>::Ast;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::UNION] analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY]
.get(&src) .get(&src)
.copied() .copied()
.map(Union::from) .map(Self::from)
}
}
impl FromSource for Enum {
type Ast = ast::EnumDef;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
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<Self::Ast>) -> Option<Self> {
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<Self::Ast>) -> Option<Self> {
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::FUNCTION]
.get(&src)
.copied()
.map(Function::from)
} }
} }
impl FromSource for Const { macro_rules! from_source_by_container_impls {
type Ast = ast::ConstDef; ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$(
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { impl FromSourceByContainer for $hir {
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::CONST] type Ast = $ast;
.get(&src) type Id = $id;
.copied() const KEY: Key<Self::Ast, Self::Id> = $key;
.map(Const::from) }
} )*}
}
impl FromSource for Static {
type Ast = ast::StaticDef;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STATIC]
.get(&src)
.copied()
.map(Static::from)
}
} }
impl FromSource for TypeAlias { from_source_by_container_impls![
type Ast = ast::TypeAliasDef; (Struct, StructId, ast::StructDef, keys::STRUCT),
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { (Union, UnionId, ast::UnionDef, keys::UNION),
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TYPE_ALIAS] (Enum, EnumId, ast::EnumDef, keys::ENUM),
.get(&src) (Trait, TraitId, ast::TraitDef, keys::TRAIT),
.copied() (Function, FunctionId, ast::FnDef, keys::FUNCTION),
.map(TypeAlias::from) (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 { impl FromSource for MacroDef {
type Ast = ast::MacroCall; type Ast = ast::MacroCall;
@ -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<Self::Ast>) -> Option<Self> {
analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::IMPL]
.get(&src)
.copied()
.map(ImplBlock::from)
}
}
impl FromSource for EnumVariant { impl FromSource for EnumVariant {
type Ast = ast::EnumVariant; type Ast = ast::EnumVariant;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {

View file

@ -12,7 +12,7 @@ use crate::{
TypeAliasId, TypeParamId, UnionId, TypeAliasId, TypeParamId, UnionId,
}; };
type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>;
pub const FUNCTION: Key<ast::FnDef, FunctionId> = Key::new(); pub const FUNCTION: Key<ast::FnDef, FunctionId> = Key::new();
pub const CONST: Key<ast::ConstDef, ConstId> = Key::new(); pub const CONST: Key<ast::ConstDef, ConstId> = Key::new();