Skip to content

Commit

Permalink
impl Default for structs with pointers too
Browse files Browse the repository at this point in the history
  • Loading branch information
maia-s committed Jan 2, 2025
1 parent 9b10a2d commit 82d5c81
Show file tree
Hide file tree
Showing 17 changed files with 638 additions and 56 deletions.
95 changes: 70 additions & 25 deletions sdl3-sys-gen/src/emit.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{
common_ident_prefix,
parse::{
ArgDecl, CanCopy, Conditional, ConditionalExpr, Define, DocComment, DocCommentFile, Expr,
FnAbi, FnDeclArgs, FnPointer, Function, GetSpan, Ident, IdentOrKwT, Include,
IntegerLiteral, Item, Items, Literal, ParseErr, PreProcBlock, PrimitiveType, StructFields,
StructKind, StructOrUnion, Type, TypeDef, TypeEnum,
ArgDecl, CanCopy, CanDefault, Conditional, ConditionalExpr, Define, DocComment,
DocCommentFile, Expr, FnAbi, FnDeclArgs, FnPointer, Function, GetSpan, Ident, IdentOrKwT,
Include, IntegerLiteral, Item, Items, Literal, ParseErr, PreProcBlock, PrimitiveType,
StructFields, StructKind, StructOrUnion, Type, TypeDef, TypeEnum,
},
};
use std::{
Expand Down Expand Up @@ -652,7 +652,7 @@ impl Emit for Define {
SymKind::Other,
false,
arg.ty.can_derive_debug(ctx),
arg.ty.can_derive_default(ctx),
arg.ty.can_default(ctx),
)?;
}
let _guard = ctx.expect_unresolved_sym_dependency_guard();
Expand Down Expand Up @@ -709,7 +709,7 @@ impl Emit for Define {
SymKind::Other,
false,
false,
false,
CanDefault::No,
)?;
writeln!(ctx, "{f}")?;
return Ok(());
Expand All @@ -736,7 +736,7 @@ impl Emit for Define {
SymKind::Other,
true,
ty.can_derive_debug(ctx),
ty.can_derive_default(ctx),
ty.can_default(ctx),
)?;
self.doc.emit(ctx)?;
write!(ctx, "pub const ")?;
Expand Down Expand Up @@ -799,7 +799,7 @@ impl Emit for Function {
SymKind::Other,
false,
false,
false,
CanDefault::No,
)?;
emit_extern_start(ctx, &self.abi, false)?;
self.doc.emit(ctx)?;
Expand Down Expand Up @@ -831,7 +831,7 @@ impl Emit for Function {
SymKind::Other,
false,
arg.ty.can_derive_debug(&ctx_body),
arg.ty.can_derive_default(&ctx_body),
arg.ty.can_default(&ctx_body),
)?;
}
}
Expand All @@ -857,7 +857,7 @@ impl Emit for Function {
SymKind::Other,
false,
false,
false,
CanDefault::No,
)?;

self.doc.emit(ctx)?;
Expand Down Expand Up @@ -962,18 +962,21 @@ impl StructOrUnion {
true
}

pub fn can_derive_default(&self, ctx: &EmitContext) -> bool {
pub fn can_default(&self, ctx: &EmitContext) -> CanDefault {
if !self.can_construct || matches!(self.kind, StructKind::Union) {
return false;
return CanDefault::No;
}
let mut can = CanDefault::Derive;
if let Some(fields) = &self.fields {
for field in fields.fields.iter() {
if !field.ty.can_derive_default(ctx) {
return false;
match field.ty.can_default(ctx) {
CanDefault::Derive => (),
CanDefault::Manual => can = CanDefault::Manual,
CanDefault::No => return CanDefault::No,
}
}
}
true
can
}

pub fn emit_with_doc_and_ident(
Expand Down Expand Up @@ -1027,6 +1030,11 @@ impl StructOrUnion {
let can_derive_copy = !is_interface
&& (sym.can_copy == CanCopy::Always
|| (sym.can_copy != CanCopy::Never && self.can_derive_copy(ctx, Some(fields))));
let can_default = if is_interface || !sym.can_construct {
CanDefault::No
} else {
self.can_default(ctx)
};

let ctx_ool = &mut { ctx.with_ool_output() };
if self.hidden {
Expand All @@ -1047,7 +1055,7 @@ impl StructOrUnion {
r#"#[cfg_attr(feature = "debug-impls", derive(Debug))]"#
)?;
}
if !is_interface && sym.can_construct && self.can_derive_default(ctx_ool) {
if can_default == CanDefault::Derive {
writeln!(ctx_ool, "#[derive(Default)]")?;
}
writeln!(
Expand All @@ -1071,6 +1079,29 @@ impl StructOrUnion {
writeln!(ctx_ool, "}}")?;
writeln!(ctx_ool)?;

if can_default == CanDefault::Manual {
writeln!(ctx_ool, "impl ::core::default::Default for {ident} {{")?;
ctx_ool.increase_indent();
writeln!(ctx_ool, "#[inline(always)]")?;
writeln!(ctx_ool, "fn default() -> Self {{")?;
ctx_ool.increase_indent();
writeln!(ctx_ool, "Self {{")?;
ctx_ool.increase_indent();
for field in fields.fields.iter() {
field.ident.emit(ctx_ool)?;
write!(ctx_ool, ": ")?;
field.ty.emit_default_value(ctx_ool)?;
writeln!(ctx_ool, ",")?;
}
ctx_ool.decrease_indent();
writeln!(ctx_ool, "}}")?;
ctx_ool.decrease_indent();
writeln!(ctx_ool, "}}")?;
ctx_ool.decrease_indent();
writeln!(ctx_ool, "}}")?;
writeln!(ctx_ool)?;
}

if is_interface {
writeln!(ctx_ool, "impl {ident} {{")?;
ctx_ool.increase_indent();
Expand Down Expand Up @@ -1173,6 +1204,20 @@ impl Type {
}
Ok(None)
}

pub fn emit_default_value(&self, ctx: &mut EmitContext) -> EmitResult {
match &self.ty {
TypeEnum::Pointer(p) => {
if p.is_const {
write!(ctx, "::core::ptr::null()")?
} else {
write!(ctx, "::core::ptr::null_mut()")?
}
}
_ => write!(ctx, "::core::default::Default::default()")?,
}
Ok(())
}
}

impl Emit for Type {
Expand Down Expand Up @@ -1314,7 +1359,7 @@ impl Emit for TypeDef {
SymKind::Other,
true,
true,
true,
CanDefault::Derive,
)?;
self.doc.emit(ctx)?;
write!(ctx, "{assoc_doc}")?;
Expand All @@ -1339,7 +1384,7 @@ impl Emit for TypeDef {
sym.kind,
sym.can_derive_copy,
sym.can_derive_debug,
sym.can_derive_default,
sym.can_default,
)?;
self.doc.emit(ctx)?;
write!(ctx, "{assoc_doc}")?;
Expand Down Expand Up @@ -1396,7 +1441,7 @@ impl Emit for TypeDef {
SymKind::Other,
true,
true,
true,
CanDefault::Derive,
)?;

let mut doc_consts = String::new();
Expand Down Expand Up @@ -1436,7 +1481,7 @@ impl Emit for TypeDef {
SymKind::Other,
true,
true,
true,
CanDefault::Derive,
)?;

let variant_ident = variant.ident.as_str();
Expand Down Expand Up @@ -1615,7 +1660,7 @@ impl Emit for TypeDef {
}(s.ident.clone().unwrap()),
s.can_derive_copy(ctx, None),
s.can_derive_debug(ctx),
s.can_derive_default(ctx),
s.can_default(ctx),
)?;

ctx.flush_ool_output()?;
Expand Down Expand Up @@ -1643,7 +1688,7 @@ impl Emit for TypeDef {
SymKind::Other,
false,
true,
false,
CanDefault::Manual,
)?;
self.doc.emit(ctx)?;
write!(ctx, "pub type {} = ", self.ident.as_str())?;
Expand All @@ -1662,7 +1707,7 @@ impl Emit for TypeDef {
SymKind::Other,
ty.can_derive_copy(ctx),
ty.can_derive_debug(ctx),
ty.can_derive_default(ctx),
ty.can_default(ctx),
)?;
self.doc.emit(ctx)?;
todo!()
Expand All @@ -1677,7 +1722,7 @@ impl Emit for TypeDef {
SymKind::Other,
false,
true,
true,
CanDefault::Derive,
)?;
self.doc.emit(ctx)?;
write!(
Expand Down Expand Up @@ -1709,7 +1754,7 @@ impl Emit for TypeDef {
SymKind::Other,
r.can_derive_copy,
r.can_derive_debug,
r.can_derive_default,
r.can_default,
)?;
writeln!(ctx, "pub type {} = {};", self.ident.as_str(), r.string)?;
Ok(())
Expand Down
8 changes: 4 additions & 4 deletions sdl3-sys-gen/src/emit/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use super::{
EmitResult, Eval, Sym,
};
use crate::parse::{
Alternative, Ambiguous, BinaryOp, Cast, DefineValue, Expr, FloatLiteral, FnCall, GetSpan,
Ident, IntegerLiteral, IntegerLiteralType, Literal, Op, Parenthesized, ParseErr, PrimitiveType,
RustCode, RustType, SizeOf, Span, StringLiteral, Ternary, Type, TypeEnum,
Alternative, Ambiguous, BinaryOp, CanDefault, Cast, DefineValue, Expr, FloatLiteral, FnCall,
GetSpan, Ident, IntegerLiteral, IntegerLiteralType, Literal, Op, Parenthesized, ParseErr,
PrimitiveType, RustCode, RustType, SizeOf, Span, StringLiteral, Ternary, Type, TypeEnum,
};
use core::fmt::{self, Display, Write};

Expand Down Expand Up @@ -114,7 +114,7 @@ impl Value {
string: STRING_TYPE.into(),
can_derive_copy: true,
can_derive_debug: true,
can_derive_default: true,
can_default: CanDefault::Manual,
})),
Value::RustCode(r) => Ok(r.ty.clone()),
Value::TargetDependent(_) => todo!(),
Expand Down
12 changes: 6 additions & 6 deletions sdl3-sys-gen/src/emit/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use super::{
Cfg, DefineState, Emit, EmitContext, EmitErr, EmitResult, Eval, StructSym, SymKind, Value,
};
use crate::parse::{
Block, Define, DefineValue, Expr, FnCall, Function, GetSpan, Ident, IdentOrKw, Item, Items,
Kw_static, ParseErr, RustCode, Span, StringLiteral, Type, TypeDef,
Block, CanDefault, Define, DefineValue, Expr, FnCall, Function, GetSpan, Ident, IdentOrKw,
Item, Items, Kw_static, ParseErr, RustCode, Span, StringLiteral, Type, TypeDef,
};
use core::fmt::Write;
use std::ffi::CString;
Expand Down Expand Up @@ -277,7 +277,7 @@ const EMIT_DEFINE_PATCHES: &[EmitDefinePatch] = &[
SymKind::Other,
false,
false,
false,
CanDefault::No,
)?;
define.doc.emit(ctx)?;
ctx.write_str(str_block! {r#"
Expand All @@ -302,7 +302,7 @@ const EMIT_DEFINE_PATCHES: &[EmitDefinePatch] = &[
SymKind::Other,
false,
false,
false,
CanDefault::No,
)?;
define.doc.emit(ctx)?;
ctx.write_str(str_block! {r#"
Expand Down Expand Up @@ -650,7 +650,7 @@ fn emit_begin_end_thread_function(ctx: &mut EmitContext) -> EmitResult {
SymKind::Other,
false,
true,
false,
CanDefault::No,
)?;
ctx.register_sym(
etf,
Expand All @@ -660,7 +660,7 @@ fn emit_begin_end_thread_function(ctx: &mut EmitContext) -> EmitResult {
SymKind::Other,
false,
true,
false,
CanDefault::No,
)?;

let cfg_default = "#[cfg(not(windows))]";
Expand Down
12 changes: 6 additions & 6 deletions sdl3-sys-gen/src/emit/state.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::{patch::patch_emit_opaque_struct, Emit, EmitErr, EmitResult, Eval, Value};
use crate::{
parse::{
CanCopy, DefineArg, DefineValue, DocComment, Expr, GetSpan, Ident, IdentOrKw, ParseErr,
PrimitiveType, RustCode, Span, StructFields, StructKind, Type, TypeEnum,
CanCopy, CanDefault, DefineArg, DefineValue, DocComment, Expr, GetSpan, Ident, IdentOrKw,
ParseErr, PrimitiveType, RustCode, Span, StructFields, StructKind, Type, TypeEnum,
},
Defer, Gen,
};
Expand Down Expand Up @@ -653,7 +653,7 @@ impl<'a, 'b> EmitContext<'a, 'b> {
kind: SymKind,
can_derive_copy: bool,
can_derive_debug: bool,
can_derive_default: bool,
can_default: CanDefault,
) -> EmitResult {
let module = self.inner().module.clone();
self.scope_mut().register_sym(Sym {
Expand All @@ -665,7 +665,7 @@ impl<'a, 'b> EmitContext<'a, 'b> {
kind,
can_derive_copy,
can_derive_debug,
can_derive_default,
can_default,
})?;
self.emit_pending()?;
Ok(())
Expand Down Expand Up @@ -1077,7 +1077,7 @@ pub struct Sym {
pub kind: SymKind,
pub can_derive_copy: bool,
pub can_derive_debug: bool,
pub can_derive_default: bool,
pub can_default: CanDefault,
}

impl Sym {
Expand Down Expand Up @@ -1395,7 +1395,7 @@ impl InnerScope {
}(sym.ident.clone()),
can_derive_copy: false,
can_derive_debug: false,
can_derive_default: false,
can_default: CanDefault::No,
})?;
}

Expand Down
Loading

0 comments on commit 82d5c81

Please sign in to comment.