static void S_run_overridden_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*"); CFCParamList *param_list = CFCTest_parse_param_list(test, parser, "(Foo *self)"); CFCMethod *orig = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, param_list, NULL, 0, 0); CFCParamList *overrider_param_list = CFCTest_parse_param_list(test, parser, "(FooJr *self)"); CFCMethod *overrider = CFCMethod_new(neato_parcel, NULL, "Neato::Foo::FooJr", "FooJr", "Return_An_Obj", return_type, overrider_param_list, NULL, 0, 0); CFCMethod_override(overrider, orig); OK(test, !CFCMethod_novel(overrider), "A Method which overrides another is not 'novel'"); CFCBase_decref((CFCBase*)parser); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)return_type); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)orig); CFCBase_decref((CFCBase*)overrider_param_list); CFCBase_decref((CFCBase*)overrider); CFCParcel_reap_singletons(); }
CFCMethod* CFCMethod_finalize(CFCMethod *self) { CFCParcel *parcel = CFCMethod_get_parcel(self); const char *exposure = CFCMethod_get_exposure(self); const char *class_name = CFCMethod_get_class_name(self); const char *class_cnick = CFCMethod_get_class_cnick(self); CFCMethod *finalized = CFCMethod_new(parcel, exposure, class_name, class_cnick, self->macro_sym, self->function.return_type, self->function.param_list, self->function.docucomment, true, self->is_abstract); finalized->is_novel = self->is_novel; return finalized; }
static CFCMethod* S_make_method_obj(CFCClass *klass, const char *method_name) { const char *klass_full_struct_sym = CFCClass_full_struct_sym(klass); const char *klass_name = CFCClass_get_class_name(klass); const char *klass_cnick = CFCClass_get_cnick(klass); CFCParcel *klass_parcel = CFCClass_get_parcel(klass); CFCType *return_type = CFCType_new_object(CFCTYPE_INCREMENTED, klass_parcel, "cfish_Obj", 1); CFCType *self_type = CFCType_new_object(0, klass_parcel, klass_full_struct_sym, 1); CFCVariable *self_var = CFCVariable_new(NULL, NULL, NULL, NULL, "self", self_type, false); CFCParamList *param_list = NULL; if (strcmp(method_name, "Dump") == 0) { param_list = CFCParamList_new(false); CFCParamList_add_param(param_list, self_var, NULL); } else if (strcmp(method_name, "Load") == 0) { CFCType *dump_type = CFCType_new_object(0, klass_parcel, "cfish_Obj", 1); CFCVariable *dump_var = CFCVariable_new(NULL, NULL, NULL, NULL, "dump", dump_type, false); param_list = CFCParamList_new(false); CFCParamList_add_param(param_list, self_var, NULL); CFCParamList_add_param(param_list, dump_var, NULL); CFCBase_decref((CFCBase*)dump_var); CFCBase_decref((CFCBase*)dump_type); } else { CFCUtil_die("Unexpected method_name: '%s'", method_name); } CFCMethod *method = CFCMethod_new(klass_parcel, "public", klass_name, klass_cnick, method_name, return_type, param_list, NULL, false, false); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)self_type); CFCBase_decref((CFCBase*)self_var); CFCBase_decref((CFCBase*)return_type); return method; }
static void S_run_final_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCClass *obj_class = CFCTest_parse_class(test, parser, "class Obj {}"); CFCClass *foo_class = CFCTest_parse_class(test, parser, "class Neato::Foo {}"); CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*"); CFCParamList *param_list = CFCTest_parse_param_list(test, parser, "(Foo *self)"); CFCMethod *not_final = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, param_list, NULL, 0, 0); CFCMethod_resolve_types(not_final); CFCMethod *final = CFCMethod_finalize(not_final); OK(test, CFCMethod_compatible(not_final, final), "finalize clones properly"); OK(test, !CFCMethod_final(not_final), "not final by default"); OK(test, CFCMethod_final(final), "finalize"); CFCBase_decref((CFCBase*)parser); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)obj_class); CFCBase_decref((CFCBase*)foo_class); CFCBase_decref((CFCBase*)return_type); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)not_final); CFCBase_decref((CFCBase*)final); CFCClass_clear_registry(); CFCParcel_reap_singletons(); }
static void S_run_basic_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*"); CFCParamList *param_list = CFCTest_parse_param_list(test, parser, "(Foo *self, int32_t count = 0)"); CFCMethod *method = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, param_list, NULL, 0, 0); OK(test, method != NULL, "new"); OK(test, CFCSymbol_parcel((CFCSymbol*)method), "parcel exposure by default"); { CFCMethod *dupe = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, param_list, NULL, 0, 0); OK(test, CFCMethod_compatible(method, dupe), "compatible"); CFCBase_decref((CFCBase*)dupe); } { CFCMethod *macro_sym_differs = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Eat", return_type, param_list, NULL, 0, 0); OK(test, !CFCMethod_compatible(method, macro_sym_differs), "different macro_sym spoils compatible"); OK(test, !CFCMethod_compatible(macro_sym_differs, method), "... reversed"); CFCBase_decref((CFCBase*)macro_sym_differs); } { static const char *param_strings[5] = { "(Foo *self, int32_t count = 0, int b)", "(Foo *self, int32_t count = 1)", "(Foo *self, int32_t count)", "(Foo *self, int32_t countess = 0)", "(Foo *self, uint32_t count = 0)" }; static const char *test_names[5] = { "extra param", "different initial_value", "missing initial_value", "different param name", "different param type" }; for (int i = 0; i < 5; ++i) { CFCParamList *other_param_list = CFCTest_parse_param_list(test, parser, param_strings[i]); CFCMethod *other = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, other_param_list, NULL, 0, 0); OK(test, !CFCMethod_compatible(method, other), "%s spoils compatible", test_names[i]); OK(test, !CFCMethod_compatible(other, method), "... reversed"); CFCBase_decref((CFCBase*)other_param_list); CFCBase_decref((CFCBase*)other); } } { CFCParamList *self_differs_list = CFCTest_parse_param_list(test, parser, "(Bar *self, int32_t count = 0)"); CFCMethod *self_differs = CFCMethod_new(neato_parcel, NULL, "Neato::Bar", "Bar", "Return_An_Obj", return_type, self_differs_list, NULL, 0, 0); OK(test, CFCMethod_compatible(method, self_differs), "different self type still compatible()," " since can't test inheritance"); OK(test, CFCMethod_compatible(self_differs, method), "... reversed"); CFCBase_decref((CFCBase*)self_differs_list); CFCBase_decref((CFCBase*)self_differs); } { CFCMethod *aliased = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Aliased", return_type, param_list, NULL, 0, 0); OK(test, !CFCMethod_get_host_alias(aliased), "no host alias by default"); CFCMethod_set_host_alias(aliased, "Host_Alias"); STR_EQ(test, CFCMethod_get_host_alias(aliased), "Host_Alias", "set/get host alias"); CFCBase_decref((CFCBase*)aliased); } { CFCMethod *excluded = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Excluded", return_type, param_list, NULL, 0, 0); OK(test, !CFCMethod_excluded_from_host(excluded), "not excluded by default"); CFCMethod_exclude_from_host(excluded); OK(test, CFCMethod_excluded_from_host(excluded), "exclude from host"); CFCBase_decref((CFCBase*)excluded); } CFCBase_decref((CFCBase*)parser); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)return_type); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)method); CFCParcel_reap_singletons(); }