]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support subclassing of GLib.Source
authorJürg Billeter <j@bitron.ch>
Wed, 15 Aug 2012 20:22:34 +0000 (22:22 +0200)
committerJürg Billeter <j@bitron.ch>
Wed, 15 Aug 2012 20:22:34 +0000 (22:22 +0200)
codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valagtypemodule.vala
vala/valaclass.vala
vala/valamethod.vala
vala/valasemanticanalyzer.vala
vapi/glib-2.0.vapi

index 0d1472c9902cc8c3a6523d28d12b73182fae1552..5881751b288d13458017fb1f2c8f1e689b11c252 100644 (file)
@@ -318,6 +318,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public Struct grecmutex_type;
        public Struct grwlock_type;
        public Struct gcond_type;
+       public Class gsource_type;
        public TypeSymbol type_module_type;
        public TypeSymbol dbus_proxy_type;
 
@@ -460,6 +461,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark"));
                gvalue_type = (Struct) glib_ns.scope.lookup ("Value");
                gvariant_type = (Class) glib_ns.scope.lookup ("Variant");
+               gsource_type = (Class) glib_ns.scope.lookup ("Source");
                mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex");
 
                if (context.require_glib_version (2, 32)) {
index bd816092692f1b3c666a24507771703875e8db62..8cb1171407f860cefe4be8c32b06d1333258eb9d 100644 (file)
@@ -150,6 +150,21 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                                type_param_index++;
                                        }
                                }
+                       } else if (current_class.base_class == gsource_type) {
+                               // g_source_new
+
+                               string class_prefix = CCodeBaseModule.get_ccode_lower_case_name (current_class);
+
+                               var funcs = new CCodeDeclaration ("const GSourceFuncs");
+                               funcs.modifiers = CCodeModifiers.STATIC;
+                               funcs.add_declarator (new CCodeVariableDeclarator ("_source_funcs", new CCodeConstant ("{ %s_real_prepare, %s_real_check, %s_real_dispatch, %s_finalize}".printf (class_prefix, class_prefix, class_prefix, class_prefix))));
+                               ccode.add_statement (funcs);
+
+                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_source_funcs")));
+
+                               var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+                               csizeof.add_argument (new CCodeIdentifier (get_ccode_name (current_class)));
+                               ccall.add_argument (csizeof);
                        }
                } else if (m is CreationMethod && m.parent_symbol is Struct) {
                        ccall.add_argument (get_this_cexpression ());
@@ -795,6 +810,12 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                        // assign new value
                        store_value (unary.inner.target_value, transform_value (unary.target_value, unary.inner.value_type, arg));
                }
+
+               if (m is CreationMethod && m.parent_symbol is Class && current_class.base_class == gsource_type) {
+                       var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (get_ccode_lower_case_name (current_class, null))));
+                       cinitcall.add_argument (get_this_cexpression ());
+                       ccode.add_expression (cinitcall);
+               }
        }
 
        private string generate_enum_tostring_function (Enum en) {
index ab29c5846ee6132015934ee89e605626d29ce5bb..3be2d29f6f35896263f2913b43b6d4d9b3e6be03 100644 (file)
@@ -60,6 +60,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                bool is_gtypeinstance = !cl.is_compact;
                bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+               bool is_gsource = cl.base_class == gsource_type;
 
                if (is_gtypeinstance) {
                        decl_space.add_type_declaration (new CCodeNewline ());
@@ -83,7 +84,7 @@ public class Vala.GTypeModule : GErrorModule {
                        decl_space.add_type_declaration (new CCodeNewline ());
                }
 
-               if (cl.is_compact && cl.base_class != null) {
+               if (cl.is_compact && cl.base_class != null && !is_gsource) {
                        decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (cl.base_class), new CCodeVariableDeclarator (get_ccode_name (cl))));
                } else {
                        decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (cl)), new CCodeVariableDeclarator (get_ccode_name (cl))));
@@ -155,7 +156,7 @@ public class Vala.GTypeModule : GErrorModule {
                        }
 
                        decl_space.add_function_declaration (function);
-               } else if (!is_gtypeinstance) {
+               } else if (!is_gtypeinstance && !is_gsource) {
                        if (cl.base_class == null) {
                                var function = new CCodeFunction (get_ccode_lower_case_prefix (cl) + "free", "void");
                                if (cl.access == SymbolAccessibility.PRIVATE) {
@@ -197,6 +198,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                bool is_gtypeinstance = !cl.is_compact;
                bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+               bool is_gsource = cl.base_class == gsource_type;
 
                var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (cl)));
                var type_struct = new CCodeStruct ("_%sClass".printf (get_ccode_name (cl)));
@@ -350,7 +352,7 @@ public class Vala.GTypeModule : GErrorModule {
                        }
                }
 
-               if (!cl.is_compact || cl.base_class == null) {
+               if (!cl.is_compact || cl.base_class == null || is_gsource) {
                        // derived compact classes do not have a struct
                        decl_space.add_type_definition (instance_struct);
                }
@@ -574,7 +576,7 @@ public class Vala.GTypeModule : GErrorModule {
                        begin_class_finalize_function (cl);
                        begin_finalize_function (cl);
                } else {
-                       if (cl.base_class == null) {
+                       if (cl.base_class == null || cl.base_class == gsource_type) {
                                begin_instance_init_function (cl);
                                begin_finalize_function (cl);
                        }
@@ -698,7 +700,7 @@ public class Vala.GTypeModule : GErrorModule {
                                cfile.add_function (unref_fun);
                        }
                } else {
-                       if (cl.base_class == null) {
+                       if (cl.base_class == null || cl.base_class == gsource_type) {
                                // derived compact classes do not have fields
                                add_instance_init_function (cl);
                                add_finalize_function (cl);
@@ -1645,7 +1647,9 @@ public class Vala.GTypeModule : GErrorModule {
        private void begin_finalize_function (Class cl) {
                push_context (instance_finalize_context);
 
-               if (!cl.is_compact) {
+               bool is_gsource = cl.base_class == gsource_type;
+
+               if (!cl.is_compact || is_gsource) {
                        var fundamental_class = cl;
                        while (fundamental_class.base_class != null) {
                                fundamental_class = fundamental_class.base_class;
@@ -1657,10 +1661,19 @@ public class Vala.GTypeModule : GErrorModule {
 
                        push_function (func);
 
-                       CCodeFunctionCall ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
+                       if (is_gsource) {
+                               cfile.add_function_declaration (func);
+                       }
+
+                       CCodeExpression ccast;
+                       if (!cl.is_compact) {
+                               ccast = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
+                       } else {
+                               ccast = new CCodeCastExpression (new CCodeIdentifier ("obj"), get_ccode_name (cl) + "*");
+                       }
 
                        ccode.add_declaration ("%s *".printf (get_ccode_name (cl)), new CCodeVariableDeclarator ("self"));
-                       ccode.add_assignment (new CCodeIdentifier ("self"), ccall);
+                       ccode.add_assignment (new CCodeIdentifier ("self"), ccast);
                } else {
                        var function = new CCodeFunction (get_ccode_lower_case_prefix (cl) + "free", "void");
                        if (cl.access == SymbolAccessibility.PRIVATE) {
@@ -1707,7 +1720,7 @@ public class Vala.GTypeModule : GErrorModule {
                        }
 
                        cfile.add_function_declaration (instance_finalize_context.ccode);
-               } else {
+               } else if (cl.base_class == null) {
                        var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
                        ccall.add_argument (new CCodeIdentifier (get_ccode_name (cl)));
                        ccall.add_argument (new CCodeIdentifier ("self"));
index 63278788a72bf1de11311ed5098f62709feb3560..5110a7aa63854fea5f4c90331ef5f521b99cb5da 100644 (file)
@@ -720,7 +720,7 @@ public class Vala.Class : ObjectTypeSymbol {
                                }
                        }
 
-                       if (!external && !external_package && base_class != null) {
+                       if (!external && !external_package && base_class != null && base_class != context.analyzer.gsource_type) {
                                foreach (Field f in fields) {
                                        if (f.binding == MemberBinding.INSTANCE) {
                                                error = true;
index 942f0d2fd708fc83e31c6e36ae0a4a769a6b2132..7af50e8e81a39c43610de9951537826f80c0e6ee 100644 (file)
@@ -589,7 +589,7 @@ public class Vala.Method : Subroutine {
 
                        if (parent_symbol is Class) {
                                var cl = (Class) parent_symbol;
-                               if (cl.is_compact) {
+                               if (cl.is_compact && cl != context.analyzer.gsource_type) {
                                        Report.error (source_reference, "Virtual methods may not be declared in compact classes");
                                        return false;
                                }
index 8afe17582f9d5b71d4f7f6bf867ef1341015579c..90923ac2c5ddeabe095bc57465d739deab406dfa 100644 (file)
@@ -161,6 +161,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public DataType list_type;
        public DataType tuple_type;
        public DataType error_type;
+       public Class gsource_type;
 
        public int next_lambda_id = 0;
 
@@ -216,6 +217,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                gerror_type = (Class) glib_ns.scope.lookup ("Error");
                regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex"));
 
+               gsource_type = (Class) glib_ns.scope.lookup ("Source");
+
                current_symbol = root_symbol;
                context.root.check (context);
                context.accept (this);
index cb7ccd03a524e414fd6accadeeed67cad49ba50c..50805233c89770c554c6251a5a05205525a54181 100644 (file)
@@ -1584,8 +1584,8 @@ namespace GLib {
 
        [Compact]
        [CCode (ref_function = "g_source_ref", unref_function = "g_source_unref")]
-       public class Source {
-               public Source (SourceFuncs source_funcs, uint struct_size /* = sizeof (Source) */);
+       public abstract class Source {
+               protected Source ();
                public void set_funcs (SourceFuncs funcs);
                public uint attach (MainContext? context);
                public void destroy ();
@@ -1611,6 +1611,10 @@ namespace GLib {
                public static bool remove (uint id);
                public static bool remove_by_funcs_user_data (void* user_data);
                public static bool remove_by_user_data (void* user_data);
+
+               protected abstract bool prepare (out int timeout_);
+               protected abstract bool check ();
+               protected abstract bool dispatch (SourceFunc _callback);
        }
 
        [CCode (has_target = false)]