diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 888a20c..530a79f 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -12,7 +12,7 @@ pub struct ClassProcessedData { self_path: ExprPath, self_ty: TypeExpr, fields: Vec>, - constructor: Spanned, + constructor: Option>, items: Vec, methods: Vec>, v_table: Vec, @@ -26,7 +26,7 @@ impl ClassProcessedData { generics: &GenericsDecl, inherits: &Option, fields: &Vec>, - constructor: &Spanned, + constructor: &Option>, items: &Vec, ) -> Self { let self_path = ExprPath(vec![ExprPathSegment { @@ -136,7 +136,9 @@ impl ClassProcessedData { self.emit_unified_vtable(cg); self.emit_super_v_tests(cg); - self.emit_constructor(ctx, cg); + if let Some(constructor) = &self.constructor { + self.emit_constructor(constructor, ctx, cg); + } self.emit_methods(ctx, cg); cg.indent -= 1; @@ -295,7 +297,7 @@ impl ClassProcessedData { // Deref tests for override targets if self.inherits.is_some() && !self.override_v_table.is_empty() { - cg.add_indentedln("let this: &Self = &unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); + cg.add_indentedln("let this: &Self = &unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); for (override_tier, v) in &self.override_v_table { if let Some(path) = &override_tier.0 { @@ -310,20 +312,24 @@ impl ClassProcessedData { cg.add_indentedln("}"); } - fn emit_constructor(&self, ctx: &mut Context, cg: &mut RustCodegen) { - let constructor_comment = self.constructor.get_comment(); + fn emit_constructor( + &self, + constructor: &Spanned, + ctx: &mut Context, + cg: &mut RustCodegen, + ) { + let constructor_comment = constructor.get_comment(); cg.add_indentedln("#[allow(invalid_value)]"); cg.add_indentedln(&constructor_comment); cg.add_indented(&format!( "{}fn new{}(", - self.constructor.item.visibility.get_rust(), - self.constructor.item.generics.get_rust() + constructor.item.visibility.get_rust(), + constructor.item.generics.get_rust() )); - let params = self - .constructor + let params = constructor .item .params .0 @@ -389,19 +395,19 @@ impl ClassProcessedData { }), }]; - constructor_params.append(&mut self.constructor.item.params.0.clone()); + constructor_params.append(&mut constructor.item.params.0.clone()); Spanned { - line: self.constructor.line, - column: self.constructor.column, + line: constructor.line, + column: constructor.column, item: FunctionDecl { - visibility: self.constructor.item.visibility.clone(), + visibility: constructor.item.visibility.clone(), is_override: None, name: Identifier(String::from("constructor")), - generics: self.constructor.item.generics.clone(), + generics: constructor.item.generics.clone(), params: ParamList(constructor_params), return_type: Some(TypeExpr::Tuple(Vec::new())), - body: Some(self.constructor.item.body.clone()), + body: Some(constructor.item.body.clone()), }, } .gen_rust(ctx, cg); @@ -491,7 +497,7 @@ pub fn class_decl( generics: &GenericsDecl, inherits: &Option, fields: &Vec>, - constructor: &Spanned, + constructor: &Option>, items: &Vec, ) { let data = ClassProcessedData::analyze( diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index 2899893..31847bf 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -56,7 +56,7 @@ pub enum TopLevelKind { generics: GenericsDecl, inherits: Option, fields: Vec>, - constructor: Spanned, + constructor: Option>, items: Vec, }, } diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 7877237..d6e934c 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -292,7 +292,7 @@ class_item = _{ } class_decl = { - visibility? ~ "class" ~ identifier ~ generics_decl? ~ (":" ~ expr_path)? ~ "{" ~ class_fields ~ class_constructor ~ class_item* ~ "}" + visibility? ~ "class" ~ identifier ~ generics_decl? ~ (":" ~ expr_path)? ~ "{" ~ class_fields ~ class_constructor? ~ class_item* ~ "}" } // ====================================================== diff --git a/crates/parser/src/parser/items/mod.rs b/crates/parser/src/parser/items/mod.rs index 58c3bd2..1bae6d0 100644 --- a/crates/parser/src/parser/items/mod.rs +++ b/crates/parser/src/parser/items/mod.rs @@ -75,7 +75,9 @@ impl<'a> TryFrom> for TopLevelKind { fields: collect_recovered(inner.next().unwrap().into_inner()), - constructor: inner.next().unwrap().try_into(), + constructor: consume_rule(&mut inner, Rule::class_constructor) + .map(Spanned::try_from) + .transpose(), items: collect_recovered(inner), }),