switch to positional enum variants

This commit is contained in:
Aleksey Kladov 2019-01-25 11:35:38 +03:00
parent 946aea3eb3
commit 2ee2fba752
3 changed files with 44 additions and 38 deletions

View File

@ -3,11 +3,14 @@
use std::sync::Arc;
use ra_syntax::ast::{self, NameOwner, StructFlavor};
use ra_syntax::{
TreeArc,
ast::{self, NameOwner, StructFlavor}
};
use crate::{
Name, AsName, Struct, Enum, EnumVariant, Crate,
HirDatabase,
HirDatabase, HirFileId,
type_ref::TypeRef,
ids::LocationCtx,
};
@ -55,6 +58,24 @@ pub(crate) fn struct_data_query(db: &impl HirDatabase, struct_: Struct) -> Arc<S
}
}
fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> {
enum_def
.variant_list()
.into_iter()
.flat_map(|it| it.variants())
}
impl EnumVariant {
pub fn source_impl(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) {
let (file_id, enum_def) = self.parent.source(db);
let var = variants(&*enum_def)
.nth(self.idx as usize)
.unwrap()
.to_owned();
(file_id, var)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumData {
pub(crate) name: Option<Name>,
@ -68,22 +89,19 @@ fn new(enum_def: &ast::EnumDef, variants: Vec<(Name, EnumVariant)>) -> Self {
}
pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
let (file_id, enum_def) = e.source(db);
let module = e.module(db);
let ctx = LocationCtx::new(db, module, file_id);
let variants = if let Some(vl) = enum_def.variant_list() {
vl.variants()
.filter_map(|variant_def| {
let name = variant_def.name()?.as_name();
let var = EnumVariant {
id: ctx.to_def(variant_def),
};
Some((name, var))
})
.collect()
} else {
Vec::new()
};
let (_file_id, enum_def) = e.source(db);
let variants = variants(&*enum_def)
.enumerate()
.filter_map(|(idx, variant_def)| {
let name = variant_def.name()?.as_name();
let var = EnumVariant {
parent: e,
idx: idx as u32,
};
Some((name, var))
})
.collect();
Arc::new(EnumData::new(&*enum_def, variants))
}
}

View File

@ -15,7 +15,7 @@
generics::GenericParams,
docs::{Documentation, Docs, docs_from_ast},
module_tree::ModuleId,
ids::{FunctionId, StructId, EnumId, EnumVariantId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
};
/// hir::Crate describes a single crate. It's the main interface with which
@ -269,18 +269,19 @@ fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EnumVariant {
pub(crate) id: EnumVariantId,
pub(crate) parent: Enum,
pub(crate) idx: u32,
}
impl EnumVariant {
pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) {
self.id.source(db)
self.source_impl(db)
}
pub fn module(&self, db: &impl HirDatabase) -> Module {
self.id.module(db)
self.parent.module(db)
}
pub fn parent_enum(&self, db: &impl HirDatabase) -> Enum {
db.enum_variant_data(*self).parent_enum.clone()
pub fn parent_enum(&self, _db: &impl HirDatabase) -> Enum {
self.parent
}
pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {

View File

@ -18,7 +18,6 @@ pub struct HirInterner {
fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>,
structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>,
enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>,
enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>,
consts: LocationIntener<ItemLoc<ast::ConstDef>, ConstId>,
statics: LocationIntener<ItemLoc<ast::StaticDef>, StaticId>,
traits: LocationIntener<ItemLoc<ast::TraitDef>, TraitId>,
@ -31,7 +30,6 @@ pub fn len(&self) -> usize {
+ self.fns.len()
+ self.structs.len()
+ self.enums.len()
+ self.enum_variants.len()
+ self.consts.len()
+ self.statics.len()
+ self.traits.len()
@ -261,15 +259,6 @@ fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::EnumDef>, S
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EnumVariantId(RawId);
impl_arena_id!(EnumVariantId);
impl AstItemDef<ast::EnumVariant> for EnumVariantId {
fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::EnumVariant>, Self> {
&interner.enum_variants
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConstId(RawId);
impl_arena_id!(ConstId);
@ -342,9 +331,7 @@ fn init(&mut self, source_file: &SourceFile) {
// change parent's id. This means that, say, adding a new function to a
// trait does not chage ids of top-level items, which helps caching.
bfs(source_file.syntax(), |it| {
if let Some(enum_variant) = ast::EnumVariant::cast(it) {
self.alloc(enum_variant.syntax().to_owned());
} else if let Some(module_item) = ast::ModuleItem::cast(it) {
if let Some(module_item) = ast::ModuleItem::cast(it) {
self.alloc(module_item.syntax().to_owned());
} else if let Some(macro_call) = ast::MacroCall::cast(it) {
self.alloc(macro_call.syntax().to_owned());