Initialize class fields in class init function
authorJared Moore <jaredm@svn.gnome.org>
Sat, 21 Jun 2008 14:34:56 +0000 (14:34 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 21 Jun 2008 14:34:56 +0000 (14:34 +0000)
2008-06-21  Jared Moore  <jaredm@svn.gnome.org>

* gobject/valaccodeclassbinding.vala:

Initialize class fields in class init function

* gobject/valaccodegenerator.vala:
* gobject/valaccodememberaccessbinding.vala:

Fix class field access, fixes bug 530039

* tests/classes-fields.exp:
* tests/classes-fields.vala

Test class field access

svn path=/trunk/; revision=1622

ChangeLog
gobject/valaccodeclassbinding.vala
gobject/valaccodegenerator.vala
gobject/valaccodememberaccessbinding.vala
tests/classes-fields.exp
tests/classes-fields.vala

index a6a2022..61d04cf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-06-21  Jared Moore  <jaredm@svn.gnome.org>
+
+       * gobject/valaccodeclassbinding.vala:
+
+       Initialize class fields in class init function
+
+       * gobject/valaccodegenerator.vala:
+       * gobject/valaccodememberaccessbinding.vala:
+
+       Fix class field access, fixes bug 530039
+
+       * tests/classes-fields.exp:
+       * tests/classes-fields.vala
+
+       Test class field access
+
 2008-06-21  Jürg Billeter  <j@bitron.ch>
 
        * vala/valascanner.vala:
index dd53a1b..267b2ea 100644 (file)
@@ -424,6 +424,19 @@ public class Vala.CCodeClassBinding : CCodeObjectTypeSymbolBinding {
                                codegen.instance_priv_struct.add_field ("GDestroyNotify", func_name);
                        }
 
+                       /* initialize class fields */
+                       var fields = cl.get_fields ();
+                       foreach (Field field in fields) {
+                               if (field.binding != MemberBinding.CLASS || field.initializer == null) {
+                                       continue;
+                               }
+                               CCodeExpression left = new CCodeMemberAccess (new CCodeIdentifier ("klass"),
+                                                                             field.get_cname (), true);
+                               CCodeExpression right = (CCodeExpression)field.initializer.ccodenode;
+                               CCodeAssignment assign = new CCodeAssignment (left, right);
+                               init_block.add_statement (new CCodeExpressionStatement (assign));
+                       }
+
                        /* create properties */
                        var props = cl.get_properties ();
                        foreach (Property prop in props) {
index 7276072..797f15e 100644 (file)
@@ -82,6 +82,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
        private int next_try_id = 0;
        public bool in_creation_method = false;
        private bool in_constructor = false;
+       public bool in_static_or_class_ctor = false;
        public bool current_method_inner_error = false;
 
        public DataType bool_type;
@@ -949,7 +950,11 @@ public class Vala.CCodeGenerator : CodeGenerator {
                current_method_inner_error = false;
                in_constructor = true;
 
+               if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
+                       in_static_or_class_ctor = true;
+               }
                c.accept_children (this);
+               in_static_or_class_ctor = false;
 
                in_constructor = false;
 
index 2b7fba7..b772386 100644 (file)
@@ -102,7 +102,25 @@ public class Vala.CCodeMemberAccessBinding : CCodeExpressionBinding {
                        } else if (f.binding == MemberBinding.CLASS) {
                                var cl = (Class) f.parent_symbol;
                                var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
-                               cast.add_argument (new CCodeIdentifier ("klass"));
+
+                               CCodeExpression klass;
+                               if (expr.inner == null) {
+                                       if (codegen.in_static_or_class_ctor) {
+                                               // Accessing the field from a static or class constructor
+                                               klass = new CCodeIdentifier ("klass");
+                                       } else {
+                                               // Accessing the field from within an instance method
+                                               var k = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_GET_CLASS"));
+                                               k.add_argument (new CCodeIdentifier ("self"));
+                                               klass = k;
+                                       }
+                               } else {
+                                       // Accessing the field of an instance
+                                       var k = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_GET_CLASS"));
+                                       k.add_argument ((CCodeExpression) expr.inner.ccodenode);
+                                       klass = k;
+                               }
+                               cast.add_argument (klass);
                                expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
                        } else {
                                expr.ccodenode = new CCodeIdentifier (f.get_cname ());
index e7e68ab..e76fe4f 100644 (file)
@@ -1 +1 @@
-Field Test: 1 2 3 4 5 6 7 8 9 10 11 12
+Field Test: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
index 2c3a7d0..02e283e 100644 (file)
@@ -2,6 +2,7 @@ using GLib;
 
 class Maman.Foo : Object {
        public int public_base_field = 2;
+       public class int public_class_field = 23;
 }
 
 class Maman.Bar : Foo {
@@ -9,19 +10,30 @@ class Maman.Bar : Foo {
        private int private_field = 4;
        private static int private_static_field = 5;
        public static int public_static_field = 6;
-       public class int public_class_field = 7;
-       private class int private_class_field = 8;
+       private class int private_class_field; 
+       public class int public_class_field;
+
+       class construct {
+               private_class_field = 7;
+       }
+       static construct {
+               public_class_field = 8;
+       }
        
        void do_action () {
-               stdout.printf (" %d %d %d %d %d", public_base_field, public_field,
-                              private_field, private_static_field, public_static_field);
-               public_base_field = 7;
-               public_field = 8;
-               private_field = 9;
-               private_static_field = 10;
-               public_static_field = 11;
-               stdout.printf (" %d %d %d %d %d", public_base_field, public_field,
-                              private_field, private_static_field, public_static_field);
+               stdout.printf (" %d %d %d %d %d %d %d", public_base_field, public_field,
+                              private_field, private_static_field, public_static_field, 
+                                          private_class_field, public_class_field);
+               public_base_field = 9;
+               public_field = 10;
+               private_field = 11;
+               private_static_field = 12;
+               public_static_field = 13;
+               private_class_field = 14;
+               public_class_field = 15;
+               stdout.printf (" %d %d %d %d %d %d %d", public_base_field, public_field,
+                              private_field, private_static_field, public_static_field, 
+                                          private_class_field, public_class_field);
        }
 
        static int main (string[] args) {
@@ -29,8 +41,21 @@ class Maman.Bar : Foo {
                
                var bar = new Bar ();
                bar.do_action ();
-               
-               stdout.printf (" 12\n");
+
+               bar.public_base_field = 16;
+               bar.public_field = 17;
+               bar.private_field = 18;
+               bar.private_static_field = 19;
+               bar.public_static_field = 20;
+               bar.private_class_field = 21;
+               ((Foo)bar).public_class_field = 22;
+               stdout.printf (" %d %d %d %d %d %d %d", bar.public_base_field, bar.public_field,
+                              bar.private_field, bar.private_static_field, bar.public_static_field, 
+                                          bar.private_class_field, ((Foo)bar).public_class_field);
+
+               var foo = new Foo ();
+               stdout.printf (" %d", foo.public_class_field);
+               stdout.printf (" 24\n");
                
                return 0;
        }