From 050019c8c06eccf6bcfe3a6482517909c21b16a9 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 6 Oct 2026 07:23:25 -0400 Subject: [PATCH] more tests and fixes --- base/components/code_serialization.cpp | 12 ++-- test/c_library/test.c | 98 +++++++++++++++++--------- test/cpp_library/test.cpp | 81 ++++++++++++++------- 3 files changed, 121 insertions(+), 70 deletions(-) diff --git a/base/components/code_serialization.cpp b/base/components/code_serialization.cpp index 648d344..32237a1 100644 --- a/base/components/code_serialization.cpp +++ b/base/components/code_serialization.cpp @@ -263,12 +263,12 @@ void destructor_to_strbuilder_def(CodeDestructor self, StrBuilder* result ) else if ( self->Specs ) { if ( specifiers_has(self->Specs, Spec_Virtual ) ) - strbuilder_append_fmt( result, "virtual ~%S()", self->Parent->Name ); + strbuilder_append_fmt( result, "virtual ~%S()", self->Parent->Parent->Name ); else - strbuilder_append_fmt( result, "~%S()", self->Parent->Name ); + strbuilder_append_fmt( result, "~%S()", self->Parent->Parent->Name ); } else - strbuilder_append_fmt( result, "~%S()", self->Parent->Name ); + strbuilder_append_fmt( result, "~%S()", self->Parent->Parent->Name ); strbuilder_append_fmt( result, "\n{\n%SB\n}\n", code_to_strbuilder(self->Body) ); } @@ -629,9 +629,6 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) if ( self->Attributes ) strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); - if ( self->Attributes ) - strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); - if ( self->Specs ) { for ( Specifier* spec = begin_CodeSpecifiers(self->Specs); spec != end_CodeSpecifiers(self->Specs); spec = next_CodeSpecifiers(self->Specs, spec) ) @@ -644,8 +641,7 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) } } - if ( self->Attributes || self->Specs ) - { + if ( self->Attributes || self->Specs ) { strbuilder_append_str( result, txt("\n") ); } diff --git a/test/c_library/test.c b/test/c_library/test.c index 8571a11..fb46b26 100644 --- a/test/c_library/test.c +++ b/test/c_library/test.c @@ -117,10 +117,14 @@ int main() expect((gen_Code)option_class->Specs == (gen_Code)class_specifiers, gen_txt("c11 class specifiers")); expect( option_class->ModuleFlags == ModuleFlag_Export, gen_txt("c11 class module flags")); gen_Str class_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_class)); - expect(gen_str_contains(class_text, gen_txt("ClassOption")), gen_txt("c11 class name serialization")); - expect(gen_str_contains(class_text, gen_txt("ClassOptionBase")), gen_txt("c11 class parent serialization")); - expect(gen_str_contains(class_text, gen_txt("IClassOption")), gen_txt("c11 class interface serialization")); - expect(gen_str_contains(class_text, gen_txt("public")), gen_txt("c11 class access serialization")); + expect(gen_str_contains(class_text, gen_txt("ClassOption")), gen_txt("c11 class name serialization")); + expect(gen_str_contains(class_text, gen_txt("ClassOptionBase")), gen_txt("c11 class parent serialization")); + expect(gen_str_contains(class_text, gen_txt("IClassOption")), gen_txt("c11 class interface serialization")); + expect(gen_str_contains(class_text, gen_txt("public")), gen_txt("c11 class access serialization")); + expect(gen_str_contains(class_text, gen_txt("class_option_member")), gen_txt("c11 class body serialization")); + expect(gen_str_contains(class_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 class attribute serialization")); + expect(gen_str_contains(class_text, gen_txt("final")), gen_txt("c11 class final specifier serialization")); + expect(gen_str_contains(class_text, gen_txt("export")), gen_txt("c11 class module flag serialization")); } gen_CodeVar struct_member = gen_def_variable(gen_def_type(name(u32)), name(struct_option_member)); @@ -149,10 +153,14 @@ int main() expect((gen_Code)option_struct->Specs == (gen_Code)struct_specifiers, gen_txt("c11 struct specifiers")); expect( option_struct->ModuleFlags == ModuleFlag_Export, gen_txt("c11 struct module flags")); gen_Str struct_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_struct)); - expect(gen_str_contains(struct_text, gen_txt("StructOption")), gen_txt("c11 struct name serialization")); - expect(gen_str_contains(struct_text, gen_txt("StructOptionBase")), gen_txt("c11 struct parent serialization")); - expect(gen_str_contains(struct_text, gen_txt("IStructOption")), gen_txt("c11 struct interface serialization")); - expect(gen_str_contains(struct_text, gen_txt("public")), gen_txt("c11 struct access serialization")); + expect(gen_str_contains(struct_text, gen_txt("StructOption")), gen_txt("c11 struct name serialization")); + expect(gen_str_contains(struct_text, gen_txt("StructOptionBase")), gen_txt("c11 struct parent serialization")); + expect(gen_str_contains(struct_text, gen_txt("IStructOption")), gen_txt("c11 struct interface serialization")); + expect(gen_str_contains(struct_text, gen_txt("public")), gen_txt("c11 struct access serialization")); + expect(gen_str_contains(struct_text, gen_txt("struct_option_member")), gen_txt("c11 struct body serialization")); + expect(gen_str_contains(struct_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 struct attribute serialization")); + expect(gen_str_contains(struct_text, gen_txt("final")), gen_txt("c11 struct final specifier serialization")); + expect(gen_str_contains(struct_text, gen_txt("export")), gen_txt("c11 struct module flag serialization")); } gen_CodeBody enum_body = gen_def_enum_body(1, code_pod((gen_Code)gen_untyped_str(gen_txt("Option_None")))); @@ -173,10 +181,11 @@ int main() expect((gen_Code)option_enum->Attributes == (gen_Code)enum_attributes, gen_txt("c11 enum attributes")); expect( option_enum->ModuleFlags == ModuleFlag_Export, gen_txt("c11 enum module flags")); gen_Str enum_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_enum)); - expect(gen_str_contains(enum_text, gen_txt("export")), gen_txt("c11 enum module flag serialization")); - expect(gen_str_contains(enum_text, gen_txt("enum class")), gen_txt("c11 enum specifier serialization")); - expect(gen_str_contains(enum_text, gen_txt("u32")), gen_txt("c11 enum type serialization")); - expect(gen_str_contains(enum_text, gen_txt("Option_None")), gen_txt("c11 enum body serialization")); + expect(gen_str_contains(enum_text, gen_txt("export")), gen_txt("c11 enum module flag serialization")); + expect(gen_str_contains(enum_text, gen_txt("enum class")), gen_txt("c11 enum specifier serialization")); + expect(gen_str_contains(enum_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 enum attribute serialization")); + expect(gen_str_contains(enum_text, gen_txt("u32")), gen_txt("c11 enum type serialization")); + expect(gen_str_contains(enum_text, gen_txt("Option_None")), gen_txt("c11 enum body serialization")); } gen_Code enum_macro = gen_untyped_str(gen_txt("ENUM_BASE_TYPE")); @@ -273,8 +282,9 @@ int main() expect(option_macro != 0, gen_txt("c11 define registration")); if (option_macro != 0) expect(option_macro->Flags == define_flags, gen_txt("c11 define flags")); gen_Str define_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_define)); - expect(gen_str_contains(define_text, gen_txt("OptionMacro")), gen_txt("c11 define name serialization")); - expect(gen_str_contains(define_text, gen_txt("param + 1")), gen_txt("c11 define content serialization")); + expect(gen_str_contains(define_text, gen_txt("OptionMacro")), gen_txt("c11 define name serialization")); + expect(gen_str_contains(define_text, gen_txt("OptionMacro( param)")), gen_txt("c11 define parameters serialization")); + expect(gen_str_contains(define_text, gen_txt("param + 1")), gen_txt("c11 define content serialization")); } gen_CodeDefine no_register_define = gen_def_define(name(OptionMacroNoRegister), MT_Expression, @@ -293,6 +303,8 @@ int main() expect(foreign_include != 0, gen_txt("c11 foreign include option")); if (foreign_include != 0) { expect(gen_str_contains(foreign_include->Content, gen_txt("")), gen_txt("c11 foreign include path")); + gen_Str include_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)foreign_include)); + expect(gen_str_contains(include_text, gen_txt("#include ")), gen_txt("c11 foreign include directive serialization")); } gen_CodeModule option_module = gen_def_module(name(OptionModule), .mflags = ModuleFlag_Export); @@ -309,7 +321,7 @@ int main() if (option_namespace != 0) { expect((gen_Code)option_namespace->Body == (gen_Code)namespace_body, gen_txt("c11 namespace body")); expect( option_namespace->ModuleFlags == ModuleFlag_Export, gen_txt("c11 namespace flags")); - gen_Str namespace_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Csode)option_namespace)); + gen_Str namespace_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_namespace)); expect(gen_str_contains(namespace_text, gen_txt("OptionNamespace")), gen_txt("c11 namespace name serialization")); expect(gen_str_contains(namespace_text, gen_txt("namespace_option_value")), gen_txt("c11 namespace body serialization")); expect(gen_str_contains(namespace_text, gen_txt("export")), gen_txt("c11 namespace serialization")); @@ -325,7 +337,7 @@ int main() } gen_CodeParams function_params = gen_def_param(gen_def_type(name(u32)), name(function_option_arg)); - gen_CodeTypename function_return = gen_def_type(name(u32)); + gen_CodeTypename function_return = gen_def_type(name(FunctionOptionReturn)); gen_CodeBody function_body = gen_def_function_body(1, code_pod((gen_Code)gen_untyped_str(gen_txt("return function_option_arg;")))); gen_CodeAttributes function_attributes = gen_def_attributes(gen_txt("[[maybe_unused]]")); gen_CodeSpecifiers function_specs = gen_def_specifier(Spec_Inline); @@ -346,12 +358,13 @@ int main() expect((gen_Code)option_function->Attributes == (gen_Code)function_attributes, gen_txt("c11 function attributes")); expect( option_function->ModuleFlags == ModuleFlag_Export, gen_txt("c11 function module flags")); gen_Str function_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_function)); - expect(gen_str_contains(function_text, gen_txt("OptionFunction")), gen_txt("c11 function name serialization")); - expect(gen_str_contains(function_text, gen_txt("function_option_arg")), gen_txt("c11 function parameters serialization")); - expect(gen_str_contains(function_text, gen_txt("return function_option_arg")), gen_txt("c11 function body serialization")); - expect(gen_str_contains(function_text, gen_txt("inline")), gen_txt("c11 function specifier serialization")); - expect(gen_str_contains(function_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 function attribute serialization")); - expect(gen_str_contains(function_text, gen_txt("export")), gen_txt("c11 function module flag serialization")); + expect(gen_str_contains(function_text, gen_txt("OptionFunction")), gen_txt("c11 function name serialization")); + expect(gen_str_contains(function_text, gen_txt("FunctionOptionReturn OptionFunction(")), gen_txt("c11 function return type serialization")); + expect(gen_str_contains(function_text, gen_txt("function_option_arg")), gen_txt("c11 function parameters serialization")); + expect(gen_str_contains(function_text, gen_txt("return function_option_arg")), gen_txt("c11 function body serialization")); + expect(gen_str_contains(function_text, gen_txt("inline")), gen_txt("c11 function specifier serialization")); + expect(gen_str_contains(function_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 function attribute serialization")); + expect(gen_str_contains(function_text, gen_txt("export")), gen_txt("c11 function module flag serialization")); } gen_CodeParams constructor_params = gen_def_param(gen_def_type(name(u32)), name(constructor_option_arg)); @@ -375,9 +388,10 @@ int main() expect(constructor_class != 0, gen_txt("c11 constructor serialization parent")); if (constructor_class != 0) { gen_Str constructor_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)constructor_class)); - expect(gen_str_contains(constructor_text, gen_txt("ConstructorOptions(")), gen_txt("c11 constructor name serialization")); - expect(gen_str_contains(constructor_text, gen_txt("option_member( 0 )")), gen_txt("c11 constructor initializer serialization")); - expect(gen_str_contains(constructor_text, gen_txt("constructor_option_arg")), gen_txt("c11 constructor body serialization")); + expect(gen_str_contains(constructor_text, gen_txt("ConstructorOptions(")), gen_txt("c11 constructor name serialization")); + expect(gen_str_contains(constructor_text, gen_txt("u32 constructor_option_arg")), gen_txt("c11 constructor parameter serialization")); + expect(gen_str_contains(constructor_text, gen_txt("option_member( 0 )")), gen_txt("c11 constructor initializer serialization")); + expect(gen_str_contains(constructor_text, gen_txt("constructor_option_arg")), gen_txt("c11 constructor body serialization")); } gen_Code destructor_body = gen_untyped_str(gen_txt("release_option_resource();")); @@ -390,19 +404,29 @@ int main() if (option_destructor != 0) { expect(option_destructor->Body == destructor_body, gen_txt("c11 destructor body")); expect((gen_Code)option_destructor->Specs == (gen_Code)destructor_specs, gen_txt("c11 destructor specifiers")); + gen_Code_POD destructor_pod = code_pod((gen_Code)option_destructor); + gen_CodeBody destructor_class_body = gen_def_class_body(1, destructor_pod); + gen_CodeClass destructor_class = gen_def_class(name(DestructorOptions), .body = destructor_class_body); + expect(destructor_class != 0, gen_txt("c11 destructor serialization parent")); + if (destructor_class != 0) { + gen_Str destructor_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)destructor_class)); + if (gen_str_contains(destructor_text, gen_txt("virtual ~DestructorOptions()")) == false) gen_log_fmt("%S\n", destructor_text); + expect(gen_str_contains(destructor_text, gen_txt("virtual ~DestructorOptions()")), gen_txt("c11 destructor signature serialization")); + expect(gen_str_contains(destructor_text, gen_txt("release_option_resource();")), gen_txt("c11 destructor body serialization")); + } } - gen_CodeTypename operator_type = gen_def_type(name(OperatorOptionType)); - gen_CodeParams operator_lhs = gen_def_param(operator_type, name(operator_option_lhs)); - gen_CodeParams operator_rhs = gen_def_param(operator_type, name(operator_option_rhs)); - gen_CodeParams operator_params_array[] = { operator_lhs, operator_rhs }; - gen_CodeParams operator_params = gen_def_params_arr(2, operator_params_array); - gen_CodeBody operator_body = gen_def_function_body(1, code_pod((gen_Code)gen_untyped_str(gen_txt("return operator_option_lhs;")))); - gen_CodeSpecifiers operator_specs = gen_def_specifier(Spec_Inline); - gen_CodeAttributes operator_attributes = gen_def_attributes(gen_txt("[[maybe_unused]]")); + gen_CodeTypename operator_type = gen_def_type(name(OperatorOptionType)); + gen_CodeTypename operator_return = gen_def_type(name(OperatorOptionReturn)); + gen_CodeParams operator_lhs = gen_def_param(operator_type, name(operator_option_lhs)); + gen_CodeParams operator_rhs = gen_def_param(operator_type, name(operator_option_rhs)); + gen_CodeParams operator_params = gen_def_params(2, code_pod((gen_Code)operator_lhs), code_pod((gen_Code)operator_rhs)); + gen_CodeBody operator_body = gen_def_function_body(1, code_pod((gen_Code)gen_untyped_str(gen_txt("return operator_option_lhs;")))); + gen_CodeSpecifiers operator_specs = gen_def_specifier(Spec_Inline); + gen_CodeAttributes operator_attributes = gen_def_attributes(gen_txt("[[maybe_unused]]")); gen_CodeOperator option_operator = gen_def_operator(Op_Add, gen_txt(""), .params = operator_params, - .ret_type = operator_type, + .ret_type = operator_return, .body = operator_body, .specifiers = operator_specs, .attributes = operator_attributes, @@ -411,18 +435,22 @@ int main() expect(option_operator != 0, gen_txt("c11 operator options")); if (option_operator != 0) { expect((gen_Code)option_operator->Params == (gen_Code)operator_params, gen_txt("c11 operator parameters")); - expect((gen_Code)option_operator->ReturnType == (gen_Code)operator_type, gen_txt("c11 operator return type")); + expect((gen_Code)option_operator->ReturnType == (gen_Code)operator_return, gen_txt("c11 operator return type")); expect((gen_Code)option_operator->Body == (gen_Code)operator_body, gen_txt("c11 operator body")); expect((gen_Code)option_operator->Specs == (gen_Code)operator_specs, gen_txt("c11 operator specifiers")); expect((gen_Code)option_operator->Attributes == (gen_Code)operator_attributes, gen_txt("c11 operator attributes")); expect( option_operator->ModuleFlags == ModuleFlag_Export, gen_txt("c11 operator module flags")); gen_Str operator_text = gen_strbuilder_to_str(gen_code_to_strbuilder((gen_Code)option_operator)); + expect(gen_str_contains(operator_text, gen_txt("OperatorOptionReturn")), gen_txt("c11 operator return type serialization")); expect(gen_str_contains(operator_text, gen_txt("operator +")), gen_txt("c11 operator name serialization")); expect(gen_str_contains(operator_text, gen_txt("operator_option_lhs")), gen_txt("c11 operator parameters serialization")); + expect(gen_str_contains(operator_text, gen_txt("operator_option_rhs")), gen_txt("c11 operator second parameter serialization")); expect(gen_str_contains(operator_text, gen_txt("return operator_option_lhs")), gen_txt("c11 operator body serialization")); expect(gen_str_contains(operator_text, gen_txt("inline")), gen_txt("c11 operator specifier serialization")); expect(gen_str_contains(operator_text, gen_txt("[[maybe_unused]]")), gen_txt("c11 operator attribute serialization")); expect(gen_str_contains(operator_text, gen_txt("export")), gen_txt("c11 operator module flag serialization")); + if (gen_str_starts_with(operator_text, gen_txt("export [[maybe_unused]] inline\nOperatorOptionReturn")) == false) gen_log_fmt("%S\n", operator_text); + expect(gen_str_starts_with(operator_text, gen_txt("export [[maybe_unused]] inline\nOperatorOptionReturn")), gen_txt("c11 operator one-attribute prefix serialization")); } gen_CodeTypename cast_type = gen_def_type(name(s32)); diff --git a/test/cpp_library/test.cpp b/test/cpp_library/test.cpp index 222fb0a..c06801b 100644 --- a/test/cpp_library/test.cpp +++ b/test/cpp_library/test.cpp @@ -113,10 +113,14 @@ int main() expect(option_class->Specs.ast == class_options.specifiers.ast, txt("cpp class specifiers")); expect(option_class->ModuleFlags == ModuleFlag_Export, txt("cpp class module flags")); Str class_text = strbuilder_to_str(code_to_strbuilder((Code)option_class)); - expect(str_contains(class_text, txt("ClassOption")), txt("cpp class name serialization")); - expect(str_contains(class_text, txt("ClassOptionBase")), txt("cpp class parent serialization")); - expect(str_contains(class_text, txt("IClassOption")), txt("cpp class interface serialization")); - expect(str_contains(class_text, txt("public")), txt("cpp class access serialization")); + expect(str_contains(class_text, txt("ClassOption")), txt("cpp class name serialization")); + expect(str_contains(class_text, txt("ClassOptionBase")), txt("cpp class parent serialization")); + expect(str_contains(class_text, txt("IClassOption")), txt("cpp class interface serialization")); + expect(str_contains(class_text, txt("public")), txt("cpp class access serialization")); + expect(str_contains(class_text, txt("class_option_member")), txt("cpp class body serialization")); + expect(str_contains(class_text, txt("[[maybe_unused]]")), txt("cpp class attribute serialization")); + expect(str_contains(class_text, txt("final")), txt("cpp class final specifier serialization")); + expect(str_contains(class_text, txt("export")), txt("cpp class module flag serialization")); } CodeVar struct_member = def_variable(def_type(name(u32)), name(struct_option_member)); @@ -143,10 +147,14 @@ int main() expect(option_struct->Specs.ast == struct_options.specifiers.ast, txt("cpp struct specifiers")); expect(option_struct->ModuleFlags == ModuleFlag_Export, txt("cpp struct module flags")); Str struct_text = strbuilder_to_str(code_to_strbuilder((Code)option_struct)); - expect(str_contains(struct_text, txt("StructOption")), txt("cpp struct name serialization")); - expect(str_contains(struct_text, txt("StructOptionBase")), txt("cpp struct parent serialization")); - expect(str_contains(struct_text, txt("IStructOption")), txt("cpp struct interface serialization")); - expect(str_contains(struct_text, txt("public")), txt("cpp struct access serialization")); + expect(str_contains(struct_text, txt("StructOption")), txt("cpp struct name serialization")); + expect(str_contains(struct_text, txt("StructOptionBase")), txt("cpp struct parent serialization")); + expect(str_contains(struct_text, txt("IStructOption")), txt("cpp struct interface serialization")); + expect(str_contains(struct_text, txt("public")), txt("cpp struct access serialization")); + expect(str_contains(struct_text, txt("struct_option_member")), txt("cpp struct body serialization")); + expect(str_contains(struct_text, txt("[[maybe_unused]]")), txt("cpp struct attribute serialization")); + expect(str_contains(struct_text, txt("final")), txt("cpp struct final specifier serialization")); + expect(str_contains(struct_text, txt("export")), txt("cpp struct module flag serialization")); } CodeBody enum_body = def_enum_body(args(untyped_str(txt("Option_None")))); @@ -165,10 +173,11 @@ int main() expect(option_enum->Attributes.ast == enum_options.attributes.ast, txt("cpp enum attributes")); expect(option_enum->ModuleFlags == ModuleFlag_Export, txt("cpp enum module flags")); Str enum_text = strbuilder_to_str(code_to_strbuilder((Code)option_enum)); - expect(str_contains(enum_text, txt("export")), txt("cpp enum module flag serialization")); - expect(str_contains(enum_text, txt("enum class")), txt("cpp enum specifier serialization")); - expect(str_contains(enum_text, txt("u32")), txt("cpp enum type serialization")); - expect(str_contains(enum_text, txt("Option_None")), txt("cpp enum body serialization")); + expect(str_contains(enum_text, txt("export")), txt("cpp enum module flag serialization")); + expect(str_contains(enum_text, txt("enum class")), txt("cpp enum specifier serialization")); + expect(str_contains(enum_text, txt("[[maybe_unused]]")), txt("cpp enum attribute serialization")); + expect(str_contains(enum_text, txt("u32")), txt("cpp enum type serialization")); + expect(str_contains(enum_text, txt("Option_None")), txt("cpp enum body serialization")); } Code enum_macro = untyped_str(txt("ENUM_BASE_TYPE")); CodeEnum macro_enum = def_enum(name(MacroOptionEnum), { @@ -262,8 +271,9 @@ int main() expect(option_macro != nullptr, txt("cpp define registration")); if (option_macro != nullptr) expect(option_macro->Flags == define_options.flags, txt("cpp define flags")); Str define_text = strbuilder_to_str(code_to_strbuilder((Code)option_define)); - expect(str_contains(define_text, txt("OptionMacro")), txt("cpp define name serialization")); - expect(str_contains(define_text, txt("param + 1")), txt("cpp define content serialization")); + expect(str_contains(define_text, txt("OptionMacro")), txt("cpp define name serialization")); + expect(str_contains(define_text, txt("OptionMacro( param)")), txt("cpp define parameters serialization")); + expect(str_contains(define_text, txt("param + 1")), txt("cpp define content serialization")); } Opts_def_define no_register_options = {}; no_register_options.dont_register_to_preprocess_macros = true; @@ -282,6 +292,8 @@ int main() expect(foreign_include.ast != nullptr, txt("cpp foreign include option")); if (foreign_include.ast != nullptr) { expect(str_contains(foreign_include->Content, txt("")), txt("cpp foreign include path")); + Str include_text = strbuilder_to_str(code_to_strbuilder((Code)foreign_include)); + expect(str_contains(include_text, txt("#include ")), txt("cpp foreign include directive serialization")); } CodeModule option_module = def_module(name(OptionModule), { .mflags = ModuleFlag_Export }); @@ -315,7 +327,7 @@ int main() } CodeParams function_params = def_param(def_type(name(u32)), name(function_option_arg)); - CodeTypename function_return = def_type(name(u32)); + CodeTypename function_return = def_type(name(FunctionOptionReturn)); CodeBody function_body = def_function_body(args(untyped_str(txt("return function_option_arg;")))); Opts_def_function function_options = {}; function_options.params = function_params; @@ -335,6 +347,7 @@ int main() expect(option_function->ModuleFlags == ModuleFlag_Export, txt("cpp function module flags")); Str function_text = strbuilder_to_str(code_to_strbuilder((Code)option_function)); expect(str_contains(function_text, txt("OptionFunction")), txt("cpp function name serialization")); + expect(str_contains(function_text, txt("FunctionOptionReturn OptionFunction(")), txt("cpp function return type serialization")); expect(str_contains(function_text, txt("function_option_arg")), txt("cpp function parameters serialization")); expect(str_contains(function_text, txt("return function_option_arg")), txt("cpp function body serialization")); expect(str_contains(function_text, txt("inline")), txt("cpp function specifier serialization")); @@ -361,11 +374,12 @@ int main() expect(constructor_class.ast != nullptr, txt("cpp constructor serialization parent")); if (constructor_class.ast != nullptr) { Str constructor_text = strbuilder_to_str(code_to_strbuilder((Code)constructor_class)); - expect(str_contains(constructor_text, txt("ConstructorOptions(")), txt("cpp constructor name serialization")); - expect(str_contains(constructor_text, txt("option_member( 0 )")), txt("cpp constructor initializer serialization")); - expect(str_contains(constructor_text, txt("constructor_option_arg")), txt("cpp constructor body serialization")); + expect(str_contains(constructor_text, txt("ConstructorOptions(")), txt("cpp constructor name serialization")); + expect(str_contains(constructor_text, txt("u32 constructor_option_arg")), txt("cpp constructor parameter serialization")); + expect(str_contains(constructor_text, txt("option_member( 0 )")), txt("cpp constructor initializer serialization")); + expect(str_contains(constructor_text, txt("constructor_option_arg")), txt("cpp constructor body serialization")); } - Code destructor_body = untyped_str(txt("release_option_resource();")); + Code destructor_body = untyped_str(txt("release_option_resource();")); CodeSpecifiers destructor_specs = def_specifier(Spec_Virtual); Opts_def_destructor destructor_options = {}; destructor_options.body = destructor_body; @@ -373,18 +387,27 @@ int main() CodeDestructor option_destructor = def_destructor(destructor_options); expect(option_destructor.ast != nullptr, txt("cpp destructor options")); if (option_destructor.ast != nullptr) { - expect(option_destructor->Body.ast == destructor_body.ast, txt("cpp destructor body")); + expect(option_destructor->Body.ast == destructor_body.ast, txt("cpp destructor body")); expect(option_destructor->Specs.ast == destructor_specs.ast, txt("cpp destructor specifiers")); + CodeBody destructor_class_body = def_class_body(args(option_destructor)); + CodeClass destructor_class = def_class(name(DestructorOptions), { .body = destructor_class_body }); + expect(destructor_class.ast != nullptr, txt("cpp destructor serialization parent")); + if (destructor_class.ast != nullptr) { + Str destructor_text = strbuilder_to_str(code_to_strbuilder((Code)destructor_class)); + expect(str_contains(destructor_text, txt("virtual ~DestructorOptions()")), txt("cpp destructor signature serialization")); + expect(str_contains(destructor_text, txt("release_option_resource();")), txt("cpp destructor body serialization")); + } } - CodeTypename operator_type = def_type(name(OperatorOptionType)); - CodeParams operator_lhs = def_param(operator_type, name(operator_option_lhs)); - CodeParams operator_rhs = def_param(operator_type, name(operator_option_rhs)); - CodeParams operator_params = def_params(args(operator_lhs, operator_rhs)); - CodeBody operator_body = def_function_body(args(untyped_str(txt("return operator_option_lhs;")))); + CodeTypename operator_type = def_type(name(OperatorOptionType)); + CodeTypename operator_return = def_type(name(OperatorOptionReturn)); + CodeParams operator_lhs = def_param(operator_type, name(operator_option_lhs)); + CodeParams operator_rhs = def_param(operator_type, name(operator_option_rhs)); + CodeParams operator_params = def_params(args(operator_lhs, operator_rhs)); + CodeBody operator_body = def_function_body(args(untyped_str(txt("return operator_option_lhs;")))); Opts_def_operator operator_options = {}; operator_options.params = operator_params; - operator_options.ret_type = operator_type; + operator_options.ret_type = operator_return; operator_options.body = operator_body; operator_options.specifiers = def_specifier(Spec_Inline); operator_options.attributes = def_attributes(txt("[[maybe_unused]]")); @@ -393,18 +416,22 @@ int main() expect(option_operator.ast != nullptr, txt("cpp operator options")); if (option_operator.ast != nullptr) { expect(option_operator->Params.ast == operator_params.ast, txt("cpp operator parameters")); - expect(option_operator->ReturnType.ast == operator_type.ast, txt("cpp operator return type")); + expect(option_operator->ReturnType.ast == operator_return.ast, txt("cpp operator return type")); expect(option_operator->Body.ast == operator_body.ast, txt("cpp operator body")); expect(option_operator->Specs.ast == operator_options.specifiers.ast, txt("cpp operator specifiers")); expect(option_operator->Attributes.ast == operator_options.attributes.ast, txt("cpp operator attributes")); expect(option_operator->ModuleFlags == ModuleFlag_Export, txt("cpp operator module flags")); Str operator_text = strbuilder_to_str(code_to_strbuilder((Code)option_operator)); + expect(str_contains(operator_text, txt("OperatorOptionReturn")), txt("cpp operator return type serialization")); expect(str_contains(operator_text, txt("operator +")), txt("cpp operator name serialization")); expect(str_contains(operator_text, txt("operator_option_lhs")), txt("cpp operator parameters serialization")); + expect(str_contains(operator_text, txt("operator_option_rhs")), txt("cpp operator second parameter serialization")); expect(str_contains(operator_text, txt("return operator_option_lhs")), txt("cpp operator body serialization")); expect(str_contains(operator_text, txt("inline")), txt("cpp operator specifier serialization")); expect(str_contains(operator_text, txt("[[maybe_unused]]")), txt("cpp operator attribute serialization")); expect(str_contains(operator_text, txt("export")), txt("cpp operator module flag serialization")); + if (!str_starts_with(operator_text, txt("export [[maybe_unused]] inline\nOperatorOptionReturn"))) log_fmt("%S\n", operator_text); + expect(str_starts_with(operator_text, txt("export [[maybe_unused]] inline\nOperatorOptionReturn")), txt("cpp operator one-attribute prefix serialization")); } CodeTypename cast_type = def_type(name(s32));