From: Simon Werbeck Date: Wed, 5 Oct 2016 17:01:44 +0000 (+0200) Subject: codegen: Use g_signal_emit where possible X-Git-Tag: 0.35.1~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bbf223347d9280accb608c90672312d4bd30a05;p=thirdparty%2Fvala.git codegen: Use g_signal_emit where possible https://bugzilla.gnome.org/show_bug.cgi?id=641828 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 32f461a9b..2f983d0d2 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 d9f7d51f3..f995f2794 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 b7328860e..f46465fc5 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 a9d0c18e4..901cb2815 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 000000000..159515d99 --- /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); +}