]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add support for private class fields, patch by Sebastian Dröge, fixes bug
authorJürg Billeter <j@bitron.ch>
Tue, 16 Dec 2008 21:14:45 +0000 (21:14 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Tue, 16 Dec 2008 21:14:45 +0000 (21:14 +0000)
2008-12-16  Jürg Billeter  <j@bitron.ch>

* vala/valaclass.vala:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodememberaccessmodule.vala:
* gobject/valaclassregisterfunction.vala:
* gobject/valagobjectmodule.vala:
* gobject/valainterfaceregisterfunction.vala:
* gobject/valatyperegisterfunction.vala:

Add support for private class fields, patch by Sebastian Dröge,
fixes bug 561469

svn path=/trunk/; revision=2187

ChangeLog
gobject/valaccodebasemodule.vala
gobject/valaccodememberaccessmodule.vala
gobject/valaclassregisterfunction.vala
gobject/valagobjectmodule.vala
gobject/valainterfaceregisterfunction.vala
gobject/valatyperegisterfunction.vala
vala/valaclass.vala

index 079d561fd86b1389b08f8ddf3d2f52ae802328a5..2a75d9b621d86c282c19d422104c44e4ec1b4bcb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-12-16  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valaclass.vala:
+       * gobject/valaccodebasemodule.vala:
+       * gobject/valaccodememberaccessmodule.vala:
+       * gobject/valaclassregisterfunction.vala:
+       * gobject/valagobjectmodule.vala:
+       * gobject/valainterfaceregisterfunction.vala:
+       * gobject/valatyperegisterfunction.vala:
+
+       Add support for private class fields, patch by Sebastian Dröge,
+       fixes bug 561469
+
 2008-12-16  Jürg Billeter  <j@bitron.ch>
 
        * gobject/valaccodebasemodule.vala:
index b94c76d7c23ebb602eada96bff50df1a2daf8663..981b0f18607bb8886105b81ee182316135b33d37 100644 (file)
@@ -52,6 +52,8 @@ public class Vala.CCodeBaseModule : CCodeModule {
        public CCodeFragment source_signal_marshaller_declaration;
        public CCodeFragment source_type_member_definition;
        public CCodeFragment class_init_fragment;
+       public CCodeFragment base_init_fragment;
+       public CCodeFragment base_finalize_fragment;
        public CCodeFragment instance_init_fragment;
        public CCodeFragment instance_finalize_fragment;
        public CCodeFragment source_signal_marshaller_definition;
@@ -61,6 +63,7 @@ public class Vala.CCodeBaseModule : CCodeModule {
        public CCodeStruct instance_struct;
        public CCodeStruct type_struct;
        public CCodeStruct instance_priv_struct;
+       public CCodeStruct type_priv_struct;
        public CCodeEnum prop_enum;
        public CCodeEnum cenum;
        public CCodeFunction function;
@@ -837,7 +840,8 @@ public class Vala.CCodeBaseModule : CCodeModule {
                                        lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
                                }
                        } else if (f.binding == MemberBinding.CLASS) {
-                               st = type_struct;
+                               st = type_priv_struct;
+                               lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), f.get_cname ());
                        } else {
                                var cdecl = new CCodeDeclaration (field_ctype);
                                var var_decl = new CCodeVariableDeclarator (f.get_cname ());
index 8a509f1c7e5550a93bea9ce3f7b25dd15fcdd0ef..b6391b3da7ccb29dde89ea85fdce9ca2167d8244 100644 (file)
@@ -129,7 +129,13 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                        klass = k;
                                }
                                cast.add_argument (klass);
-                               expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
+
+                               if (f.access == SymbolAccessibility.PRIVATE) {
+                                       expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (cast, "priv"), f.get_cname ());
+                               } else {
+                                       expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
+                               }
+
                        } else {
                                expr.ccodenode = new CCodeIdentifier (f.get_cname ());
                        }
index 966aaa8f87a359a43ee3f14474c419f4e7a39aa4..adc9a02b3525525b3079b8ce508fc178ec331a45 100644 (file)
@@ -51,13 +51,21 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction {
        }
 
        public override string get_base_init_func_name () {
-               if (class_reference.class_constructor != null) {
+               if (class_reference.class_constructor != null || class_reference.has_class_private_fields) {
                        return "%s_base_init".printf (class_reference.get_lower_case_cname (null));
                } else {
                        return "NULL";
                }
        }
 
+       public override string get_base_finalize_func_name () {
+               if (class_reference.has_class_private_fields) {
+                       return "%s_base_finalize".printf (class_reference.get_lower_case_cname (null));
+               } else {
+                       return "NULL";
+               }
+       }
+
        public override string get_class_init_func_name () {
                return "%s_class_init".printf (class_reference.get_lower_case_cname (null));
        }
index 8b8432b5f821968a7f047ecaa29497d20afa986a..f9efce04ff25169703b99078c047ccd9a262f047 100644 (file)
@@ -39,8 +39,11 @@ public class Vala.GObjectModule : GTypeModule {
                var old_param_spec_struct = param_spec_struct;
                var old_type_struct = type_struct;
                var old_instance_priv_struct = instance_priv_struct;
+               var old_type_priv_struct = type_priv_struct;
                var old_prop_enum = prop_enum;
                var old_class_init_fragment = class_init_fragment;
+               var old_base_init_fragment = base_init_fragment;
+               var old_base_finalize_fragment = base_finalize_fragment;
                var old_instance_init_fragment = instance_init_fragment;
                var old_instance_finalize_fragment = instance_finalize_fragment;
                current_symbol = cl;
@@ -61,9 +64,12 @@ public class Vala.GObjectModule : GTypeModule {
                instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
                type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
                instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
+               type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ()));
                prop_enum = new CCodeEnum ();
                prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
                class_init_fragment = new CCodeFragment ();
+               base_init_fragment = new CCodeFragment ();
+               base_finalize_fragment = new CCodeFragment ();
                instance_init_fragment = new CCodeFragment ();
                instance_finalize_fragment = new CCodeFragment ();
 
@@ -122,14 +128,23 @@ public class Vala.GObjectModule : GTypeModule {
                                decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
                        }
                        decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
+                       if (cl.has_class_private_fields) {
+                               decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
+                       }
 
                        instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
                        if (is_fundamental) {
                                type_struct.add_field ("GTypeClass", "parent_class");
-                               type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
                        } else {
                                type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent_class");
                        }
+                       if (cl.has_class_private_fields) {
+                               type_struct.add_field ("%sClassPrivate *".printf (cl.get_cname ()), "priv");
+                       }
+
+                       if (is_fundamental) {
+                               type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
+                       }
                }
 
                if (cl.source_reference.comment != null) {
@@ -145,6 +160,10 @@ public class Vala.GObjectModule : GTypeModule {
                                var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ());
                                source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
                        }
+
+                       if (cl.has_class_private_fields) {
+                               source_type_member_declaration.append (type_priv_struct);
+                       }
                        source_type_member_declaration.append (prop_enum);
                }
 
@@ -181,8 +200,17 @@ public class Vala.GObjectModule : GTypeModule {
                                        add_set_property_function (cl);
                                }
                        }
+
+
+                       if (cl.class_constructor != null || cl.has_class_private_fields) {
+                               add_base_init_function (cl);
+                       }
                        add_class_init_function (cl);
-                       
+
+                       if (cl.has_class_private_fields) {
+                               add_base_finalize_function (cl);
+                       }
+
                        foreach (DataType base_type in cl.get_base_types ()) {
                                if (base_type.data_type is Interface) {
                                        add_interface_init_function (cl, (Interface) base_type.data_type);
@@ -313,8 +341,11 @@ public class Vala.GObjectModule : GTypeModule {
                param_spec_struct = old_param_spec_struct;
                type_struct = old_type_struct;
                instance_priv_struct = old_instance_priv_struct;
+               type_priv_struct = old_type_priv_struct;
                prop_enum = old_prop_enum;
                class_init_fragment = old_class_init_fragment;
+               base_init_fragment = old_base_init_fragment;
+               base_finalize_fragment = old_base_finalize_fragment;
                instance_init_fragment = old_instance_init_fragment;
                instance_finalize_fragment = old_instance_finalize_fragment;
        }
@@ -682,6 +713,53 @@ public class Vala.GObjectModule : GTypeModule {
                source_type_member_definition.append (function);
        }
 
+       private void add_base_init_function (Class cl) {
+               var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
+               base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+               base_init.modifiers = CCodeModifiers.STATIC;
+
+               var init_block = new CCodeBlock ();
+               base_init.block = init_block;
+
+               if (cl.has_class_private_fields) {
+                       var block = new CCodeBlock ();
+                       var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+                       cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
+                       block.add_statement (cdecl);
+                       
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+                       ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf(cl.get_cname())));
+
+                       block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+
+                       source_include_directives.append (new CCodeIncludeDirective ("string.h"));
+
+                       var iftrue = new CCodeBlock ();
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+                       ccall.add_argument (new CCodeIdentifier ("priv"));
+                       ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"));
+                       ccall.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl.get_cname())));
+                       iftrue.add_statement (new CCodeExpressionStatement (ccall));
+
+                       block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), iftrue));
+
+                       block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), new CCodeIdentifier ("priv"))));
+
+
+                       init_block.add_statement (block);
+
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+                       ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
+                       ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"));
+                       base_finalize_fragment.append (new CCodeExpressionStatement (ccall));
+                       base_finalize_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), new CCodeIdentifier ("NULL"))));
+               }
+
+               init_block.add_statement (base_init_fragment);
+
+               source_type_member_definition.append (base_init);
+       }
+
        private void add_class_init_function (Class cl) {
                var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
                class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
@@ -790,9 +868,15 @@ public class Vala.GObjectModule : GTypeModule {
                        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;
+
+                       CCodeExpression left;
+
+                       if (field.access == SymbolAccessibility.PRIVATE) {
+                               left = new CCodeMemberAccess (new CCodeMemberAccess (new CCodeIdentifier ("klass"), "priv", true), field.get_cname (), true);
+                       } else {
+                               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));
                }
@@ -1072,7 +1156,22 @@ public class Vala.GObjectModule : GTypeModule {
 
                source_type_member_definition.append (instance_init);
        }
-       
+
+       private void add_base_finalize_function (Class cl) {
+               var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void");
+               function.modifiers = CCodeModifiers.STATIC;
+
+               function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
+               source_type_member_declaration.append (function.copy ());
+               
+               var cblock = new CCodeBlock ();
+
+               cblock.add_statement (base_finalize_fragment);
+
+               function.block = cblock;
+               source_type_member_definition.append (function);
+       }
+
        private void add_finalize_function (Class cl) {
                var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
                function.modifiers = CCodeModifiers.STATIC;
@@ -1602,25 +1701,16 @@ public class Vala.GObjectModule : GTypeModule {
                } else if (c.binding == MemberBinding.CLASS) {
                        // class constructor
 
-                       var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
-                       base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-                       base_init.modifiers = CCodeModifiers.STATIC;
-
-                       source_type_member_declaration.append (base_init.copy ());
-
-                       var block = (CCodeBlock) c.body.ccodenode;
                        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")));
-                               block.prepend_statement (cdecl);
+                               base_init_fragment.append (cdecl);
                        }
 
-                       base_init.block = block;
-               
-                       source_type_member_definition.append (base_init);
+                       base_init_fragment.append (c.body.ccodenode);
                } else if (c.binding == MemberBinding.STATIC) {
                        // static class constructor
                        // add to class_init
index 8e9ffb68c2c51a876a5f83e165ae0db7848a755f..306aa3d8cd4e66ca0121008b1b31db3edf0ffe82 100644 (file)
@@ -48,11 +48,15 @@ public class Vala.InterfaceRegisterFunction : TypeRegisterFunction {
        public override string get_base_init_func_name () {
                return "%s_base_init".printf (interface_reference.get_lower_case_cname (null));
        }
+       
+       public override string get_base_finalize_func_name () {
+               return "NULL";
+       }
 
        public override string get_class_init_func_name () {
                return "NULL";
        }
-       
+
        public override string get_instance_struct_size () {
                return "0";
        }
index 652eda63977208d2431743714948782472964743..db813865c36017be8ecc559876f77a1d73517152 100644 (file)
@@ -1,6 +1,6 @@
 /* valatyperegisterfunction.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
@@ -108,7 +108,7 @@ public abstract class Vala.TypeRegisterFunction {
                if (get_type_declaration () is ObjectTypeSymbol) {
                        var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
                        ctypedecl.modifiers = CCodeModifiers.STATIC;
-                       ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
+                       ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_base_finalize_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
                        type_init.add_statement (ctypedecl);
                        if (fundamental) {
                                var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
@@ -208,7 +208,6 @@ public abstract class Vala.TypeRegisterFunction {
        public virtual string get_type_struct_name () {
                assert_not_reached ();
        }
-
        /**
         * Returns the name of the base_init function in C code.
         *
@@ -218,6 +217,15 @@ public abstract class Vala.TypeRegisterFunction {
                assert_not_reached ();
        }
 
+       /**
+        * Returns the name of the base_finalize function in C code.
+        *
+        * @return C function name
+        */
+       public virtual string get_base_finalize_func_name () {
+               assert_not_reached ();
+       }
+
        /**
         * Returns the name of the class_init function in C code.
         *
index 3bf09e6e45ba0519ca89b7a3342d77447f09ec3c..87c7da499a8d9f27f150f56250978e208c230a35 100644 (file)
@@ -81,6 +81,11 @@ public class Vala.Class : ObjectTypeSymbol {
         * Specifies whether this class has private fields.
         */
        public bool has_private_fields { get; private set; }
+       
+       /**
+        * Specifies whether this class has class fields.
+        */
+       public bool has_class_private_fields { get; private set; }
 
        private string cname;
        private string const_cname;
@@ -247,6 +252,8 @@ public class Vala.Class : ObjectTypeSymbol {
                fields.add (f);
                if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) {
                        has_private_fields = true;
+               } else if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.CLASS) {
+                       has_class_private_fields = true;
                }
                scope.add (f.name, f);
        }