[vala/staging] Support "emit" for explicit signal emission



commit d74400bfaae61a1e2c246382e627b0a9adf8c304
Author: Lorenz Wildberg <lorenz wild-fisch de>
Date:   Sat Dec 4 19:05:42 2021 +0000

    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.

 codegen/valaccodemethodcallmodule.vala        |   4 +-
 codegen/valagsignalmodule.vala                |   2 +-
 tests/Makefile.am                             |   2 +
 tests/objects/signals-dynamic-emit.c-expected | 195 ++++++++++++++++++++++++
 tests/objects/signals-dynamic-emit.vala       |  20 +++
 tests/objects/signals-emit.c-expected         | 206 ++++++++++++++++++++++++++
 tests/objects/signals-emit.vala               |  28 ++++
 vala/valamemberaccess.vala                    |  13 ++
 vala/valasignaltype.vala                      |  13 ++
 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;
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]