[vala/staging: 1/2] codegen: Use g_signal_emit where possible
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging: 1/2] codegen: Use g_signal_emit where possible
- Date: Wed, 12 Oct 2016 19:22:50 +0000 (UTC)
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]