patch adding first-class support of constructor/dispose/finalize methods

View: New views
2 Messages — Rating Filter:   Alert me  

patch adding first-class support of constructor/dispose/finalize methods

by Jean-Yves Lefort :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The attached patch allows to write:

        constructor (self)
        {
                /* hi */
        }

        dispose (self)
        {
                /* hi */
        }

        finalize (self)
        {
                /* hi */
        }

instead of:

        override (G:Object) GObject *
        constructor (GType type, unsigned int n_construct_properties, GObjectConstructParam *construct_params)
        {
                GObject *object;
                Self *self;

                object = PARENT_HANDLER(type, n_construct_properties, construct_params);
                self = SELF(object);

                /* hi */

                return object;
        }

        override (G:Object) void
        dispose (GObject *object)
        {
                Self *self = SELF(object);

                /* hi */

                PARENT_HANDLER(object);
        }

        override (G:Object) void
        finalize (GObject *object)
        {
                Self *self = SELF(object);

                /* hi */

                PARENT_HANDLER(object);
        }

In my opinion, these virtual methods are used so often that they
deserve such first-class support.

Of course, to preserve backwards compatibility, the normal override
syntax is still supported.

--
Jean-Yves Lefort <jylefort@...>

[gob2-2.0.15-gobject-overrides.diff]

--- src/main.c.orig 2007-10-17 16:49:04.000000000 +0200
+++ src/main.c 2008-01-21 00:53:57.000000000 +0100
@@ -92,11 +92,16 @@
 static gboolean special_array[SPECIAL_LAST] = {0};
 static gboolean any_special = FALSE;
 
+static gboolean need_constructor = FALSE;
+static Method * user_constructor = NULL;
+
 static gboolean need_dispose = FALSE;
 static Method * dispose_handler = NULL;
+static Method * user_dispose_method = NULL;
 
 static gboolean need_finalize = FALSE;
 static Method * finalize_handler = NULL;
+static Method * user_finalize_method = NULL;
 
 FILE *out = NULL;
 FILE *outh = NULL;
@@ -269,6 +274,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -291,6 +299,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -330,6 +341,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -543,7 +557,10 @@
  g_free(s);
  } else if(m->scope == PRIVATE_SCOPE ||
   m->method == INIT_METHOD ||
-  m->method == CLASS_INIT_METHOD) {
+  m->method == CLASS_INIT_METHOD ||
+  m->method == CONSTRUCTOR_METHOD ||
+  m->method == DISPOSE_METHOD ||
+  m->method == FINALIZE_METHOD) {
  print_method(out, "static ", "", "", " ", "",
      no_gnu?";\n":" G_GNUC_UNUSED;\n",
      m, FALSE, FALSE, TRUE, FALSE, FALSE);
@@ -629,66 +646,68 @@
  }
 }
 
-static void
-find_dispose(const Class *cl)
+static Method *
+find_method(const Class *cl, int method, const char *id)
 {
  GList *li;
 
- dispose_handler = NULL;
  for(li=cl->nodes;li;li=g_list_next(li)) {
  Node *n = li->data;
  if(n->type == METHOD_NODE) {
  Method *m = (Method *)n;
- if(m->method == OVERRIDE_METHOD &&
-   strcmp(m->id, "dispose")==0) {
- if(strcmp(m->otype, "G:Object") != 0) {
- error_print(GOB_ERROR, m->line_no,
-    "dispose method override "
-    "of class other then "
-    "G:Object");
- }
- if(g_list_length(m->args) != 1) {
- error_print(GOB_ERROR, m->line_no,
-    "dispose method override "
-    "with more then one "
-    "parameter");
- }
- dispose_handler = m;
- break;
- }
+ if (m->method == method
+    && (id == NULL || strcmp(m->id, id)==0))
+ return m;
  }
  }
+
+ return NULL;
 }
 
 static void
-find_finalize(const Class *cl)
+find_constructor(const Class *cl)
 {
- GList *li;
+ user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
+}
 
- finalize_handler = NULL;
- for(li=cl->nodes;li;li=g_list_next(li)) {
- Node *n = li->data;
- if(n->type == METHOD_NODE) {
- Method *m = (Method *)n;
- if(m->method == OVERRIDE_METHOD &&
-   strcmp(m->id, "finalize")==0) {
- if(strcmp(m->otype, "G:Object") != 0) {
- error_print(GOB_ERROR, m->line_no,
-    "finalize method override "
-    "of class other then "
-    "G:Object");
- }
- if(g_list_length(m->args) != 1) {
- error_print(GOB_ERROR, m->line_no,
-    "finalize method override "
-    "with more then one "
-    "parameter");
- }
- finalize_handler = m;
- break;
- }
- }
+static void
+find_dispose(const Class *cl)
+{
+ dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
+ if (dispose_handler != NULL) {
+ if(strcmp(dispose_handler->otype, "G:Object") != 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) != 1)
+ error_print(GOB_ERROR, dispose_handler->line_no,
+    "dispose method override "
+    "with more then one "
+    "parameter");
  }
+
+ user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
+}
+
+static void
+find_finalize(const Class *cl)
+{
+ finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
+ if (finalize_handler != NULL) {
+ if(strcmp(finalize_handler->otype, "G:Object") != 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) != 1)
+ error_print(GOB_ERROR, finalize_handler->line_no,
+    "finalize method override "
+    "with more then one "
+    "parameter");
+ }
+
+ user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
 }
 
 
@@ -2118,6 +2137,33 @@
 }
 
 static void
+add_constructor (Class *c)
+{
+ out_printf(out, "\nstatic GObject *\n"
+   "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *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 = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
+ out_printf(out, "\tself = %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);
 
- if (unreftors > 0) {
+ if (unreftors > 0 || user_dispose_method != NULL) {
  out_printf (out, "\t%s *self%s = %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 != 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);
 
  if (privates > 0 ||
-    destructors > 0) {
+    destructors > 0 ||
+    user_finalize_method != NULL) {
  const char *unused = "";
  if ( ! no_gnu)
  unused = " G_GNUC_UNUSED";
@@ -2202,6 +2257,14 @@
  if(finalize_handler->line_no > 0)
  out_addline_outfile(out);
  } else {
+ if (user_finalize_method != 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");
@@ -2381,6 +2444,9 @@
 
  /* 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 "
+   "= ___constructor;\n");
  if(need_dispose && !dispose_handler)
  out_printf(out, "\tg_object_class->dispose "
    "= ___dispose;\n");
@@ -3064,6 +3130,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 +3708,9 @@
     funcbase);
  }
 
+ if (need_constructor)
+ add_constructor (c);
+
  if (need_dispose)
  add_dispose (c);
 
@@ -4441,15 +4519,24 @@
 
  make_bases ();
  make_inits ((Class *)class);
- if(unreftors > 0) {
+
+ find_constructor ((Class *)class);
+ if (user_constructor != NULL)
+ need_constructor = TRUE;
+
+ find_dispose ((Class *)class);
+ if (unreftors > 0 ||
+    dispose_handler != NULL ||
+    user_dispose_method != NULL)
  need_dispose = TRUE;
- find_dispose ((Class *)class);
- }
+
+ find_finalize ((Class *)class);
  if (destructors > 0 ||
-    privates > 0) {
+    privates > 0 ||
+    user_finalize_method != NULL) {
  need_finalize = 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-21 00:53:13.000000000 +0100
@@ -155,7 +155,11 @@
 
  g_assert(scope != CLASS_SCOPE);
       
- if(method == INIT_METHOD || method == CLASS_INIT_METHOD) {
+ if(method == INIT_METHOD
+   || method == CLASS_INIT_METHOD
+   || method == CONSTRUCTOR_METHOD
+   || method == DISPOSE_METHOD
+   || method == FINALIZE_METHOD) {
  type = (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")==0) {
+ 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")==0) {
+ 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")==0) {
+ 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-21 00:53:13.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,



--
to unsubscribe:
send mail to minimalist@... with "unsubscribe gob-list" in the subject

attachment0 (196 bytes) Download Attachment

Re: patch adding first-class support of constructor/dispose/finalize methods

by Jean-Yves Lefort :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 21 Jan 2008 01:24:53 +0100
Jean-Yves Lefort <jylefort@...> wrote:

> The attached patch allows to write:
>
> constructor (self)
> {
> /* hi */
> }
>
> dispose (self)
> {
> /* hi */
> }
>
> finalize (self)
> {
> /* hi */
> }
>
> instead of:
>
> override (G:Object) GObject *
> constructor (GType type, unsigned int n_construct_properties, GObjectConstructParam *construct_params)
> {
> GObject *object;
> Self *self;
>
> object = PARENT_HANDLER(type, n_construct_properties, construct_params);
> self = SELF(object);
>
> /* hi */
>
> return object;
> }
>
> override (G:Object) void
> dispose (GObject *object)
> {
> Self *self = SELF(object);
>
> /* hi */
>
> PARENT_HANDLER(object);
> }
>
> override (G:Object) void
> finalize (GObject *object)
> {
> Self *self = SELF(object);
>
> /* hi */
>
> PARENT_HANDLER(object);
> }
In some cases, the generated class_init function used a nonexistent
g_object_class variable. I've attached a fixed patch.

--
Jean-Yves Lefort <jylefort@...>

[gob2-2.0.15-gobject-overrides.diff]

--- 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] = {0};
 static gboolean any_special = FALSE;
 
+static gboolean need_constructor = FALSE;
+static Method * user_constructor = NULL;
+
 static gboolean need_dispose = FALSE;
 static Method * dispose_handler = NULL;
+static Method * user_dispose_method = NULL;
 
 static gboolean need_finalize = FALSE;
 static Method * finalize_handler = NULL;
+static Method * user_finalize_method = NULL;
 
 FILE *out = NULL;
 FILE *outh = NULL;
@@ -269,6 +274,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -291,6 +299,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -330,6 +341,9 @@
 
  if(m->method == INIT_METHOD ||
    m->method == CLASS_INIT_METHOD ||
+   m->method == CONSTRUCTOR_METHOD ||
+   m->method == DISPOSE_METHOD ||
+   m->method == FINALIZE_METHOD ||
    m->method == OVERRIDE_METHOD)
  continue;
 
@@ -543,7 +557,10 @@
  g_free(s);
  } else if(m->scope == PRIVATE_SCOPE ||
   m->method == INIT_METHOD ||
-  m->method == CLASS_INIT_METHOD) {
+  m->method == CLASS_INIT_METHOD ||
+  m->method == CONSTRUCTOR_METHOD ||
+  m->method == DISPOSE_METHOD ||
+  m->method == FINALIZE_METHOD) {
  print_method(out, "static ", "", "", " ", "",
      no_gnu?";\n":" G_GNUC_UNUSED;\n",
      m, FALSE, FALSE, TRUE, FALSE, FALSE);
@@ -629,66 +646,68 @@
  }
 }
 
-static void
-find_dispose(const Class *cl)
+static Method *
+find_method(const Class *cl, int method, const char *id)
 {
  GList *li;
 
- dispose_handler = NULL;
  for(li=cl->nodes;li;li=g_list_next(li)) {
  Node *n = li->data;
  if(n->type == METHOD_NODE) {
  Method *m = (Method *)n;
- if(m->method == OVERRIDE_METHOD &&
-   strcmp(m->id, "dispose")==0) {
- if(strcmp(m->otype, "G:Object") != 0) {
- error_print(GOB_ERROR, m->line_no,
-    "dispose method override "
-    "of class other then "
-    "G:Object");
- }
- if(g_list_length(m->args) != 1) {
- error_print(GOB_ERROR, m->line_no,
-    "dispose method override "
-    "with more then one "
-    "parameter");
- }
- dispose_handler = m;
- break;
- }
+ if (m->method == method
+    && (id == NULL || strcmp(m->id, id)==0))
+ return m;
  }
  }
+
+ return NULL;
 }
 
 static void
-find_finalize(const Class *cl)
+find_constructor(const Class *cl)
 {
- GList *li;
+ user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
+}
 
- finalize_handler = NULL;
- for(li=cl->nodes;li;li=g_list_next(li)) {
- Node *n = li->data;
- if(n->type == METHOD_NODE) {
- Method *m = (Method *)n;
- if(m->method == OVERRIDE_METHOD &&
-   strcmp(m->id, "finalize")==0) {
- if(strcmp(m->otype, "G:Object") != 0) {
- error_print(GOB_ERROR, m->line_no,
-    "finalize method override "
-    "of class other then "
-    "G:Object");
- }
- if(g_list_length(m->args) != 1) {
- error_print(GOB_ERROR, m->line_no,
-    "finalize method override "
-    "with more then one "
-    "parameter");
- }
- finalize_handler = m;
- break;
- }
- }
+static void
+find_dispose(const Class *cl)
+{
+ dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
+ if (dispose_handler != NULL) {
+ if(strcmp(dispose_handler->otype, "G:Object") != 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) != 1)
+ error_print(GOB_ERROR, dispose_handler->line_no,
+    "dispose method override "
+    "with more then one "
+    "parameter");
  }
+
+ user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
+}
+
+static void
+find_finalize(const Class *cl)
+{
+ finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
+ if (finalize_handler != NULL) {
+ if(strcmp(finalize_handler->otype, "G:Object") != 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) != 1)
+ error_print(GOB_ERROR, finalize_handler->line_no,
+    "finalize method override "
+    "with more then one "
+    "parameter");
+ }
+
+ user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
 }
 
 
@@ -2118,6 +2137,33 @@
 }
 
 static void
+add_constructor (Class *c)
+{
+ out_printf(out, "\nstatic GObject *\n"
+   "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *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 = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
+ out_printf(out, "\tself = %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);
 
- if (unreftors > 0) {
+ if (unreftors > 0 || user_dispose_method != NULL) {
  out_printf (out, "\t%s *self%s = %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 != 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);
 
  if (privates > 0 ||
-    destructors > 0) {
+    destructors > 0 ||
+    user_finalize_method != NULL) {
  const char *unused = "";
  if ( ! no_gnu)
  unused = " G_GNUC_UNUSED";
@@ -2202,6 +2257,14 @@
  if(finalize_handler->line_no > 0)
  out_addline_outfile(out);
  } else {
+ if (user_finalize_method != 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 @@
 
  /* 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 "
+   "= ___constructor;\n");
  if(need_dispose && !dispose_handler)
  out_printf(out, "\tg_object_class->dispose "
    "= ___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);
  }
 
+ if (need_constructor)
+ add_constructor (c);
+
  if (need_dispose)
  add_dispose (c);
 
@@ -4441,15 +4520,24 @@
 
  make_bases ();
  make_inits ((Class *)class);
- if(unreftors > 0) {
+
+ find_constructor ((Class *)class);
+ if (user_constructor != NULL)
+ need_constructor = TRUE;
+
+ find_dispose ((Class *)class);
+ if (unreftors > 0 ||
+    dispose_handler != NULL ||
+    user_dispose_method != NULL)
  need_dispose = TRUE;
- find_dispose ((Class *)class);
- }
+
+ find_finalize ((Class *)class);
  if (destructors > 0 ||
-    privates > 0) {
+    privates > 0 ||
+    user_finalize_method != NULL) {
  need_finalize = 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 @@
 
  g_assert(scope != CLASS_SCOPE);
       
- if(method == INIT_METHOD || method == CLASS_INIT_METHOD) {
+ if(method == INIT_METHOD
+   || method == CLASS_INIT_METHOD
+   || method == CONSTRUCTOR_METHOD
+   || method == DISPOSE_METHOD
+   || method == FINALIZE_METHOD) {
  type = (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")==0) {
+ 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")==0) {
+ 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")==0) {
+ 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,



--
to unsubscribe:
send mail to minimalist@... with "unsubscribe gob-list" in the subject

attachment0 (196 bytes) Download Attachment