Skip to content
Permalink
Tree: f0710305f1
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
182 lines (166 sloc) 5.92 KB
use crate::macros::EntityMacroDefinition;
use crate::parser::Parser;
use crate::syntax::delimited::Delimited;
use crate::syntax::entity::{
InvalidParsedEntity, LazyParsedEntity, ParsedEntity, ParsedEntityThunk,
};
use crate::syntax::identifier::SpannedGlobalIdentifier;
use crate::syntax::list::CommaList;
use crate::syntax::member::{Member, ParsedMember};
use crate::syntax::sigil::Curlies;
use crate::syntax::skip_newline::SkipNewline;
use crate::ParserDatabase;
use lark_collections::Seq;
use lark_debug_with::DebugWith;
use lark_entity::Entity;
use lark_entity::EntityData;
use lark_entity::ItemKind;
use lark_entity::MemberKind;
use lark_error::ErrorReported;
use lark_error::ErrorSentinel;
use lark_error::WithError;
use lark_hir as hir;
use lark_intern::Intern;
use lark_span::FileName;
use lark_span::Spanned;
use lark_string::GlobalIdentifier;
use lark_ty as ty;
use lark_ty::declaration::Declaration;
use std::sync::Arc;
/// ```ignore
/// struct <id> {
/// <id>: <ty> // separated by `,` or newline
/// }
/// ```
#[derive(Default)]
pub struct StructDeclaration;
impl EntityMacroDefinition for StructDeclaration {
fn expect(
&self,
parser: &mut Parser<'_>,
base: Entity,
macro_name: Spanned<GlobalIdentifier, FileName>,
) -> Result<ParsedEntity, ErrorReported> {
log::trace!(
"StructDeclaration::parse(base={}, macro_name={})",
base.debug_with(parser),
macro_name.debug_with(parser)
);
log::trace!("StructDeclaration::parse: parsing name");
let struct_name = parser.expect(SkipNewline(SpannedGlobalIdentifier))?;
log::trace!("StructDeclaration::parse: parsing fields");
let fields = parser
.expect(SkipNewline(Delimited(Curlies, CommaList(Member))))
.unwrap_or_else(|ErrorReported(_)| Seq::default());
log::trace!("StructDeclaration::parse: done");
let entity = EntityData::ItemName {
base,
kind: ItemKind::Struct,
id: struct_name.value,
}
.intern(parser);
let full_span = macro_name.span.extended_until_end_of(parser.last_span());
let characteristic_span = struct_name.span;
Ok(ParsedEntity::new(
entity,
full_span,
characteristic_span,
ParsedEntityThunk::new(ParsedStructDeclaration { fields }),
))
}
}
struct ParsedStructDeclaration {
fields: Seq<Spanned<ParsedMember, FileName>>,
}
impl LazyParsedEntity for ParsedStructDeclaration {
fn parse_children(
&self,
entity: Entity,
db: &dyn ParserDatabase,
) -> WithError<Seq<ParsedEntity>> {
WithError::ok(
self.fields
.iter()
.map(
|Spanned {
value: member,
span,
}| {
match member {
ParsedMember::ParsedField(field) => {
let field_entity = EntityData::MemberName {
base: entity,
kind: MemberKind::Field,
id: field.name.value,
}
.intern(&db);
ParsedEntity::new(
field_entity,
*span,
field.name.span,
ParsedEntityThunk::new(field.clone()),
)
}
ParsedMember::ParsedMethod(method) => {
let method_entity = EntityData::MemberName {
base: entity,
kind: MemberKind::Method,
id: method.name.value,
}
.intern(&db);
ParsedEntity::new(
method_entity,
*span,
method.name.span,
ParsedEntityThunk::new(method.clone()),
)
}
}
},
)
.collect(),
)
}
fn parse_generic_declarations(
&self,
_entity: Entity,
_db: &dyn ParserDatabase,
) -> WithError<Result<Arc<ty::GenericDeclarations>, ErrorReported>> {
// FIXME -- no support for generics yet
WithError::ok(Ok(ty::GenericDeclarations::empty(None)))
}
fn parse_signature(
&self,
entity: Entity,
db: &dyn ParserDatabase,
) -> WithError<Result<ty::Signature<Declaration>, ErrorReported>> {
InvalidParsedEntity.parse_signature(entity, db)
}
fn parse_type(
&self,
entity: Entity,
db: &dyn ParserDatabase,
) -> WithError<ty::Ty<Declaration>> {
// For each struct `Foo`, the "type" is just `own Foo`
match db.generic_declarations(entity).into_value() {
Ok(generic_declarations) => {
assert!(generic_declarations.is_empty());
let ty = crate::type_conversion::declaration_ty_named(
&db,
entity,
ty::declaration::DeclaredPermKind::Own,
ty::ReprKind::Direct,
ty::Generics::empty(),
);
WithError::ok(ty)
}
Err(err) => WithError::error_sentinel(&db, err),
}
}
fn parse_fn_body(&self, entity: Entity, db: &dyn ParserDatabase) -> WithError<hir::FnBody> {
panic!(
"cannot parse fn body of a struct: {:?}",
entity.debug_with(db)
)
}
}
You can’t perform that action at this time.