Re: patch adding first-class support of constructor/dispose/finalize methods
Jean-Yves Lefort <[email protected]> Tue, 29 Jan 2008 01:36:03 +0100
| Newsgroups | gmane.comp.gnome.devtools.gob.general |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. [email protected] Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg="PGP-SHA1"; boundary="Signature=_Tue__29_Jan_2008_01_36_03_+0100_L5LS2ok3Z=p.CJhZ" --Signature=_Tue__29_Jan_2008_01_36_03_+0100_L5LS2ok3Z=p.CJhZ Content-Type: multipart/mixed; boundary="Multipart=_Tue__29_Jan_2008_01_36_03_+0100_=8JoJw==qj9Mh7dJ" --Multipart=_Tue__29_Jan_2008_01_36_03_+0100_=8JoJw==qj9Mh7dJ Content-Type: text/plain; charset=US-ASCII Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, 21 Jan 2008 01:24:53 +0100 Jean-Yves Lefort <[email protected]> wrote: > The attached patch allows to write: >=20 > constructor (self) > { > /* hi */ > } >=20 > dispose (self) > { > /* hi */ > } >=20 > finalize (self) > { > /* hi */ > } >=20 > instead of: >=20 > override (G:Object) GObject * > constructor (GType type, unsigned int n_construct_properties, GObjectCon= structParam *construct_params) > { > GObject *object; > Self *self; >=20 > object =3D PARENT_HANDLER(type, n_construct_properties, construct_param= s); > self =3D SELF(object); >=20 > /* hi */ >=20 > return object; > } >=20 > override (G:Object) void > dispose (GObject *object) > { > Self *self =3D SELF(object); >=20 > /* hi */ >=20 > PARENT_HANDLER(object); > } >=20 > override (G:Object) void > finalize (GObject *object) > { > Self *self =3D SELF(object); >=20 > /* hi */ >=20 > PARENT_HANDLER(object); > } In some cases, the generated class_init function used a nonexistent g_object_class variable. I've attached a fixed patch. --=20 Jean-Yves Lefort <[email protected]> --Multipart=_Tue__29_Jan_2008_01_36_03_+0100_=8JoJw==qj9Mh7dJ Content-Type: text/x-diff; name="gob2-2.0.15-gobject-overrides.diff" Content-Disposition: attachment; filename="gob2-2.0.15-gobject-overrides.diff" Content-Transfer-Encoding: quoted-printable --- src/main.c.orig 2007-10-17 16:49:04.000000000 +0200 +++ src/main.c 2008-01-29 01:21:02.000000000 +0100 @@ -92,11 +92,16 @@ static gboolean special_array[SPECIAL_LAST] =3D {0}; static gboolean any_special =3D FALSE; =20 +static gboolean need_constructor =3D FALSE; +static Method * user_constructor =3D NULL; + static gboolean need_dispose =3D FALSE; static Method * dispose_handler =3D NULL; +static Method * user_dispose_method =3D NULL; =20 static gboolean need_finalize =3D FALSE; static Method * finalize_handler =3D NULL; +static Method * user_finalize_method =3D NULL; =20 FILE *out =3D NULL; FILE *outh =3D NULL; @@ -269,6 +274,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -291,6 +299,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -330,6 +341,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -543,7 +557,10 @@ g_free(s); } else if(m->scope =3D=3D PRIVATE_SCOPE || m->method =3D=3D INIT_METHOD || - m->method =3D=3D CLASS_INIT_METHOD) { + m->method =3D=3D CLASS_INIT_METHOD ||=20 + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD) { print_method(out, "static ", "", "", " ", "", no_gnu?";\n":" G_GNUC_UNUSED;\n", m, FALSE, FALSE, TRUE, FALSE, FALSE); @@ -629,66 +646,68 @@ } } =20 -static void -find_dispose(const Class *cl) +static Method * +find_method(const Class *cl, int method, const char *id) { GList *li; =20 - dispose_handler =3D NULL; for(li=3Dcl->nodes;li;li=3Dg_list_next(li)) { Node *n =3D li->data; if(n->type =3D=3D METHOD_NODE) { Method *m =3D (Method *)n; - if(m->method =3D=3D OVERRIDE_METHOD && - strcmp(m->id, "dispose")=3D=3D0) { - if(strcmp(m->otype, "G:Object") !=3D 0) { - error_print(GOB_ERROR, m->line_no, - "dispose method override " - "of class other then " - "G:Object"); - } - if(g_list_length(m->args) !=3D 1) { - error_print(GOB_ERROR, m->line_no, - "dispose method override " - "with more then one " - "parameter"); - } - dispose_handler =3D m; - break; - } + if (m->method =3D=3D method + && (id =3D=3D NULL || strcmp(m->id, id)=3D=3D0)) + return m; } } + + return NULL; } =20 static void -find_finalize(const Class *cl) +find_constructor(const Class *cl) { - GList *li; + user_constructor =3D find_method(cl, CONSTRUCTOR_METHOD, NULL); +} =20 - finalize_handler =3D NULL; - for(li=3Dcl->nodes;li;li=3Dg_list_next(li)) { - Node *n =3D li->data; - if(n->type =3D=3D METHOD_NODE) { - Method *m =3D (Method *)n; - if(m->method =3D=3D OVERRIDE_METHOD && - strcmp(m->id, "finalize")=3D=3D0) { - if(strcmp(m->otype, "G:Object") !=3D 0) { - error_print(GOB_ERROR, m->line_no, - "finalize method override " - "of class other then " - "G:Object"); - } - if(g_list_length(m->args) !=3D 1) { - error_print(GOB_ERROR, m->line_no, - "finalize method override " - "with more then one " - "parameter"); - } - finalize_handler =3D m; - break; - } - } +static void +find_dispose(const Class *cl) +{ + dispose_handler =3D find_method(cl, OVERRIDE_METHOD, "dispose"); + if (dispose_handler !=3D NULL) { + if(strcmp(dispose_handler->otype, "G:Object") !=3D 0) + error_print(GOB_ERROR, dispose_handler->line_no, + "dispose method override " + "of class other then " + "G:Object"); + if(g_list_length(dispose_handler->args) !=3D 1) + error_print(GOB_ERROR, dispose_handler->line_no, + "dispose method override " + "with more then one " + "parameter"); } + + user_dispose_method =3D find_method(cl, DISPOSE_METHOD, NULL); +} + +static void +find_finalize(const Class *cl) +{ + finalize_handler =3D find_method(cl, OVERRIDE_METHOD, "finalize"); + if (finalize_handler !=3D NULL) { + if(strcmp(finalize_handler->otype, "G:Object") !=3D 0) + error_print(GOB_ERROR, finalize_handler->line_no, + "finalize method override " + "of class other then " + "G:Object"); + if(g_list_length(finalize_handler->args) !=3D 1) + error_print(GOB_ERROR, finalize_handler->line_no, + "finalize method override " + "with more then one " + "parameter"); + } + + user_finalize_method =3D find_method(cl, FINALIZE_METHOD, NULL); } =20 =20 @@ -2118,6 +2137,33 @@ } =20 static void +add_constructor (Class *c) +{ + out_printf(out, "\nstatic GObject *\n" + "___constructor (GType type, guint n_construct_properties, GObjectCon= structParam *construct_properties)\n" + "{\n"); + out_printf(out, + "#define __GOB_FUNCTION__ \"%s::constructor\"\n", + c->otype); + + out_printf(out, "\tGObject *obj_self;\n"); + out_printf(out, "\t%s *self;\n", typebase); + + out_printf(out, "\tobj_self =3D G_OBJECT_CLASS (parent_class)->constructo= r (type, n_construct_properties, construct_properties);\n"); + out_printf(out, "\tself =3D %s (obj_self);\n", macrobase); + + if (user_constructor->line_no > 0) + out_addline_infile (out, user_constructor->line_no); + out_printf (out, "\t%s_constructor (self);\n", funcbase); + if (user_constructor->line_no > 0) + out_addline_outfile (out); + + out_printf(out, "\treturn obj_self;\n"); + out_printf(out, "}\n" + "#undef __GOB_FUNCTION__\n\n"); +} + +static void add_dispose (Class *c) { out_printf(out, "\nstatic void\n" @@ -2127,7 +2173,7 @@ "#define __GOB_FUNCTION__ \"%s::dispose\"\n", c->otype); =20 - if (unreftors > 0) { + if (unreftors > 0 || user_dispose_method !=3D NULL) { out_printf (out, "\t%s *self%s =3D %s (obj_self);\n", typebase, ! no_gnu ? " G_GNUC_UNUSED" : "", @@ -2143,6 +2189,14 @@ if (dispose_handler->line_no > 0) out_addline_outfile (out); } else { + if (user_dispose_method !=3D NULL) { + if (user_dispose_method->line_no > 0) + out_addline_infile (out, user_dispose_method->line_no); + out_printf (out, "\t%s_dispose (self);\n", funcbase); + if (user_dispose_method->line_no > 0) + out_addline_outfile (out); + } + out_printf (out, "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n" "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n"); @@ -2178,7 +2232,8 @@ c->otype); =20 if (privates > 0 || - destructors > 0) { + destructors > 0 || + user_finalize_method !=3D NULL) { const char *unused =3D ""; if ( ! no_gnu) unused =3D " G_GNUC_UNUSED"; @@ -2202,6 +2257,14 @@ if(finalize_handler->line_no > 0) out_addline_outfile(out); } else { + if (user_finalize_method !=3D NULL) { + if (user_finalize_method->line_no > 0) + out_addline_infile (out, user_finalize_method->line_no); + out_printf (out, "\t%s_finalize (self);\n", funcbase); + if (user_finalize_method->line_no > 0) + out_addline_outfile (out); + } + out_printf(out, "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n" "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"); @@ -2333,6 +2396,7 @@ if (set_properties > 0 || get_properties > 0 || signals > 0 || + need_constructor || need_dispose || need_finalize) { out_printf(out, @@ -2381,6 +2445,9 @@ =20 /* if there are no handlers for these things, we * need to set them up here */ + if(need_constructor) + out_printf(out, "\tg_object_class->constructor " + "=3D ___constructor;\n"); if(need_dispose && !dispose_handler) out_printf(out, "\tg_object_class->dispose " "=3D ___dispose;\n"); @@ -3064,6 +3131,15 @@ /* the outfile line was added above */ out_printf(out, "#undef PARENT_HANDLER\n"); break; + case CONSTRUCTOR_METHOD: + case DISPOSE_METHOD: + case FINALIZE_METHOD: + if(m->line_no > 0) + out_addline_infile(out, m->line_no); + print_method(out, "static ", "\n", "", " ", "", "\n", + m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method_body(m, TRUE, TRUE); + /* the outfile line was added above */ default: break; } @@ -3633,6 +3709,9 @@ funcbase); } =20 + if (need_constructor) + add_constructor (c); + if (need_dispose) add_dispose (c); =20 @@ -4441,15 +4520,24 @@ =20 make_bases (); make_inits ((Class *)class); - if(unreftors > 0) { + + find_constructor ((Class *)class); + if (user_constructor !=3D NULL) + need_constructor =3D TRUE; + + find_dispose ((Class *)class); + if (unreftors > 0 || + dispose_handler !=3D NULL || + user_dispose_method !=3D NULL) need_dispose =3D TRUE; - find_dispose ((Class *)class); - } + + find_finalize ((Class *)class); if (destructors > 0 || - privates > 0) { + privates > 0 || + user_finalize_method !=3D NULL) { need_finalize =3D TRUE; - find_finalize ((Class *)class); } + check_bad_symbols ((Class *)class); check_duplicate_symbols ((Class *)class); check_duplicate_overrides ((Class *)class); --- src/parse.y.orig 2007-03-09 18:46:14.000000000 +0100 +++ src/parse.y 2008-01-29 01:19:59.000000000 +0100 @@ -155,7 +155,11 @@ =20 g_assert(scope !=3D CLASS_SCOPE); =20 - if(method =3D=3D INIT_METHOD || method =3D=3D CLASS_INIT_METHOD) { + if(method =3D=3D INIT_METHOD + || method =3D=3D CLASS_INIT_METHOD + || method =3D=3D CONSTRUCTOR_METHOD + || method =3D=3D DISPOSE_METHOD + || method =3D=3D FINALIZE_METHOD) { type =3D (Type *)node_new (TYPE_NODE, "name", "void", NULL); @@ -1767,13 +1771,29 @@ push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL, $<id>1, $<cbuf>5, $<line>2, ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "constructor")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, CONSTRUCTOR_METHOD, NULL, + $<id>1, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "dispose")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, DISPOSE_METHOD, NULL, + $<id>1, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "finalize")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, FINALIZE_METHOD, NULL, + $<id>1, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); } else { g_free($<id>1); g_free($<id>3); g_string_free($<cbuf>5,TRUE); yyerror(_("parse error " - "(untyped blocks must be init or " - "class_init)")); + "(untyped blocks must be init, " + "class_init, constructor, dispose " + "or finalize)")); YYERROR; } } --- src/treefuncs.def.orig 2007-03-09 18:46:14.000000000 +0100 +++ src/treefuncs.def 2008-01-29 01:19:59.000000000 +0100 @@ -40,6 +40,9 @@ REGULAR_METHOD, INIT_METHOD, CLASS_INIT_METHOD, + CONSTRUCTOR_METHOD, + DISPOSE_METHOD, + FINALIZE_METHOD, VIRTUAL_METHOD, SIGNAL_LAST_METHOD, SIGNAL_FIRST_METHOD, --Multipart=_Tue__29_Jan_2008_01_36_03_+0100_=8JoJw==qj9Mh7dJ-- --Signature=_Tue__29_Jan_2008_01_36_03_+0100_L5LS2ok3Z=p.CJhZ Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFHnnTzyzD7UaO4AGoRAvQGAJwLIfhZeyBR7tB2WBLN24wWa0XgFgCeOE+u mTpW6tVGXfaVSiQ/jmWXgDM= =73hS -----END PGP SIGNATURE----- --Signature=_Tue__29_Jan_2008_01_36_03_+0100_L5LS2ok3Z=p.CJhZ-- [email protected] Content-Type: text/plain; charset=us-ascii; name="footer.txt" Content-Disposition: inline Content-Transfer-Encoding: 8bit -- to unsubscribe: send mail to [email protected] with "unsubscribe gob-list" in the subject [email protected]