Remove Params and Fields from AstIdMap

This commit is contained in:
Lukas Wirth 2024-07-25 10:18:06 +02:00
parent 200a01adc4
commit 9cbafa2d49
16 changed files with 494 additions and 449 deletions

View file

@ -17,12 +17,12 @@ use crate::{
db::DefDatabase,
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
item_tree::{
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldAstId,
Fields, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, IdxRange,
Impl, ImportAlias, Interned, ItemTree, ItemTreeData, ItemTreeNode, Macro2, MacroCall,
MacroRules, Mod, ModItem, ModKind, ModPath, Mutability, Name, Param, ParamAstId, Path,
Range, RawAttrs, RawIdx, RawVisibilityId, Static, Struct, StructKind, Trait, TraitAlias,
TypeAlias, Union, Use, UseTree, UseTreeKind, Variant,
AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldParent,
FieldsShape, FileItemTreeId, FnFlags, Function, GenericArgs, GenericModItem, Idx, Impl,
ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem,
ModKind, ModPath, Mutability, Name, Param, Path, Range, RawAttrs, RawIdx, RawVisibilityId,
Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
Variant,
},
path::AssociatedTypeBinding,
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef, TypeBound, TypeRef},
@ -30,7 +30,7 @@ use crate::{
LocalLifetimeParamId, LocalTypeOrConstParamId,
};
fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
fn id<N>(index: Idx<N>) -> FileItemTreeId<N> {
FileItemTreeId(index)
}
@ -193,82 +193,98 @@ impl<'a> Ctx<'a> {
let visibility = self.lower_visibility(strukt);
let name = strukt.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(strukt);
let fields = self.lower_fields(&strukt.kind());
let (fields, kind, attrs) = self.lower_fields(&strukt.kind());
let generic_params = self.lower_generic_params(HasImplicitSelf::No, strukt);
let res = Struct { name, visibility, generic_params, fields, ast_id };
let res = Struct { name, visibility, generic_params, fields, shape: kind, ast_id };
let id = id(self.data().structs.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Struct(id),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
fn lower_fields(&mut self, strukt_kind: &ast::StructKind) -> Fields {
fn lower_fields(
&mut self,
strukt_kind: &ast::StructKind,
) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
match strukt_kind {
ast::StructKind::Record(it) => {
let range = self.lower_record_fields(it);
Fields::Record(range)
let mut fields = vec![];
let mut attrs = vec![];
for (i, field) in it.fields().enumerate() {
let data = self.lower_record_field(&field);
fields.push(data);
let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map());
if !attr.is_empty() {
attrs.push((i, attr))
}
}
(fields.into(), FieldsShape::Record, attrs)
}
ast::StructKind::Tuple(it) => {
let range = self.lower_tuple_fields(it);
Fields::Tuple(range)
let mut fields = vec![];
let mut attrs = vec![];
for (i, field) in it.fields().enumerate() {
let data = self.lower_tuple_field(i, &field);
fields.push(data);
let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map());
if !attr.is_empty() {
attrs.push((i, attr))
}
}
(fields.into(), FieldsShape::Tuple, attrs)
}
ast::StructKind::Unit => Fields::Unit,
ast::StructKind::Unit => (Box::default(), FieldsShape::Unit, Vec::default()),
}
}
fn lower_record_fields(&mut self, fields: &ast::RecordFieldList) -> IdxRange<Field> {
let start = self.next_field_idx();
for field in fields.fields() {
if let Some(data) = self.lower_record_field(&field) {
let idx = self.data().fields.alloc(data);
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &field, self.span_map()),
);
}
}
let end = self.next_field_idx();
IdxRange::new(start..end)
}
fn lower_record_field(&mut self, field: &ast::RecordField) -> Option<Field> {
let name = field.name()?.as_name();
fn lower_record_field(&mut self, field: &ast::RecordField) -> Field {
let name = match field.name() {
Some(name) => name.as_name(),
None => Name::missing(),
};
let visibility = self.lower_visibility(field);
let type_ref = self.lower_type_ref_opt(field.ty());
let ast_id = FieldAstId::Record(self.source_ast_id_map.ast_id(field));
let res = Field { name, type_ref, visibility, ast_id };
Some(res)
}
fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldList) -> IdxRange<Field> {
let start = self.next_field_idx();
for (i, field) in fields.fields().enumerate() {
let data = self.lower_tuple_field(i, &field);
let idx = self.data().fields.alloc(data);
self.add_attrs(idx.into(), RawAttrs::new(self.db.upcast(), &field, self.span_map()));
}
let end = self.next_field_idx();
IdxRange::new(start..end)
Field { name, type_ref, visibility }
}
fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field {
let name = Name::new_tuple_field(idx);
let visibility = self.lower_visibility(field);
let type_ref = self.lower_type_ref_opt(field.ty());
let ast_id = FieldAstId::Tuple(self.source_ast_id_map.ast_id(field));
Field { name, type_ref, visibility, ast_id }
Field { name, type_ref, visibility }
}
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
let visibility = self.lower_visibility(union);
let name = union.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(union);
let fields = match union.record_field_list() {
let (fields, _, attrs) = match union.record_field_list() {
Some(record_field_list) => self.lower_fields(&StructKind::Record(record_field_list)),
None => Fields::Record(IdxRange::new(self.next_field_idx()..self.next_field_idx())),
None => (Box::default(), FieldsShape::Record, Vec::default()),
};
let generic_params = self.lower_generic_params(HasImplicitSelf::No, union);
let res = Union { name, visibility, generic_params, fields, ast_id };
let id = id(self.data().unions.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Union(id),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
@ -293,24 +309,35 @@ impl<'a> Ctx<'a> {
fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
let start = self.next_variant_idx();
for variant in variants.variants() {
if let Some(data) = self.lower_variant(&variant) {
let idx = self.data().variants.alloc(data);
self.add_attrs(
id(idx).into(),
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
);
}
let idx = self.lower_variant(&variant);
self.add_attrs(
id(idx).into(),
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
);
}
let end = self.next_variant_idx();
FileItemTreeId(start)..FileItemTreeId(end)
}
fn lower_variant(&mut self, variant: &ast::Variant) -> Option<Variant> {
let name = variant.name()?.as_name();
let fields = self.lower_fields(&variant.kind());
fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
let name = match variant.name() {
Some(name) => name.as_name(),
None => Name::missing(),
};
let (fields, kind, attrs) = self.lower_fields(&variant.kind());
let ast_id = self.source_ast_id_map.ast_id(variant);
let res = Variant { name, fields, ast_id };
Some(res)
let res = Variant { name, fields, shape: kind, ast_id };
let id = self.data().variants.alloc(res);
for (idx, attr) in attrs {
self.add_attrs(
AttrOwner::Field(
FieldParent::Variant(FileItemTreeId(id)),
Idx::from_raw(RawIdx::from_u32(idx as u32)),
),
attr,
);
}
id
}
fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
@ -318,9 +345,20 @@ impl<'a> Ctx<'a> {
let name = func.name()?.as_name();
let mut has_self_param = false;
let start_param = self.next_param_idx();
let mut has_var_args = false;
let mut params = vec![];
let mut attrs = vec![];
let mut push_attr = |idx, attr: RawAttrs| {
if !attr.is_empty() {
attrs.push((idx, attr))
}
};
if let Some(param_list) = func.param_list() {
if let Some(self_param) = param_list.self_param() {
push_attr(
params.len(),
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
);
let self_type = match self_param.ty() {
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
None => {
@ -342,40 +380,25 @@ impl<'a> Ctx<'a> {
}
};
let type_ref = Interned::new(self_type);
let ast_id = self.source_ast_id_map.ast_id(&self_param);
let idx = self.data().params.alloc(Param {
type_ref: Some(type_ref),
ast_id: ParamAstId::SelfParam(ast_id),
});
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
);
params.push(Param { type_ref });
has_self_param = true;
}
for param in param_list.params() {
let ast_id = self.source_ast_id_map.ast_id(&param);
let idx = match param.dotdotdot_token() {
Some(_) => self
.data()
.params
.alloc(Param { type_ref: None, ast_id: ParamAstId::Param(ast_id) }),
push_attr(params.len(), RawAttrs::new(self.db.upcast(), &param, self.span_map()));
let param = match param.dotdotdot_token() {
Some(_) => {
has_var_args = true;
Param { type_ref: Interned::new(TypeRef::Error) }
}
None => {
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
let ty = Interned::new(type_ref);
self.data()
.params
.alloc(Param { type_ref: Some(ty), ast_id: ParamAstId::Param(ast_id) })
Param { type_ref: ty }
}
};
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &param, self.span_map()),
);
params.push(param);
}
}
let end_param = self.next_param_idx();
let params = IdxRange::new(start_param..end_param);
let ret_type = match func.ret_type() {
Some(rt) => match rt.ty() {
@ -417,19 +440,25 @@ impl<'a> Ctx<'a> {
if func.unsafe_token().is_some() {
flags |= FnFlags::HAS_UNSAFE_KW;
}
if has_var_args {
flags |= FnFlags::IS_VARARGS;
}
let res = Function {
name,
visibility,
explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
abi,
params,
params: params.into_boxed_slice(),
ret_type: Interned::new(ret_type),
ast_id,
flags,
};
let id = id(self.data().functions.alloc(res));
for (idx, attr) in attrs {
self.add_attrs(AttrOwner::Param(id, Idx::from_raw(RawIdx::from_u32(idx as u32))), attr);
}
self.write_generic_params_attributes(id.into());
Some(id)
}
@ -725,21 +754,11 @@ impl<'a> Ctx<'a> {
}
}
fn next_field_idx(&self) -> Idx<Field> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.fields.len() as u32),
))
}
fn next_variant_idx(&self) -> Idx<Variant> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32),
))
}
fn next_param_idx(&self) -> Idx<Param> {
Idx::from_raw(RawIdx::from(
self.tree.data.as_ref().map_or(0, |data| data.params.len() as u32),
))
}
}
fn desugar_future_path(orig: TypeRef) -> Path {