[vala/staging: 1/2] codegen: Use g_signal_emit where possible



commit 3bbf223347d9280accb608c90672312d4bd30a05
Author: Simon Werbeck <simon werbeck gmail com>
Date:   Wed Oct 5 19:01:44 2016 +0200

    codegen: Use g_signal_emit where possible
    
    https://bugzilla.gnome.org/show_bug.cgi?id=641828

 codegen/valaccodebasemodule.vala |    3 +-
 codegen/valagsignalmodule.vala   |   68 +++++++++++++++++++++++++++++++++-----
 codegen/valagtypemodule.vala     |   31 +++++++++++++++++
 tests/Makefile.am                |    1 +
 tests/objects/bug641828.vala     |   15 ++++++++
 5 files changed, 108 insertions(+), 10 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 32f461a..2f983d0 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -239,6 +239,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public CCodeStruct param_spec_struct;
        public CCodeStruct closure_struct;
        public CCodeEnum prop_enum;
+       public CCodeEnum signal_enum;
 
        public CCodeFunction ccode { get { return emit_context.ccode; } }
 
@@ -6568,7 +6569,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return new CCodeFunctionCall (new CCodeIdentifier (""));
        }
 
-       public virtual CCodeFunctionCall get_signal_creation (Signal sig, TypeSymbol type) {
+       public virtual CCodeExpression get_signal_creation (Signal sig, TypeSymbol type) {
                return new CCodeFunctionCall (new CCodeIdentifier (""));
        }
 
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index d9f7d51..f995f27 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -132,6 +132,33 @@ public class Vala.GSignalModule : GObjectModule {
                return get_cvalue_ (detail_value);
        }
 
+       private CCodeExpression get_signal_id_cexpression (Signal sig) {
+               var cl = (TypeSymbol) sig.parent_symbol;
+               var signal_array = new CCodeIdentifier ("%s_signals".printf (get_ccode_lower_case_name (cl)));
+               var signal_enum_value = new CCodeIdentifier ("%s_%s_SIGNAL".printf (get_ccode_upper_case_name 
(cl), sig.name.ascii_up ()));
+
+               return new CCodeElementAccess (signal_array, signal_enum_value);
+       }
+
+       private CCodeExpression? get_detail_cexpression (Expression detail_expr, CodeNode node) {
+               if (detail_expr.value_type is NullType || !detail_expr.value_type.compatible (string_type)) {
+                       node.error = true;
+                       Report.error (detail_expr.source_reference, "only string details are supported");
+                       return null;
+               }
+
+               var detail_cexpr = get_cvalue (detail_expr);
+               CCodeFunctionCall detail_ccall;
+               if (is_constant_ccode_expression (detail_cexpr)) {
+                       detail_ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_quark_from_static_string"));
+               } else {
+                       detail_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
+               }
+               detail_ccall.add_argument (detail_cexpr);
+
+               return detail_ccall;
+       }
+
        public override void visit_signal (Signal sig) {
                // parent_symbol may be null for dynamic signals
 
@@ -152,6 +179,8 @@ public class Vala.GSignalModule : GObjectModule {
                        }
                }
 
+               signal_enum.add_value (new CCodeEnumValue ("%s_%s_SIGNAL".printf (get_ccode_upper_case_name 
((TypeSymbol)sig.parent_symbol), sig.name.ascii_up ())));
+
                sig.accept_children (this);
 
                // declare parameter type
@@ -304,7 +333,7 @@ public class Vala.GSignalModule : GObjectModule {
                user_marshal_set.add (signature);
        }
 
-       public override CCodeFunctionCall get_signal_creation (Signal sig, TypeSymbol type) {   
+       public override CCodeExpression get_signal_creation (Signal sig, TypeSymbol type) {
                var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
                csignew.add_argument (new CCodeConstant ("\"%s\"".printf (get_ccode_name (sig))));
                csignew.add_argument (new CCodeIdentifier (get_ccode_type_id (type)));
@@ -399,7 +428,7 @@ public class Vala.GSignalModule : GObjectModule {
 
                marshal_arg.name = marshaller;
 
-               return csignew;
+               return new CCodeAssignment (get_signal_id_cexpression (sig), csignew);
        }
 
        public override void visit_element_access (ElementAccess expr) {
@@ -410,13 +439,27 @@ public class Vala.GSignalModule : GObjectModule {
                                var ma = (MemberAccess) expr.container;
 
                                var detail_expr = expr.get_indices ().get (0);
-                               var signal_name_cexpr = get_signal_name_cexpression (sig, detail_expr, expr);
-                       
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_signal_emit_by_name"));
-                               ccall.add_argument (get_cvalue (ma.inner));
-                               if (signal_name_cexpr != null) {
-                                       ccall.add_argument (signal_name_cexpr);
+
+                               CCodeFunctionCall ccall;
+                               if (!sig.external_package && expr.source_reference.file == 
sig.source_reference.file) {
+                                       var detail_cexpr = get_detail_cexpression (detail_expr, expr);
+
+                                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit"));
+                                       ccall.add_argument (get_cvalue (ma.inner));
+                                       ccall.add_argument (get_signal_id_cexpression (sig));
+                                       if (detail_cexpr != null) {
+                                               ccall.add_argument (detail_cexpr);
+                                       }
+                               } else {
+                                       var signal_name_cexpr = get_signal_name_cexpression (sig, 
detail_expr, expr);
+
+                                       ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_signal_emit_by_name"));
+                                       ccall.add_argument (get_cvalue (ma.inner));
+                                       if (signal_name_cexpr != null) {
+                                               ccall.add_argument (signal_name_cexpr);
+                                       }
                                }
+
                                set_cvalue (expr, ccall);
                        } else {
                                // signal connect or disconnect
@@ -487,7 +530,14 @@ public class Vala.GSignalModule : GObjectModule {
                                return;
                        }
 
-                       if (get_signal_has_emitter (sig)) {
+                       if (!sig.external_package && expr.source_reference.file == sig.source_reference.file) 
{
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit"));
+                               ccall.add_argument (pub_inst);
+                               ccall.add_argument (get_signal_id_cexpression (sig));
+                               ccall.add_argument (new CCodeConstant ("0"));
+
+                               set_cvalue (expr, ccall);
+                       } else if (get_signal_has_emitter (sig)) {
                                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf 
(get_ccode_lower_case_name (cl), sig.name)));
 
                                ccall.add_argument (pub_inst);
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index b732886..f46465f 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -537,6 +537,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                var old_param_spec_struct = param_spec_struct;
                var old_prop_enum = prop_enum;
+               var old_signal_enum = signal_enum;
                var old_class_init_context = class_init_context;
                var old_base_init_context = base_init_context;
                var old_class_finalize_context = class_finalize_context;
@@ -555,6 +556,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                prop_enum = new CCodeEnum ();
                prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf 
(get_ccode_upper_case_name (cl, null))));
+               signal_enum = new CCodeEnum ();
                class_init_context = new EmitContext (cl);
                base_init_context = new EmitContext (cl);
                class_finalize_context = new EmitContext (cl);
@@ -618,6 +620,17 @@ public class Vala.GTypeModule : GErrorModule {
                                pop_context ();
                        }
 
+                       if (cl.get_signals ().size > 0) {
+                               var last_signal = "%s_LAST_SIGNAL".printf (get_ccode_upper_case_name (cl));
+                               signal_enum.add_value (new CCodeEnumValue (last_signal));
+                               cfile.add_type_declaration (signal_enum);
+
+                               var signal_array_decl = new CCodeDeclaration ("guint");
+                               signal_array_decl.modifiers |= CCodeModifiers.STATIC;
+                               signal_array_decl.add_declarator (new CCodeVariableDeclarator 
("%s_signals".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("{0}"), new 
CCodeDeclaratorSuffix.with_array (new CCodeIdentifier (last_signal))));
+                               cfile.add_type_declaration (signal_array_decl);
+                       }
+
 
                        if (cl.class_constructor != null) {
                                add_base_init_function (cl);
@@ -719,6 +732,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                param_spec_struct = old_param_spec_struct;
                prop_enum = old_prop_enum;
+               signal_enum = old_signal_enum;
                class_init_context = old_class_init_context;
                base_init_context = old_base_init_context;
                class_finalize_context = old_class_finalize_context;
@@ -2032,12 +2046,16 @@ public class Vala.GTypeModule : GErrorModule {
                push_context (new EmitContext (iface));
                push_line (iface.source_reference);
 
+               var old_signal_enum = signal_enum;
+
                if (get_ccode_name (iface).length < 3) {
                        iface.error = true;
                        Report.error (iface.source_reference, "Interface name `%s' is too short".printf 
(get_ccode_name (iface)));
                        return;
                }
 
+               signal_enum = new CCodeEnum ();
+
                generate_interface_declaration (iface, cfile);
                if (!iface.is_internal_symbol ()) {
                        generate_interface_declaration (iface, header_file);
@@ -2048,6 +2066,17 @@ public class Vala.GTypeModule : GErrorModule {
 
                iface.accept_children (this);
 
+               if (iface.get_signals ().size > 0) {
+                       var last_signal = "%s_LAST_SIGNAL".printf (get_ccode_upper_case_name (iface));
+                       signal_enum.add_value (new CCodeEnumValue (last_signal));
+                       cfile.add_type_declaration (signal_enum);
+
+                       var signal_array_decl = new CCodeDeclaration ("guint");
+                       signal_array_decl.modifiers |= CCodeModifiers.STATIC;
+                       signal_array_decl.add_declarator (new CCodeVariableDeclarator ("%s_signals".printf 
(get_ccode_lower_case_name (iface)), new CCodeConstant ("{0}"), new CCodeDeclaratorSuffix.with_array (new 
CCodeIdentifier (last_signal))));
+                       cfile.add_type_declaration (signal_array_decl);
+               }
+
                add_interface_base_init_function (iface);
 
                if (iface.comment != null) {
@@ -2059,6 +2088,8 @@ public class Vala.GTypeModule : GErrorModule {
                cfile.add_type_member_declaration (type_fun.get_source_declaration ());
                cfile.add_type_member_definition (type_fun.get_definition ());
 
+               signal_enum = old_signal_enum;
+
                pop_line ();
                pop_context ();
        }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a9d0c18..901cb28 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -162,6 +162,7 @@ TESTS = \
        objects/bug641418-1.test \
        objects/bug641418-2.test \
        objects/bug641418-3.test \
+       objects/bug641828.vala \
        objects/bug642809.vala \
        objects/bug643711.vala \
        objects/bug646362.vala \
diff --git a/tests/objects/bug641828.vala b/tests/objects/bug641828.vala
new file mode 100644
index 0000000..159515d
--- /dev/null
+++ b/tests/objects/bug641828.vala
@@ -0,0 +1,15 @@
+public interface Bar : GLib.Object {
+       public signal int bar (int i);
+}
+
+public class Foo : GLib.Object, Bar {
+}
+
+void main () {
+       var f = new Foo ();
+
+       f.bar.connect (i => i + 12);
+
+       var res = f.bar (30);
+       assert (res == 42);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]