diff options
author | Jürg Billeter <j@bitron.ch> | 2012-08-15 22:22:34 +0200 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2012-08-15 22:22:34 +0200 |
commit | 22ec8fe6c183fce66917136787dd6b9e28c49419 (patch) | |
tree | 95a2e354db888c039e8ada4fa1540f226152ce3d | |
parent | 3126a8e1af2deca94c5d3cad1e82ab1dac6f7a67 (diff) | |
download | vala-gsource.tar.gz |
Support subclassing of GLib.Sourcegsource
-rw-r--r-- | codegen/valaccodebasemodule.vala | 2 | ||||
-rw-r--r-- | codegen/valaccodemethodcallmodule.vala | 21 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 31 | ||||
-rw-r--r-- | vala/valaclass.vala | 2 | ||||
-rw-r--r-- | vala/valamethod.vala | 2 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 3 | ||||
-rw-r--r-- | vapi/glib-2.0.vapi | 8 |
7 files changed, 56 insertions, 13 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 0d1472c99..5881751b2 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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)) { diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index bd8160926..8cb117140 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -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) { diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index ab29c5846..3be2d29f6 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -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")); diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 63278788a..5110a7aa6 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -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; diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 942f0d2fd..7af50e8e8 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -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; } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 8afe17582..90923ac2c 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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); diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index cb7ccd03a..50805233c 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -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)] |