Optional constructor

This commit is contained in:
2026-06-12 18:25:26 +02:00
parent d4992e76fc
commit ddcffaea92
4 changed files with 28 additions and 20 deletions
+23 -17
View File
@@ -12,7 +12,7 @@ pub struct ClassProcessedData {
self_path: ExprPath, self_path: ExprPath,
self_ty: TypeExpr, self_ty: TypeExpr,
fields: Vec<Spanned<FieldDeclStmt>>, fields: Vec<Spanned<FieldDeclStmt>>,
constructor: Spanned<ClassConstructor>, constructor: Option<Spanned<ClassConstructor>>,
items: Vec<ClassItem>, items: Vec<ClassItem>,
methods: Vec<Spanned<FunctionDecl>>, methods: Vec<Spanned<FunctionDecl>>,
v_table: Vec<Identifier>, v_table: Vec<Identifier>,
@@ -26,7 +26,7 @@ impl ClassProcessedData {
generics: &GenericsDecl, generics: &GenericsDecl,
inherits: &Option<ExprPath>, inherits: &Option<ExprPath>,
fields: &Vec<Spanned<FieldDeclStmt>>, fields: &Vec<Spanned<FieldDeclStmt>>,
constructor: &Spanned<ClassConstructor>, constructor: &Option<Spanned<ClassConstructor>>,
items: &Vec<ClassItem>, items: &Vec<ClassItem>,
) -> Self { ) -> Self {
let self_path = ExprPath(vec![ExprPathSegment { let self_path = ExprPath(vec![ExprPathSegment {
@@ -136,7 +136,9 @@ impl ClassProcessedData {
self.emit_unified_vtable(cg); self.emit_unified_vtable(cg);
self.emit_super_v_tests(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); self.emit_methods(ctx, cg);
cg.indent -= 1; cg.indent -= 1;
@@ -295,7 +297,7 @@ impl ClassProcessedData {
// Deref tests for override targets // Deref tests for override targets
if self.inherits.is_some() && !self.override_v_table.is_empty() { if self.inherits.is_some() && !self.override_v_table.is_empty() {
cg.add_indentedln("let this: &Self = &unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };"); cg.add_indentedln("let this: &Self = &unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };");
for (override_tier, v) in &self.override_v_table { for (override_tier, v) in &self.override_v_table {
if let Some(path) = &override_tier.0 { if let Some(path) = &override_tier.0 {
@@ -310,20 +312,24 @@ impl ClassProcessedData {
cg.add_indentedln("}"); cg.add_indentedln("}");
} }
fn emit_constructor(&self, ctx: &mut Context, cg: &mut RustCodegen) { fn emit_constructor(
let constructor_comment = self.constructor.get_comment(); &self,
constructor: &Spanned<ClassConstructor>,
ctx: &mut Context,
cg: &mut RustCodegen,
) {
let constructor_comment = constructor.get_comment();
cg.add_indentedln("#[allow(invalid_value)]"); cg.add_indentedln("#[allow(invalid_value)]");
cg.add_indentedln(&constructor_comment); cg.add_indentedln(&constructor_comment);
cg.add_indented(&format!( cg.add_indented(&format!(
"{}fn new{}(", "{}fn new{}(",
self.constructor.item.visibility.get_rust(), constructor.item.visibility.get_rust(),
self.constructor.item.generics.get_rust() constructor.item.generics.get_rust()
)); ));
let params = self let params = constructor
.constructor
.item .item
.params .params
.0 .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 { Spanned {
line: self.constructor.line, line: constructor.line,
column: self.constructor.column, column: constructor.column,
item: FunctionDecl { item: FunctionDecl {
visibility: self.constructor.item.visibility.clone(), visibility: constructor.item.visibility.clone(),
is_override: None, is_override: None,
name: Identifier(String::from("constructor")), name: Identifier(String::from("constructor")),
generics: self.constructor.item.generics.clone(), generics: constructor.item.generics.clone(),
params: ParamList(constructor_params), params: ParamList(constructor_params),
return_type: Some(TypeExpr::Tuple(Vec::new())), return_type: Some(TypeExpr::Tuple(Vec::new())),
body: Some(self.constructor.item.body.clone()), body: Some(constructor.item.body.clone()),
}, },
} }
.gen_rust(ctx, cg); .gen_rust(ctx, cg);
@@ -491,7 +497,7 @@ pub fn class_decl(
generics: &GenericsDecl, generics: &GenericsDecl,
inherits: &Option<ExprPath>, inherits: &Option<ExprPath>,
fields: &Vec<Spanned<FieldDeclStmt>>, fields: &Vec<Spanned<FieldDeclStmt>>,
constructor: &Spanned<ClassConstructor>, constructor: &Option<Spanned<ClassConstructor>>,
items: &Vec<ClassItem>, items: &Vec<ClassItem>,
) { ) {
let data = ClassProcessedData::analyze( let data = ClassProcessedData::analyze(
+1 -1
View File
@@ -56,7 +56,7 @@ pub enum TopLevelKind {
generics: GenericsDecl, generics: GenericsDecl,
inherits: Option<ExprPath>, inherits: Option<ExprPath>,
fields: Vec<Spanned<FieldDeclStmt>>, fields: Vec<Spanned<FieldDeclStmt>>,
constructor: Spanned<ClassConstructor>, constructor: Option<Spanned<ClassConstructor>>,
items: Vec<ClassItem>, items: Vec<ClassItem>,
}, },
} }
+1 -1
View File
@@ -292,7 +292,7 @@ class_item = _{
} }
class_decl = { 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* ~ "}"
} }
// ====================================================== // ======================================================
+3 -1
View File
@@ -75,7 +75,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
fields: collect_recovered(inner.next().unwrap().into_inner()), 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), items: collect_recovered(inner),
}), }),