mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-25 11:17:13 +00:00
Remove most of the item tree
I'm joking, but now that the def map is the only thing that uses the item tree, we can remove a lot of things from it that aren't needed for the def map.
This commit is contained in:
parent
ed0b4506dd
commit
0a1a78cb87
@ -29,7 +29,6 @@
|
||||
//!
|
||||
//! In general, any item in the `ItemTree` stores its `AstId`, which allows mapping it back to its
|
||||
//! surface syntax.
|
||||
#![allow(unexpected_cfgs)]
|
||||
|
||||
mod lower;
|
||||
mod pretty;
|
||||
@ -51,7 +50,7 @@ use hir_expand::{
|
||||
mod_path::{ModPath, PathKind},
|
||||
name::Name,
|
||||
};
|
||||
use intern::{Interned, Symbol};
|
||||
use intern::Interned;
|
||||
use la_arena::{Arena, Idx, RawIdx};
|
||||
use rustc_hash::FxHashMap;
|
||||
use smallvec::SmallVec;
|
||||
@ -237,7 +236,6 @@ impl ItemTree {
|
||||
structs,
|
||||
unions,
|
||||
enums,
|
||||
variants,
|
||||
consts,
|
||||
statics,
|
||||
traits,
|
||||
@ -258,7 +256,6 @@ impl ItemTree {
|
||||
structs.shrink_to_fit();
|
||||
unions.shrink_to_fit();
|
||||
enums.shrink_to_fit();
|
||||
variants.shrink_to_fit();
|
||||
consts.shrink_to_fit();
|
||||
statics.shrink_to_fit();
|
||||
traits.shrink_to_fit();
|
||||
@ -310,7 +307,6 @@ struct ItemTreeData {
|
||||
structs: Arena<Struct>,
|
||||
unions: Arena<Union>,
|
||||
enums: Arena<Enum>,
|
||||
variants: Arena<Variant>,
|
||||
consts: Arena<Const>,
|
||||
statics: Arena<Static>,
|
||||
traits: Arena<Trait>,
|
||||
@ -340,41 +336,15 @@ pub enum AttrOwner {
|
||||
ModItem(ModItem),
|
||||
/// Inner attributes of the source file.
|
||||
TopLevel,
|
||||
|
||||
Variant(FileItemTreeId<Variant>),
|
||||
// while not relevant to early name resolution, fields can contain visibility
|
||||
Field(FieldParent, ItemTreeFieldId),
|
||||
}
|
||||
|
||||
impl AttrOwner {
|
||||
pub fn make_field_indexed(parent: FieldParent, idx: usize) -> Self {
|
||||
AttrOwner::Field(parent, ItemTreeFieldId::from_raw(RawIdx::from_u32(idx as u32)))
|
||||
impl From<ModItem> for AttrOwner {
|
||||
#[inline]
|
||||
fn from(value: ModItem) -> Self {
|
||||
AttrOwner::ModItem(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum FieldParent {
|
||||
Struct(FileItemTreeId<Struct>),
|
||||
Union(FileItemTreeId<Union>),
|
||||
EnumVariant(FileItemTreeId<Variant>),
|
||||
}
|
||||
|
||||
pub type ItemTreeFieldId = Idx<Field>;
|
||||
|
||||
macro_rules! from_attrs {
|
||||
( $( $var:ident($t:ty) ),+ $(,)? ) => {
|
||||
$(
|
||||
impl From<$t> for AttrOwner {
|
||||
fn from(t: $t) -> AttrOwner {
|
||||
AttrOwner::$var(t)
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>));
|
||||
|
||||
/// Trait implemented by all nodes in the item tree.
|
||||
pub trait ItemTreeNode: Clone {
|
||||
type Source: AstIdNode;
|
||||
@ -383,7 +353,6 @@ pub trait ItemTreeNode: Clone {
|
||||
|
||||
/// Looks up an instance of `Self` in an item tree.
|
||||
fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner;
|
||||
}
|
||||
|
||||
pub struct FileItemTreeId<N>(Idx<N>);
|
||||
@ -547,10 +516,6 @@ macro_rules! mod_items {
|
||||
fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
|
||||
&tree.data().$fld[index]
|
||||
}
|
||||
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
|
||||
AttrOwner::ModItem(ModItem::$typ(id))
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<Idx<$typ>> for ItemTree {
|
||||
@ -624,22 +589,6 @@ impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemTreeNode for Variant {
|
||||
type Source = ast::Variant;
|
||||
|
||||
fn ast_id(&self) -> FileAstId<Self::Source> {
|
||||
self.ast_id
|
||||
}
|
||||
|
||||
fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
|
||||
&tree.data().variants[index]
|
||||
}
|
||||
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
|
||||
AttrOwner::Variant(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Use {
|
||||
pub visibility: RawVisibilityId,
|
||||
@ -712,7 +661,6 @@ pub struct ExternCrate {
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ExternBlock {
|
||||
pub abi: Option<Symbol>,
|
||||
pub ast_id: FileAstId<ast::ExternBlock>,
|
||||
pub children: Box<[ModItem]>,
|
||||
}
|
||||
@ -728,7 +676,6 @@ pub struct Function {
|
||||
pub struct Struct {
|
||||
pub name: Name,
|
||||
pub visibility: RawVisibilityId,
|
||||
pub fields: Box<[Field]>,
|
||||
pub shape: FieldsShape,
|
||||
pub ast_id: FileAstId<ast::Struct>,
|
||||
}
|
||||
@ -737,7 +684,6 @@ pub struct Struct {
|
||||
pub struct Union {
|
||||
pub name: Name,
|
||||
pub visibility: RawVisibilityId,
|
||||
pub fields: Box<[Field]>,
|
||||
pub ast_id: FileAstId<ast::Union>,
|
||||
}
|
||||
|
||||
@ -745,18 +691,9 @@ pub struct Union {
|
||||
pub struct Enum {
|
||||
pub name: Name,
|
||||
pub visibility: RawVisibilityId,
|
||||
pub variants: Range<FileItemTreeId<Variant>>,
|
||||
pub ast_id: FileAstId<ast::Enum>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Variant {
|
||||
pub name: Name,
|
||||
pub fields: Box<[Field]>,
|
||||
pub shape: FieldsShape,
|
||||
pub ast_id: FileAstId<ast::Variant>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum FieldsShape {
|
||||
Record,
|
||||
@ -788,16 +725,6 @@ impl VisibilityExplicitness {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Remove this from item tree?
|
||||
/// A single field of an enum variant or struct
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Field {
|
||||
pub name: Name,
|
||||
pub visibility: RawVisibilityId,
|
||||
// FIXME: Not an item tree property
|
||||
pub is_unsafe: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Const {
|
||||
/// `None` for `const _: () = ();`
|
||||
@ -817,7 +744,6 @@ pub struct Static {
|
||||
pub struct Trait {
|
||||
pub name: Name,
|
||||
pub visibility: RawVisibilityId,
|
||||
pub items: Box<[AssocItem]>,
|
||||
pub ast_id: FileAstId<ast::Trait>,
|
||||
}
|
||||
|
||||
@ -830,7 +756,6 @@ pub struct TraitAlias {
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Impl {
|
||||
pub items: Box<[AssocItem]>,
|
||||
pub ast_id: FileAstId<ast::Impl>,
|
||||
}
|
||||
|
||||
@ -971,76 +896,3 @@ impl UseTree {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_froms {
|
||||
($e:ident { $($v:ident ($t:ty)),* $(,)? }) => {
|
||||
$(
|
||||
impl From<$t> for $e {
|
||||
fn from(it: $t) -> $e {
|
||||
$e::$v(it)
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl ModItem {
|
||||
pub fn as_assoc_item(&self) -> Option<AssocItem> {
|
||||
match self {
|
||||
ModItem::Use(_)
|
||||
| ModItem::ExternCrate(_)
|
||||
| ModItem::ExternBlock(_)
|
||||
| ModItem::Struct(_)
|
||||
| ModItem::Union(_)
|
||||
| ModItem::Enum(_)
|
||||
| ModItem::Static(_)
|
||||
| ModItem::Trait(_)
|
||||
| ModItem::TraitAlias(_)
|
||||
| ModItem::Impl(_)
|
||||
| ModItem::Mod(_)
|
||||
| ModItem::MacroRules(_)
|
||||
| ModItem::Macro2(_) => None,
|
||||
&ModItem::MacroCall(call) => Some(AssocItem::MacroCall(call)),
|
||||
&ModItem::Const(konst) => Some(AssocItem::Const(konst)),
|
||||
&ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(alias)),
|
||||
&ModItem::Function(func) => Some(AssocItem::Function(func)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum AssocItem {
|
||||
Function(FileItemTreeId<Function>),
|
||||
TypeAlias(FileItemTreeId<TypeAlias>),
|
||||
Const(FileItemTreeId<Const>),
|
||||
MacroCall(FileItemTreeId<MacroCall>),
|
||||
}
|
||||
|
||||
impl_froms!(AssocItem {
|
||||
Function(FileItemTreeId<Function>),
|
||||
TypeAlias(FileItemTreeId<TypeAlias>),
|
||||
Const(FileItemTreeId<Const>),
|
||||
MacroCall(FileItemTreeId<MacroCall>),
|
||||
});
|
||||
|
||||
impl From<AssocItem> for ModItem {
|
||||
fn from(item: AssocItem) -> Self {
|
||||
match item {
|
||||
AssocItem::Function(it) => it.into(),
|
||||
AssocItem::TypeAlias(it) => it.into(),
|
||||
AssocItem::Const(it) => it.into(),
|
||||
AssocItem::MacroCall(it) => it.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AssocItem {
|
||||
pub fn ast_id(self, tree: &ItemTree) -> FileAstId<ast::AssocItem> {
|
||||
match self {
|
||||
AssocItem::Function(id) => tree[id].ast_id.upcast(),
|
||||
AssocItem::TypeAlias(id) => tree[id].ast_id.upcast(),
|
||||
AssocItem::Const(id) => tree[id].ast_id.upcast(),
|
||||
AssocItem::MacroCall(id) => tree[id].ast_id.upcast(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,23 +8,22 @@ use hir_expand::{
|
||||
name::AsName,
|
||||
span_map::{SpanMap, SpanMapRef},
|
||||
};
|
||||
use intern::{Symbol, sym};
|
||||
use la_arena::Arena;
|
||||
use span::{AstIdMap, SyntaxContext};
|
||||
use syntax::{
|
||||
AstNode,
|
||||
ast::{self, HasModuleItem, HasName, IsString},
|
||||
ast::{self, HasModuleItem, HasName},
|
||||
};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
item_tree::{
|
||||
AssocItem, AttrOwner, Const, Enum, ExternBlock, ExternCrate, Field, FieldParent,
|
||||
FieldsShape, FileItemTreeId, Function, Idx, Impl, ImportAlias, Interned, ItemTree,
|
||||
ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, ModPath, Name, Range,
|
||||
RawAttrs, RawIdx, RawVisibility, RawVisibilityId, Static, Struct, StructKind, Trait,
|
||||
TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, Variant, VisibilityExplicitness,
|
||||
AttrOwner, Const, Enum, ExternBlock, ExternCrate, FieldsShape, FileItemTreeId, Function,
|
||||
Idx, Impl, ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules,
|
||||
Mod, ModItem, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct,
|
||||
StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
|
||||
VisibilityExplicitness,
|
||||
},
|
||||
};
|
||||
|
||||
@ -163,118 +162,23 @@ impl<'a> Ctx<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_assoc_item(&mut self, item_node: &ast::AssocItem) -> Option<AssocItem> {
|
||||
let item: AssocItem = match item_node {
|
||||
ast::AssocItem::Fn(ast) => self.lower_function(ast).map(Into::into),
|
||||
ast::AssocItem::TypeAlias(ast) => self.lower_type_alias(ast).map(Into::into),
|
||||
ast::AssocItem::Const(ast) => Some(self.lower_const(ast).into()),
|
||||
ast::AssocItem::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into),
|
||||
}?;
|
||||
let attrs = RawAttrs::new(self.db, item_node, self.span_map());
|
||||
self.add_attrs(
|
||||
match item {
|
||||
AssocItem::Function(it) => AttrOwner::ModItem(ModItem::Function(it)),
|
||||
AssocItem::TypeAlias(it) => AttrOwner::ModItem(ModItem::TypeAlias(it)),
|
||||
AssocItem::Const(it) => AttrOwner::ModItem(ModItem::Const(it)),
|
||||
AssocItem::MacroCall(it) => AttrOwner::ModItem(ModItem::MacroCall(it)),
|
||||
},
|
||||
attrs,
|
||||
);
|
||||
Some(item)
|
||||
}
|
||||
|
||||
fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
|
||||
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, kind, attrs) = self.lower_fields(&strukt.kind());
|
||||
let res = Struct { name, visibility, fields, shape: kind, ast_id };
|
||||
let shape = adt_shape(strukt.kind());
|
||||
let res = Struct { name, visibility, shape, 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,
|
||||
);
|
||||
}
|
||||
Some(id)
|
||||
}
|
||||
|
||||
fn lower_fields(
|
||||
&mut self,
|
||||
strukt_kind: &ast::StructKind,
|
||||
) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
|
||||
match strukt_kind {
|
||||
ast::StructKind::Record(it) => {
|
||||
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, &field, self.span_map());
|
||||
if !attr.is_empty() {
|
||||
attrs.push((i, attr))
|
||||
}
|
||||
}
|
||||
(fields.into(), FieldsShape::Record, attrs)
|
||||
}
|
||||
ast::StructKind::Tuple(it) => {
|
||||
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, &field, self.span_map());
|
||||
if !attr.is_empty() {
|
||||
attrs.push((i, attr))
|
||||
}
|
||||
}
|
||||
(fields.into(), FieldsShape::Tuple, attrs)
|
||||
}
|
||||
ast::StructKind::Unit => (Box::default(), FieldsShape::Unit, Vec::default()),
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Field { name, visibility, is_unsafe: field.unsafe_token().is_some() }
|
||||
}
|
||||
|
||||
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);
|
||||
Field { name, visibility, is_unsafe: false }
|
||||
}
|
||||
|
||||
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, _, attrs) = match union.record_field_list() {
|
||||
Some(record_field_list) => self.lower_fields(&StructKind::Record(record_field_list)),
|
||||
None => (Box::default(), FieldsShape::Record, Vec::default()),
|
||||
};
|
||||
let res = Union { name, visibility, fields, ast_id };
|
||||
let res = Union { name, visibility, 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,
|
||||
);
|
||||
}
|
||||
Some(id)
|
||||
}
|
||||
|
||||
@ -282,48 +186,11 @@ impl<'a> Ctx<'a> {
|
||||
let visibility = self.lower_visibility(enum_);
|
||||
let name = enum_.name()?.as_name();
|
||||
let ast_id = self.source_ast_id_map.ast_id(enum_);
|
||||
let variants = match &enum_.variant_list() {
|
||||
Some(variant_list) => self.lower_variants(variant_list),
|
||||
None => {
|
||||
FileItemTreeId(self.next_variant_idx())..FileItemTreeId(self.next_variant_idx())
|
||||
}
|
||||
};
|
||||
let res = Enum { name, visibility, variants, ast_id };
|
||||
let res = Enum { name, visibility, ast_id };
|
||||
let id = id(self.data().enums.alloc(res));
|
||||
Some(id)
|
||||
}
|
||||
|
||||
fn lower_variants(&mut self, variants: &ast::VariantList) -> Range<FileItemTreeId<Variant>> {
|
||||
let start = self.next_variant_idx();
|
||||
for variant in variants.variants() {
|
||||
let idx = self.lower_variant(&variant);
|
||||
self.add_attrs(id(idx).into(), RawAttrs::new(self.db, &variant, self.span_map()));
|
||||
}
|
||||
let end = self.next_variant_idx();
|
||||
FileItemTreeId(start)..FileItemTreeId(end)
|
||||
}
|
||||
|
||||
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, shape: kind, ast_id };
|
||||
let id = self.data().variants.alloc(res);
|
||||
for (idx, attr) in attrs {
|
||||
self.add_attrs(
|
||||
AttrOwner::Field(
|
||||
FieldParent::EnumVariant(FileItemTreeId(id)),
|
||||
Idx::from_raw(RawIdx::from_u32(idx as u32)),
|
||||
),
|
||||
attr,
|
||||
);
|
||||
}
|
||||
id
|
||||
}
|
||||
|
||||
fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
|
||||
let visibility = self.lower_visibility(func);
|
||||
let name = func.name()?.as_name();
|
||||
@ -390,14 +257,7 @@ impl<'a> Ctx<'a> {
|
||||
let visibility = self.lower_visibility(trait_def);
|
||||
let ast_id = self.source_ast_id_map.ast_id(trait_def);
|
||||
|
||||
let items = trait_def
|
||||
.assoc_item_list()
|
||||
.into_iter()
|
||||
.flat_map(|list| list.assoc_items())
|
||||
.filter_map(|item_node| self.lower_assoc_item(&item_node))
|
||||
.collect();
|
||||
|
||||
let def = Trait { name, visibility, items, ast_id };
|
||||
let def = Trait { name, visibility, ast_id };
|
||||
let id = id(self.data().traits.alloc(def));
|
||||
Some(id)
|
||||
}
|
||||
@ -417,16 +277,9 @@ impl<'a> Ctx<'a> {
|
||||
|
||||
fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
|
||||
let ast_id = self.source_ast_id_map.ast_id(impl_def);
|
||||
// We cannot use `assoc_items()` here as that does not include macro calls.
|
||||
let items = impl_def
|
||||
.assoc_item_list()
|
||||
.into_iter()
|
||||
.flat_map(|it| it.assoc_items())
|
||||
.filter_map(|item| self.lower_assoc_item(&item))
|
||||
.collect();
|
||||
// Note that trait impls don't get implicit `Self` unlike traits, because here they are a
|
||||
// type alias rather than a type parameter, so this is handled by the resolver.
|
||||
let res = Impl { items, ast_id };
|
||||
let res = Impl { ast_id };
|
||||
id(self.data().impls.alloc(res))
|
||||
}
|
||||
|
||||
@ -489,7 +342,6 @@ impl<'a> Ctx<'a> {
|
||||
|
||||
fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<ExternBlock> {
|
||||
let ast_id = self.source_ast_id_map.ast_id(block);
|
||||
let abi = block.abi().map(lower_abi);
|
||||
let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
|
||||
list.extern_items()
|
||||
.filter_map(|item| {
|
||||
@ -510,7 +362,7 @@ impl<'a> Ctx<'a> {
|
||||
.collect()
|
||||
});
|
||||
|
||||
let res = ExternBlock { abi, ast_id, children };
|
||||
let res = ExternBlock { ast_id, children };
|
||||
id(self.data().extern_blocks.alloc(res))
|
||||
}
|
||||
|
||||
@ -520,20 +372,6 @@ impl<'a> Ctx<'a> {
|
||||
});
|
||||
self.data().vis.alloc(vis)
|
||||
}
|
||||
|
||||
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 lower_abi(abi: ast::Abi) -> Symbol {
|
||||
match abi.abi_string() {
|
||||
Some(tok) => Symbol::intern(tok.text_without_quotes()),
|
||||
// `extern` default to be `extern "C"`.
|
||||
_ => sym::C,
|
||||
}
|
||||
}
|
||||
|
||||
struct UseTreeLowering<'a> {
|
||||
@ -647,3 +485,11 @@ pub(crate) fn visibility_from_ast(
|
||||
};
|
||||
RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit)
|
||||
}
|
||||
|
||||
fn adt_shape(kind: StructKind) -> FieldsShape {
|
||||
match kind {
|
||||
StructKind::Record(_) => FieldsShape::Record,
|
||||
StructKind::Tuple(_) => FieldsShape::Tuple,
|
||||
StructKind::Unit => FieldsShape::Unit,
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,13 @@
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
use la_arena::{Idx, RawIdx};
|
||||
use span::{Edition, ErasedFileAstId};
|
||||
|
||||
use crate::{
|
||||
item_tree::{
|
||||
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, Field, FieldParent,
|
||||
FieldsShape, FileItemTreeId, Function, Impl, ItemTree, Macro2, MacroCall, MacroRules, Mod,
|
||||
ModItem, ModKind, RawAttrs, RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias,
|
||||
Union, Use, UseTree, UseTreeKind, Variant,
|
||||
AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
|
||||
ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, RawAttrs, RawVisibilityId,
|
||||
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
|
||||
},
|
||||
visibility::RawVisibility,
|
||||
};
|
||||
@ -118,44 +116,14 @@ impl Printer<'_> {
|
||||
};
|
||||
}
|
||||
|
||||
fn print_fields(&mut self, parent: FieldParent, kind: FieldsShape, fields: &[Field]) {
|
||||
let edition = self.edition;
|
||||
fn print_fields(&mut self, kind: FieldsShape) {
|
||||
match kind {
|
||||
FieldsShape::Record => {
|
||||
self.whitespace();
|
||||
w!(self, "{{");
|
||||
self.indented(|this| {
|
||||
for (idx, Field { name, visibility, is_unsafe }) in fields.iter().enumerate() {
|
||||
this.print_attrs_of(
|
||||
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||
"\n",
|
||||
);
|
||||
this.print_visibility(*visibility);
|
||||
if *is_unsafe {
|
||||
w!(this, "unsafe ");
|
||||
}
|
||||
|
||||
wln!(this, "{},", name.display(self.db, edition));
|
||||
}
|
||||
});
|
||||
w!(self, "}}");
|
||||
w!(self, "{{ ... }}");
|
||||
}
|
||||
FieldsShape::Tuple => {
|
||||
w!(self, "(");
|
||||
self.indented(|this| {
|
||||
for (idx, Field { name, visibility, is_unsafe }) in fields.iter().enumerate() {
|
||||
this.print_attrs_of(
|
||||
AttrOwner::Field(parent, Idx::from_raw(RawIdx::from(idx as u32))),
|
||||
"\n",
|
||||
);
|
||||
this.print_visibility(*visibility);
|
||||
if *is_unsafe {
|
||||
w!(this, "unsafe ");
|
||||
}
|
||||
wln!(this, "{},", name.display(self.db, edition));
|
||||
}
|
||||
});
|
||||
w!(self, ")");
|
||||
w!(self, "(...)");
|
||||
}
|
||||
FieldsShape::Unit => {}
|
||||
}
|
||||
@ -214,13 +182,9 @@ impl Printer<'_> {
|
||||
wln!(self, ";");
|
||||
}
|
||||
ModItem::ExternBlock(it) => {
|
||||
let ExternBlock { abi, ast_id, children } = &self.tree[it];
|
||||
let ExternBlock { ast_id, children } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
w!(self, "extern ");
|
||||
if let Some(abi) = abi {
|
||||
w!(self, "\"{}\" ", abi);
|
||||
}
|
||||
w!(self, "{{");
|
||||
w!(self, "extern {{");
|
||||
self.indented(|this| {
|
||||
for child in &**children {
|
||||
this.print_mod_item(*child);
|
||||
@ -235,11 +199,11 @@ impl Printer<'_> {
|
||||
wln!(self, "fn {};", name.display(self.db, self.edition));
|
||||
}
|
||||
ModItem::Struct(it) => {
|
||||
let Struct { visibility, name, fields, shape: kind, ast_id } = &self.tree[it];
|
||||
let Struct { visibility, name, shape: kind, ast_id } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
self.print_visibility(*visibility);
|
||||
w!(self, "struct {}", name.display(self.db, self.edition));
|
||||
self.print_fields(FieldParent::Struct(it), *kind, fields);
|
||||
self.print_fields(*kind);
|
||||
if matches!(kind, FieldsShape::Record) {
|
||||
wln!(self);
|
||||
} else {
|
||||
@ -247,30 +211,18 @@ impl Printer<'_> {
|
||||
}
|
||||
}
|
||||
ModItem::Union(it) => {
|
||||
let Union { name, visibility, fields, ast_id } = &self.tree[it];
|
||||
let Union { name, visibility, ast_id } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
self.print_visibility(*visibility);
|
||||
w!(self, "union {}", name.display(self.db, self.edition));
|
||||
self.print_fields(FieldParent::Union(it), FieldsShape::Record, fields);
|
||||
self.print_fields(FieldsShape::Record);
|
||||
wln!(self);
|
||||
}
|
||||
ModItem::Enum(it) => {
|
||||
let Enum { name, visibility, variants, ast_id } = &self.tree[it];
|
||||
let Enum { name, visibility, ast_id } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
self.print_visibility(*visibility);
|
||||
w!(self, "enum {} {{", name.display(self.db, self.edition));
|
||||
let edition = self.edition;
|
||||
self.indented(|this| {
|
||||
for variant in FileItemTreeId::range_iter(variants.clone()) {
|
||||
let Variant { name, fields, shape: kind, ast_id } = &this.tree[variant];
|
||||
this.print_ast_id(ast_id.erase());
|
||||
this.print_attrs_of(variant, "\n");
|
||||
w!(this, "{}", name.display(self.db, edition));
|
||||
this.print_fields(FieldParent::EnumVariant(variant), *kind, fields);
|
||||
wln!(this, ",");
|
||||
}
|
||||
});
|
||||
wln!(self, "}}");
|
||||
w!(self, "enum {} {{ ... }}", name.display(self.db, self.edition));
|
||||
}
|
||||
ModItem::Const(it) => {
|
||||
let Const { name, visibility, ast_id } = &self.tree[it];
|
||||
@ -293,16 +245,10 @@ impl Printer<'_> {
|
||||
wln!(self);
|
||||
}
|
||||
ModItem::Trait(it) => {
|
||||
let Trait { name, visibility, items, ast_id } = &self.tree[it];
|
||||
let Trait { name, visibility, ast_id } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
self.print_visibility(*visibility);
|
||||
w!(self, "trait {} {{", name.display(self.db, self.edition));
|
||||
self.indented(|this| {
|
||||
for item in &**items {
|
||||
this.print_mod_item((*item).into());
|
||||
}
|
||||
});
|
||||
wln!(self, "}}");
|
||||
w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
|
||||
}
|
||||
ModItem::TraitAlias(it) => {
|
||||
let TraitAlias { name, visibility, ast_id } = &self.tree[it];
|
||||
@ -311,15 +257,9 @@ impl Printer<'_> {
|
||||
wln!(self, "trait {} = ..;", name.display(self.db, self.edition));
|
||||
}
|
||||
ModItem::Impl(it) => {
|
||||
let Impl { items, ast_id } = &self.tree[it];
|
||||
let Impl { ast_id } = &self.tree[it];
|
||||
self.print_ast_id(ast_id.erase());
|
||||
w!(self, "impl {{");
|
||||
self.indented(|this| {
|
||||
for item in &**items {
|
||||
this.print_mod_item((*item).into());
|
||||
}
|
||||
});
|
||||
wln!(self, "}}");
|
||||
w!(self, "impl {{ ... }}");
|
||||
}
|
||||
ModItem::TypeAlias(it) => {
|
||||
let TypeAlias { name, visibility, ast_id } = &self.tree[it];
|
||||
|
@ -73,10 +73,10 @@ extern "C" {
|
||||
fn ex_fn();
|
||||
}
|
||||
"#,
|
||||
expect![[r##"
|
||||
expect![[r#"
|
||||
#[on_extern_block]
|
||||
// AstId: ExternBlock[0000, 0]
|
||||
extern "C" {
|
||||
extern {
|
||||
#[on_extern_type]
|
||||
// AstId: TypeAlias[9FDF, 0]
|
||||
pub(self) type ExType;
|
||||
@ -89,7 +89,7 @@ extern "C" {
|
||||
// AstId: Fn[452D, 0]
|
||||
pub(self) fn ex_fn;
|
||||
}
|
||||
"##]],
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@ -129,39 +129,16 @@ enum E {
|
||||
|
||||
#[derive(Debug)]
|
||||
// AstId: Struct[C7A1, 0]
|
||||
pub(self) struct Struct {
|
||||
#[doc = " fld docs"]
|
||||
pub(self) fld,
|
||||
}
|
||||
pub(self) struct Struct { ... }
|
||||
|
||||
// AstId: Struct[DAC2, 0]
|
||||
pub(self) struct Tuple(
|
||||
#[attr]
|
||||
pub(self) 0,
|
||||
);
|
||||
pub(self) struct Tuple(...);
|
||||
|
||||
// AstId: Union[2DBB, 0]
|
||||
pub(self) union Ize {
|
||||
pub(self) a,
|
||||
pub(self) b,
|
||||
}
|
||||
pub(self) union Ize { ... }
|
||||
|
||||
// AstId: Enum[7FF8, 0]
|
||||
pub(self) enum E {
|
||||
// AstId: Variant[C717, 0]
|
||||
#[doc = " comment on Unit"]
|
||||
Unit,
|
||||
// AstId: Variant[AEAB, 0]
|
||||
#[doc = " comment on Tuple"]
|
||||
Tuple(
|
||||
pub(self) 0,
|
||||
),
|
||||
// AstId: Variant[4B1B, 0]
|
||||
Struct {
|
||||
#[doc = " comment on a: u8"]
|
||||
pub(self) a,
|
||||
},
|
||||
}
|
||||
pub(self) enum E { ... }
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@ -197,13 +174,7 @@ trait Tr: SuperTrait + 'lifetime {
|
||||
pub(self) fn f;
|
||||
|
||||
// AstId: Trait[2998, 0]
|
||||
pub(self) trait Tr {
|
||||
// AstId: TypeAlias[9F08, 0]
|
||||
pub(self) type Assoc;
|
||||
|
||||
// AstId: Fn[6C0C, 0]
|
||||
pub(self) fn method;
|
||||
}
|
||||
pub(self) trait Tr { ... }
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user