summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenz Wildberg <lorenz@wild-fisch.de>2021-12-04 19:05:42 +0000
committerRico Tzschichholz <ricotz@ubuntu.com>2022-01-04 14:51:37 +0100
commitd74400bfaae61a1e2c246382e627b0a9adf8c304 (patch)
treeca0ae596870df270819adcfbcac35b9d83585280
parentde1682099945edfd8d23958cf45186aecbd0015e (diff)
downloadvala-d74400bfaae61a1e2c246382e627b0a9adf8c304.tar.gz
Support "emit" for explicit signal emission
If "foo" is a signal then "foo.emit (...);" is allowed now additionally to "foo (...);". This is required to emit dynamic signals.
-rw-r--r--codegen/valaccodemethodcallmodule.vala4
-rw-r--r--codegen/valagsignalmodule.vala2
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/objects/signals-dynamic-emit.c-expected195
-rw-r--r--tests/objects/signals-dynamic-emit.vala20
-rw-r--r--tests/objects/signals-emit.c-expected206
-rw-r--r--tests/objects/signals-emit.vala28
-rw-r--r--vala/valamemberaccess.vala13
-rw-r--r--vala/valasignaltype.vala13
9 files changed, 481 insertions, 2 deletions
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 894660c88..d7ac3f4b0 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -715,7 +715,9 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
if (ellipsis) {
/* ensure variable argument list ends with NULL
* except when using printf-style arguments */
- if (m == null) {
+ if (itype is SignalType) {
+ // g_signal_emit*() does not require more
+ } else if (m == null) {
in_arg_map.set (get_param_pos (-1, true), new CCodeConstant ("NULL"));
} else if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "" && !expr.is_constructv_chainup) {
in_arg_map.set (get_param_pos (-1, true), new CCodeConstant (get_ccode_sentinel (m)));
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index cfd4a5da8..4186859cf 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -537,7 +537,7 @@ public class Vala.GSignalModule : GObjectModule {
return new CCodeMemberAccess.pointer (vcast, m.name);
}
- if (!sig.external_package && expr.source_reference.file == sig.source_reference.file) {
+ if (!sig.external_package && expr.source_reference.file == sig.source_reference.file && !(sig is DynamicSignal)) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit"));
ccall.add_argument (pub_inst);
ccall.add_argument (get_signal_id_cexpression (sig));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2b4cb2ba4..c34a84fa1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -556,9 +556,11 @@ TESTS = \
objects/signals-enum-marshal.vala \
objects/signals-delegate.vala \
objects/signals-delegate-parameter.vala \
+ objects/signals-dynamic-emit.vala \
objects/signals-dynamic-invalid-disconnect.test \
objects/signals-dymanic-invalid-handler.test \
objects/signals-dynamic-lambda-handler.test \
+ objects/signals-emit.vala \
objects/signals-error-marshal.vala \
objects/signals-fundamental-return.vala \
objects/signals-generic-return.vala \
diff --git a/tests/objects/signals-dynamic-emit.c-expected b/tests/objects/signals-dynamic-emit.c-expected
new file mode 100644
index 000000000..5b04c9bbb
--- /dev/null
+++ b/tests/objects/signals-dynamic-emit.c-expected
@@ -0,0 +1,195 @@
+/* objects_signals_dynamic_emit.c generated by valac, the Vala compiler
+ * generated from objects_signals_dynamic_emit.vala, do not modify */
+
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define TYPE_FOO (foo_get_type ())
+#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo))
+#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass))
+#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO))
+#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO))
+#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass))
+
+typedef struct _Foo Foo;
+typedef struct _FooClass FooClass;
+typedef struct _FooPrivate FooPrivate;
+enum {
+ FOO_0_PROPERTY,
+ FOO_NUM_PROPERTIES
+};
+static GParamSpec* foo_properties[FOO_NUM_PROPERTIES];
+enum {
+ FOO_SIG_SIGNAL,
+ FOO_NUM_SIGNALS
+};
+static guint foo_signals[FOO_NUM_SIGNALS] = {0};
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+struct _Foo {
+ GObject parent_instance;
+ FooPrivate * priv;
+};
+
+struct _FooClass {
+ GObjectClass parent_class;
+};
+
+static gpointer foo_parent_class = NULL;
+VALA_EXTERN gboolean success;
+gboolean success = FALSE;
+
+VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, g_object_unref)
+VALA_EXTERN Foo* foo_new (void);
+VALA_EXTERN Foo* foo_construct (GType object_type);
+static void g_cclosure_user_marshal_VOID__STRING_INT (GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+static GType foo_get_type_once (void);
+VALA_EXTERN void sig_cb (GObject* o,
+ const gchar* s,
+ gint i);
+static void _vala_main (void);
+static void _sig_cb_dynamic_sig0_ (GObject* _sender,
+ const gchar* s,
+ gint i,
+ gpointer self);
+
+Foo*
+foo_construct (GType object_type)
+{
+ Foo * self = NULL;
+ self = (Foo*) g_object_new (object_type, NULL);
+ return self;
+}
+
+Foo*
+foo_new (void)
+{
+ return foo_construct (TYPE_FOO);
+}
+
+static void
+g_cclosure_user_marshal_VOID__STRING_INT (GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1, const char* arg_1, gint arg_2, gpointer data2);
+ register GMarshalFunc_VOID__STRING_INT callback;
+ register GCClosure * cc;
+ register gpointer data1;
+ register gpointer data2;
+ cc = (GCClosure *) closure;
+ g_return_if_fail (n_param_values == 3);
+ if (G_CCLOSURE_SWAP_DATA (closure)) {
+ data1 = closure->data;
+ data2 = param_values->data[0].v_pointer;
+ } else {
+ data1 = param_values->data[0].v_pointer;
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
+ callback (data1, g_value_get_string (param_values + 1), g_value_get_int (param_values + 2), data2);
+}
+
+static void
+foo_class_init (FooClass * klass,
+ gpointer klass_data)
+{
+ foo_parent_class = g_type_class_peek_parent (klass);
+ foo_signals[FOO_SIG_SIGNAL] = g_signal_new ("sig", TYPE_FOO, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_INT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+}
+
+static void
+foo_instance_init (Foo * self,
+ gpointer klass)
+{
+}
+
+static GType
+foo_get_type_once (void)
+{
+ static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, NULL };
+ GType foo_type_id;
+ foo_type_id = g_type_register_static (G_TYPE_OBJECT, "Foo", &g_define_type_info, 0);
+ return foo_type_id;
+}
+
+GType
+foo_get_type (void)
+{
+ static volatile gsize foo_type_id__once = 0;
+ if (g_once_init_enter (&foo_type_id__once)) {
+ GType foo_type_id;
+ foo_type_id = foo_get_type_once ();
+ g_once_init_leave (&foo_type_id__once, foo_type_id);
+ }
+ return foo_type_id__once;
+}
+
+void
+sig_cb (GObject* o,
+ const gchar* s,
+ gint i)
+{
+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (o, G_TYPE_OBJECT));
+ g_return_if_fail (s != NULL);
+ success = TRUE;
+ _vala_assert (g_strcmp0 (s, "foo") == 0, "s == \"foo\"");
+ _vala_assert (i == 42, "i == 42");
+}
+
+static void
+_sig_cb_dynamic_sig0_ (GObject* _sender,
+ const gchar* s,
+ gint i,
+ gpointer self)
+{
+ sig_cb (_sender, s, i);
+}
+
+static void
+_vala_main (void)
+{
+ GObject* dfoo = NULL;
+ Foo* _tmp0_;
+ _tmp0_ = foo_new ();
+ dfoo = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, G_TYPE_OBJECT, GObject);
+ g_signal_connect (dfoo, "sig", (GCallback) _sig_cb_dynamic_sig0_, NULL);
+ success = FALSE;
+ g_signal_emit_by_name (dfoo, "sig", "foo", 42);
+ _vala_assert (success, "success");
+ _g_object_unref0 (dfoo);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/objects/signals-dynamic-emit.vala b/tests/objects/signals-dynamic-emit.vala
new file mode 100644
index 000000000..55d6fac98
--- /dev/null
+++ b/tests/objects/signals-dynamic-emit.vala
@@ -0,0 +1,20 @@
+class Foo : Object {
+ public signal void sig (string s, int i);
+}
+
+void sig_cb (Object o, string s, int i) {
+ success = true;
+ assert (s == "foo");
+ assert (i == 42);
+}
+
+bool success = false;
+
+void main () {
+ dynamic Object dfoo = new Foo ();
+ dfoo.sig.connect (sig_cb);
+
+ success = false;
+ dfoo.sig.emit ("foo", 42);
+ assert (success);
+}
diff --git a/tests/objects/signals-emit.c-expected b/tests/objects/signals-emit.c-expected
new file mode 100644
index 000000000..e249f6fe7
--- /dev/null
+++ b/tests/objects/signals-emit.c-expected
@@ -0,0 +1,206 @@
+/* objects_signals_emit.c generated by valac, the Vala compiler
+ * generated from objects_signals_emit.vala, do not modify */
+
+#include <glib-object.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define TYPE_FOO (foo_get_type ())
+#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo))
+#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass))
+#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO))
+#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO))
+#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass))
+
+typedef struct _Foo Foo;
+typedef struct _FooClass FooClass;
+typedef struct _FooPrivate FooPrivate;
+enum {
+ FOO_0_PROPERTY,
+ FOO_NUM_PROPERTIES
+};
+static GParamSpec* foo_properties[FOO_NUM_PROPERTIES];
+enum {
+ FOO_SIG_SIGNAL,
+ FOO_NUM_SIGNALS
+};
+static guint foo_signals[FOO_NUM_SIGNALS] = {0};
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+struct _Foo {
+ GObject parent_instance;
+ FooPrivate * priv;
+};
+
+struct _FooClass {
+ GObjectClass parent_class;
+};
+
+static gpointer foo_parent_class = NULL;
+VALA_EXTERN gboolean success;
+gboolean success = FALSE;
+
+VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, g_object_unref)
+VALA_EXTERN void foo_fire (Foo* self);
+VALA_EXTERN Foo* foo_new (void);
+VALA_EXTERN Foo* foo_construct (GType object_type);
+static void g_cclosure_user_marshal_VOID__STRING_INT (GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+static GType foo_get_type_once (void);
+VALA_EXTERN void sig_cb (GObject* o,
+ const gchar* s,
+ gint i);
+static void _vala_main (void);
+static void _sig_cb_foo_sig (Foo* _sender,
+ const gchar* s,
+ gint i,
+ gpointer self);
+
+void
+foo_fire (Foo* self)
+{
+ g_return_if_fail (IS_FOO (self));
+ g_signal_emit (self, foo_signals[FOO_SIG_SIGNAL], 0, "foo", 42);
+}
+
+Foo*
+foo_construct (GType object_type)
+{
+ Foo * self = NULL;
+ self = (Foo*) g_object_new (object_type, NULL);
+ return self;
+}
+
+Foo*
+foo_new (void)
+{
+ return foo_construct (TYPE_FOO);
+}
+
+static void
+g_cclosure_user_marshal_VOID__STRING_INT (GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1, const char* arg_1, gint arg_2, gpointer data2);
+ register GMarshalFunc_VOID__STRING_INT callback;
+ register GCClosure * cc;
+ register gpointer data1;
+ register gpointer data2;
+ cc = (GCClosure *) closure;
+ g_return_if_fail (n_param_values == 3);
+ if (G_CCLOSURE_SWAP_DATA (closure)) {
+ data1 = closure->data;
+ data2 = param_values->data[0].v_pointer;
+ } else {
+ data1 = param_values->data[0].v_pointer;
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
+ callback (data1, g_value_get_string (param_values + 1), g_value_get_int (param_values + 2), data2);
+}
+
+static void
+foo_class_init (FooClass * klass,
+ gpointer klass_data)
+{
+ foo_parent_class = g_type_class_peek_parent (klass);
+ foo_signals[FOO_SIG_SIGNAL] = g_signal_new ("sig", TYPE_FOO, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_INT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+}
+
+static void
+foo_instance_init (Foo * self,
+ gpointer klass)
+{
+}
+
+static GType
+foo_get_type_once (void)
+{
+ static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, NULL };
+ GType foo_type_id;
+ foo_type_id = g_type_register_static (G_TYPE_OBJECT, "Foo", &g_define_type_info, 0);
+ return foo_type_id;
+}
+
+GType
+foo_get_type (void)
+{
+ static volatile gsize foo_type_id__once = 0;
+ if (g_once_init_enter (&foo_type_id__once)) {
+ GType foo_type_id;
+ foo_type_id = foo_get_type_once ();
+ g_once_init_leave (&foo_type_id__once, foo_type_id);
+ }
+ return foo_type_id__once;
+}
+
+void
+sig_cb (GObject* o,
+ const gchar* s,
+ gint i)
+{
+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (o, G_TYPE_OBJECT));
+ g_return_if_fail (s != NULL);
+ success = TRUE;
+ _vala_assert (g_strcmp0 (s, "foo") == 0, "s == \"foo\"");
+ _vala_assert (i == 42, "i == 42");
+}
+
+static void
+_sig_cb_foo_sig (Foo* _sender,
+ const gchar* s,
+ gint i,
+ gpointer self)
+{
+ sig_cb (_sender, s, i);
+}
+
+static void
+_vala_main (void)
+{
+ Foo* foo = NULL;
+ Foo* _tmp0_;
+ _tmp0_ = foo_new ();
+ foo = _tmp0_;
+ g_signal_connect (foo, "sig", (GCallback) _sig_cb_foo_sig, NULL);
+ success = FALSE;
+ g_signal_emit (foo, foo_signals[FOO_SIG_SIGNAL], 0, "foo", 42);
+ _vala_assert (success, "success");
+ success = FALSE;
+ foo_fire (foo);
+ _vala_assert (success, "success");
+ _g_object_unref0 (foo);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/objects/signals-emit.vala b/tests/objects/signals-emit.vala
new file mode 100644
index 000000000..5b49cae8c
--- /dev/null
+++ b/tests/objects/signals-emit.vala
@@ -0,0 +1,28 @@
+class Foo : Object {
+ public signal void sig (string s, int i);
+
+ public void fire () {
+ sig.emit ("foo", 42);
+ }
+}
+
+void sig_cb (Object o, string s, int i) {
+ success = true;
+ assert (s == "foo");
+ assert (i == 42);
+}
+
+bool success = false;
+
+void main () {
+ var foo = new Foo ();
+ foo.sig.connect (sig_cb);
+
+ success = false;
+ foo.sig.emit ("foo", 42);
+ assert (success);
+
+ success = false;
+ foo.fire ();
+ assert (success);
+}
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index c8b3b267b..39a7af72c 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -390,6 +390,12 @@ public class Vala.MemberAccess : Expression {
}
}
+ if (inner.value_type is SignalType && member_name == "emit") {
+ // transform foo.sig.emit() to foo.sig()
+ parent_node.replace_expression (this, inner);
+ return true;
+ }
+
if (inner is MemberAccess) {
unowned MemberAccess ma = (MemberAccess) inner;
if (ma.prototype_access) {
@@ -499,6 +505,13 @@ public class Vala.MemberAccess : Expression {
s.access = SymbolAccessibility.PUBLIC;
dynamic_object_type.type_symbol.scope.add (null, s);
symbol_reference = s;
+ } else if (ma.member_name == "emit") {
+ // dynamic signal
+ var s = new DynamicSignal (inner.value_type, member_name, new VoidType (), source_reference);
+ s.access = SymbolAccessibility.PUBLIC;
+ s.add_parameter (new Parameter.with_ellipsis ());
+ dynamic_object_type.type_symbol.scope.add (null, s);
+ symbol_reference = s;
} else if (ma.member_name == "disconnect") {
error = true;
Report.error (ma.source_reference, "Use SignalHandler.disconnect() to disconnect from dynamic signal");
diff --git a/vala/valasignaltype.vala b/vala/valasignaltype.vala
index ca90186fc..93867ac54 100644
--- a/vala/valasignaltype.vala
+++ b/vala/valasignaltype.vala
@@ -35,6 +35,7 @@ public class Vala.SignalType : CallableType {
Method? connect_method;
Method? connect_after_method;
Method? disconnect_method;
+ Method? emit_method;
public SignalType (Signal signal_symbol, SourceReference? source_reference = null) {
base (signal_symbol, source_reference);
@@ -104,6 +105,16 @@ public class Vala.SignalType : CallableType {
return disconnect_method;
}
+ unowned Method get_emit_method () {
+ if (emit_method == null) {
+ emit_method = new Method ("emit", signal_symbol.return_type, source_reference);
+ emit_method.access = SymbolAccessibility.PUBLIC;
+ emit_method.external = true;
+ emit_method.owner = signal_symbol.scope;
+ }
+ return emit_method;
+ }
+
public override Symbol? get_member (string member_name) {
if (member_name == "connect") {
return get_connect_method ();
@@ -111,6 +122,8 @@ public class Vala.SignalType : CallableType {
return get_connect_after_method ();
} else if (member_name == "disconnect") {
return get_disconnect_method ();
+ } else if (member_name == "emit") {
+ return get_emit_method ();
}
return null;
}