]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use g_signal_emit where possible
authorSimon Werbeck <simon.werbeck@gmail.com>
Wed, 5 Oct 2016 17:01:44 +0000 (19:01 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 12 Oct 2016 19:14:55 +0000 (21:14 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=641828

codegen/valaccodebasemodule.vala
codegen/valagsignalmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/objects/bug641828.vala [new file with mode: 0644]

index 32f461a9b8bf679744a8a2f3277a5e676ade2bd5..2f983d0d2a113c4b048dbda611d47600a1ddcf11 100644 (file)
@@ -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 (""));
        }
 
index d9f7d51f387851eeb01cf686fb52ff817108cf7d..f995f2794a330bd86437d073f73dde68f123bfe3 100644 (file)
@@ -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);
index b7328860ebc64f14fb93366d79a00862da8fdc31..f46465fc5c2eb8006573f4e1acad2d83a67caf28 100644 (file)
@@ -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 ();
        }
index a9d0c18e4a7454bda21ffefc36a76af158b17fd1..901cb2815fe4ed7d9baf4eaf75d2cc32a97eaa50 100644 (file)
@@ -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 (file)
index 0000000..159515d
--- /dev/null
@@ -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);
+}