[vala/staging] codegen: Support non-virtual signals with default handler
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] codegen: Support non-virtual signals with default handler
- Date: Fri, 7 Aug 2020 17:07:12 +0000 (UTC)
commit 5da90d7c5bfe9a977720221717c774300c24484c
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Fri Aug 7 18:54:51 2020 +0200
codegen: Support non-virtual signals with default handler
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1056
codegen/valaccodeattribute.vala | 2 +-
codegen/valagsignalmodule.vala | 11 +++++++++--
codegen/valagtypemodule.vala | 22 +++++++++++++++++-----
tests/Makefile.am | 1 +
tests/objects/signals-default-class-handler.vala | 23 +++++++++++++++++++++++
vala/valasignal.vala | 13 +++----------
6 files changed, 54 insertions(+), 18 deletions(-)
---
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index 935810d2a..c73d124c0 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -1437,7 +1437,7 @@ public class Vala.CCodeAttribute : AttributeCache {
}
} else if (sym is Method) {
unowned Method m = (Method) sym;
- if (m.base_method != null || m.base_interface_method != null) {
+ if (m.base_method != null || m.base_interface_method != null || m.signal_reference !=
null) {
string m_name;
if (m.signal_reference != null) {
m_name = get_ccode_lower_case_name (m.signal_reference);
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 108622815..e005f6b38 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -347,7 +347,12 @@ public class Vala.GSignalModule : GObjectModule {
}
public override CCodeExpression get_signal_creation (Signal sig, TypeSymbol type) {
- var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
+ CCodeFunctionCall csignew;
+ if (sig.default_handler == null || sig.is_virtual) {
+ csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
+ } else {
+ csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new_class_handler"));
+ }
csignew.add_argument (new CCodeConstant ("\"%s\"".printf (get_ccode_name (sig))));
csignew.add_argument (new CCodeIdentifier (get_ccode_type_id (type)));
string[] flags = new string[0];
@@ -383,7 +388,7 @@ public class Vala.GSignalModule : GObjectModule {
if (sig.default_handler == null) {
csignew.add_argument (new CCodeConstant ("0"));
- } else {
+ } else if (sig.is_virtual) {
var struct_offset = new CCodeFunctionCall (new CCodeIdentifier ("G_STRUCT_OFFSET"));
if (type is Class) {
struct_offset.add_argument (new CCodeIdentifier ("%sClass".printf
(get_ccode_name (type))));
@@ -393,6 +398,8 @@ public class Vala.GSignalModule : GObjectModule {
}
struct_offset.add_argument (new CCodeIdentifier (get_ccode_vfunc_name
(sig.default_handler)));
csignew.add_argument (struct_offset);
+ } else {
+ csignew.add_argument (new CCodeCastExpression (new CCodeIdentifier
(get_ccode_real_name (sig.default_handler)), "GCallback"));
}
csignew.add_argument (new CCodeConstant ("NULL"));
csignew.add_argument (new CCodeConstant ("NULL"));
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 8b2c6c03d..88a1cd14b 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -271,7 +271,11 @@ public class Vala.GTypeModule : GErrorModule {
} else if (s is Signal) {
var sig = (Signal) s;
if (sig.default_handler != null) {
- generate_virtual_method_declaration (sig.default_handler,
decl_space, type_struct);
+ if (sig.is_virtual) {
+ generate_virtual_method_declaration
(sig.default_handler, decl_space, type_struct);
+ } else {
+ generate_method_declaration (sig.default_handler,
cfile);
+ }
}
} else if (s is Property) {
var prop = (Property) s;
@@ -291,7 +295,11 @@ public class Vala.GTypeModule : GErrorModule {
foreach (Signal sig in cl.get_signals ()) {
if (sig.default_handler != null) {
- generate_virtual_method_declaration (sig.default_handler, decl_space,
type_struct);
+ if (sig.is_virtual) {
+ generate_virtual_method_declaration (sig.default_handler,
decl_space, type_struct);
+ } else {
+ generate_method_declaration (sig.default_handler, cfile);
+ }
}
}
@@ -1281,7 +1289,7 @@ public class Vala.GTypeModule : GErrorModule {
/* connect default signal handlers */
foreach (Signal sig in cl.get_signals ()) {
- if (sig.default_handler == null) {
+ if (sig.default_handler == null || !sig.is_virtual) {
continue;
}
generate_method_declaration (sig.default_handler, cfile);
@@ -2118,7 +2126,11 @@ public class Vala.GTypeModule : GErrorModule {
generate_struct_method_declaration (iface, m, instance_struct, type_struct,
decl_space, ref has_struct_member);
} else if ((sig = sym as Signal) != null) {
if (sig.default_handler != null) {
- generate_virtual_method_declaration (sig.default_handler, decl_space,
type_struct);
+ if (sig.is_virtual) {
+ generate_virtual_method_declaration (sig.default_handler,
decl_space, type_struct);
+ } else {
+ generate_method_declaration (sig.default_handler, cfile);
+ }
}
} else if ((prop = sym as Property) != null) {
generate_struct_property_declaration (iface, prop, instance_struct,
type_struct, decl_space, ref has_struct_member);
@@ -2222,7 +2234,7 @@ public class Vala.GTypeModule : GErrorModule {
/* connect default signal handlers */
foreach (Signal sig in iface.get_signals ()) {
- if (sig.default_handler == null) {
+ if (sig.default_handler == null || !sig.is_virtual) {
continue;
}
var cname = get_ccode_real_name (sig.default_handler);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b28a2a45f..e98e4dca6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -436,6 +436,7 @@ TESTS = \
objects/sealed-class.test \
objects/sealed-compact-class.test \
objects/signals.vala \
+ objects/signals-default-class-handler.vala \
objects/signals-enum-marshal.vala \
objects/signals-delegate.vala \
objects/signals-delegate-parameter.vala \
diff --git a/tests/objects/signals-default-class-handler.vala
b/tests/objects/signals-default-class-handler.vala
new file mode 100644
index 000000000..aff938726
--- /dev/null
+++ b/tests/objects/signals-default-class-handler.vala
@@ -0,0 +1,23 @@
+bool success = false;
+bool success2 = false;
+
+class Foo {
+ public signal void foo () {
+ success = true;
+ }
+
+ [HasEmitter]
+ public signal void foo_with_emitter () {
+ success2 = true;
+ }
+}
+
+void main () {
+ var foo = new Foo ();
+
+ foo.foo ();
+ assert (success);
+
+ foo.foo_with_emitter ();
+ assert (success2);
+}
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index 392b31489..df7d76199 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -222,24 +222,17 @@ public class Vala.Signal : Symbol, Callable {
}
}
- if (!is_virtual && body != null) {
- error = true;
- Report.error (source_reference, "Only virtual signals can have a default signal
handler body");
- }
-
-
- if (is_virtual) {
+ if (body != null || (is_virtual && external_package)) {
default_handler = new Method (name, return_type, source_reference);
default_handler.owner = owner;
- default_handler.access = access;
+ default_handler.access = (is_virtual ? access : SymbolAccessibility.PRIVATE);
default_handler.external = external;
default_handler.hides = hides;
- default_handler.is_virtual = true;
+ default_handler.is_virtual = is_virtual;
default_handler.signal_reference = this;
default_handler.body = body;
-
foreach (Parameter param in parameters) {
default_handler.add_parameter (param);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]