add support for static constructors, fixes bug 506985
authorJuerg Billeter <j@bitron.ch>
Sat, 29 Mar 2008 12:04:37 +0000 (12:04 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 29 Mar 2008 12:04:37 +0000 (12:04 +0000)
2008-03-29  Juerg Billeter  <j@bitron.ch>

* vala/parser.y, vala/valaclass.vala, vala/valaconstructor.vala,
  gobject/valaccodegenerator.vala: add support for static
  constructors, fixes bug 506985

svn path=/trunk/; revision=1162

ChangeLog
gobject/valaccodegenerator.vala
vala/parser.y
vala/valaclass.vala
vala/valaconstructor.vala

index 19b90ca..b204817 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-03-29  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y, vala/valaclass.vala, vala/valaconstructor.vala,
+         gobject/valaccodegenerator.vala: add support for static
+         constructors, fixes bug 506985
+
 2008-03-24  Jürg Billeter  <j@bitron.ch>
 
        * vapi/packages/gdk-2.0/: add GDK_SELECTION_* bindings
index f01ff1d..80a190f 100644 (file)
@@ -903,78 +903,84 @@ public class Vala.CCodeGenerator : CodeGenerator {
                in_constructor = false;
 
                var cl = (Class) c.parent_symbol;
-       
-               function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
-               function.modifiers = CCodeModifiers.STATIC;
+
+               if (c.instance) {
+                       function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
+                       function.modifiers = CCodeModifiers.STATIC;
                
-               function.add_parameter (new CCodeFormalParameter ("type", "GType"));
-               function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
-               function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
+                       function.add_parameter (new CCodeFormalParameter ("type", "GType"));
+                       function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
+                       function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
                
-               source_type_member_declaration.append (function.copy ());
+                       source_type_member_declaration.append (function.copy ());
 
 
-               var cblock = new CCodeBlock ();
-               var cdecl = new CCodeDeclaration ("GObject *");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
-               cblock.add_statement (cdecl);
+                       var cblock = new CCodeBlock ();
+                       var cdecl = new CCodeDeclaration ("GObject *");
+                       cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
+                       cblock.add_statement (cdecl);
 
-               cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
-               cblock.add_statement (cdecl);
+                       cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
+                       cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
+                       cblock.add_statement (cdecl);
 
-               cdecl = new CCodeDeclaration ("GObjectClass *");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
-               cblock.add_statement (cdecl);
+                       cdecl = new CCodeDeclaration ("GObjectClass *");
+                       cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
+                       cblock.add_statement (cdecl);
 
 
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
-               ccall.add_argument (new CCodeIdentifier (cl.get_upper_case_cname ("TYPE_")));
-               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
-               ccast.add_argument (ccall);
-               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
+                       ccall.add_argument (new CCodeIdentifier (cl.get_upper_case_cname ("TYPE_")));
+                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
+                       ccast.add_argument (ccall);
+                       cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
 
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-               ccall.add_argument (new CCodeIdentifier ("klass"));
-               ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-               ccast.add_argument (ccall);
-               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
+                       ccall.add_argument (new CCodeIdentifier ("klass"));
+                       ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
+                       ccast.add_argument (ccall);
+                       cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
 
                
-               ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
-               ccall.add_argument (new CCodeIdentifier ("type"));
-               ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
-               ccall.add_argument (new CCodeIdentifier ("construct_properties"));
-               cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
+                       ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
+                       ccall.add_argument (new CCodeIdentifier ("type"));
+                       ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
+                       ccall.add_argument (new CCodeIdentifier ("construct_properties"));
+                       cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
 
 
-               ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
+                       ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
 
-               cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+                       cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
+                       cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
                
-               cblock.add_statement (cdecl);
-
-               if (current_method_inner_error) {
-                       /* always separate error parameter and inner_error local variable
-                        * as error may be set to NULL but we're always interested in inner errors
-                        */
-                       var cdecl = new CCodeDeclaration ("GError *");
-                       cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
                        cblock.add_statement (cdecl);
-               }
+
+                       if (current_method_inner_error) {
+                               /* always separate error parameter and inner_error local variable
+                                * as error may be set to NULL but we're always interested in inner errors
+                                */
+                               var cdecl = new CCodeDeclaration ("GError *");
+                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
+                               cblock.add_statement (cdecl);
+                       }
 
 
-               cblock.add_statement (c.body.ccodenode);
+                       cblock.add_statement (c.body.ccodenode);
                
-               cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
+                       cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
                
-               function.block = cblock;
+                       function.block = cblock;
 
-               if (c.source_reference.comment != null) {
-                       source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
+                       if (c.source_reference.comment != null) {
+                               source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
+                       }
+                       source_type_member_definition.append (function);
+               } else {
+                       // static class constructor
+                       // add to class_init
+                       class_init_fragment.append (c.body.ccodenode);
                }
-               source_type_member_definition.append (function);
        }
 
        public override void visit_destructor (Destructor! d) {
index 9afa0ac..bb893e6 100644 (file)
@@ -2955,7 +2955,11 @@ class_member_declaration
          {
                /* skip declarations with errors */
                if ($1 != NULL) {
-                       vala_class_set_constructor (VALA_CLASS (symbol_stack->data), $1);
+                       if (vala_constructor_get_instance ($1)) {
+                               vala_class_set_constructor (VALA_CLASS (symbol_stack->data), $1);
+                       } else {
+                               vala_class_set_static_constructor (VALA_CLASS (symbol_stack->data), $1);
+                       }
                        g_object_unref ($1);
                }
          }
@@ -3662,13 +3666,17 @@ signal_declaration
        ;
 
 constructor_declaration
-       : comment opt_attributes CONSTRUCT block
+       : comment opt_attributes opt_access_modifier opt_modifiers CONSTRUCT block
          {
-               ValaSourceReference *src = src_com(@3, $1);
+               ValaSourceReference *src = src_com(@5, $1);
                $$ = vala_code_context_create_constructor (context, src);
                g_object_unref (src);
-               vala_constructor_set_body ($$, $4);
-               g_object_unref ($4);
+               vala_constructor_set_body ($$, $6);
+               g_object_unref ($6);
+
+               if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
+                       vala_constructor_set_instance ($$, FALSE);
+               }
          }
        ;
 
index 8e0eacc..f760ebe 100644 (file)
@@ -47,11 +47,7 @@ public class Vala.Class : Typesymbol {
        /**
         * Specifies whether this class has private fields.
         */
-       public bool has_private_fields {
-               get {
-                       return _has_private_fields;
-               }
-       }
+       public bool has_private_fields { get; private set; }
 
        private string cname;
        private string const_cname;
@@ -67,8 +63,6 @@ public class Vala.Class : Typesymbol {
        private string get_value_function;
        private string set_value_function;
 
-       private bool _has_private_fields;
-       
        private Gee.List<TypeParameter> type_parameters = new ArrayList<TypeParameter> ();
 
        private Gee.List<DataType> base_types = new ArrayList<DataType> ();
@@ -94,7 +88,12 @@ public class Vala.Class : Typesymbol {
         * Specifies the instance constructor.
         */
        public Constructor constructor { get; set; }
-       
+
+       /**
+        * Specifies the static class constructor.
+        */
+       public Constructor static_constructor { get; set; }
+
        /**
         * Specifies the instance destructor.
         */
@@ -173,7 +172,7 @@ public class Vala.Class : Typesymbol {
        public void add_field (Field! f) {
                fields.add (f);
                if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
-                       _has_private_fields = true;
+                       has_private_fields = true;
                }
                scope.add (f.name, f);
        }
@@ -374,6 +373,10 @@ public class Vala.Class : Typesymbol {
                        constructor.accept (visitor);
                }
 
+               if (static_constructor != null) {
+                       static_constructor.accept (visitor);
+               }
+
                if (destructor != null) {
                        destructor.accept (visitor);
                }
index b0ab688..1627175 100644 (file)
@@ -1,6 +1,6 @@
 /* valaconstructor.vala
  *
- * Copyright (C) 2006-2007  Jürg Billeter
+ * Copyright (C) 2006-2008  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -35,20 +35,11 @@ public class Vala.Constructor : Symbol {
         * Specifies the generated `this' parameter for instance methods.
         */
        public FormalParameter this_parameter { get; set; }
-       
-       private bool _instance = true;
-       
+
        /**
         * Specifies whether this is an instance or a class constructor.
         */
-       public bool instance {
-               get {
-                       return _instance;
-               }
-               set {
-                       _instance = value;
-               }
-       }
+       public bool instance { get; set; default (true); }
        
        /**
         * Creates a new constructor.