[vala/staging: 2/2] Support [HasEmitter] for vala sources



commit e1ed6ce78bfef1f7d71fd26c4523fc6c8c431bc5
Author: Simon Werbeck <simon werbeck gmail com>
Date:   Wed Oct 5 19:01:58 2016 +0200

    Support [HasEmitter] for vala sources
    
    https://bugzilla.gnome.org/show_bug.cgi?id=681356

 codegen/valaccodemethodcallmodule.vala |    2 +-
 codegen/valagirwriter.vala             |    4 +++
 tests/Makefile.am                      |    1 +
 tests/objects/bug681356.vala           |   13 +++++++++++
 vala/valasignal.vala                   |   36 ++++++++++++++++++++++++++++++++
 5 files changed, 55 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 8e923ea..e323bed 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -628,7 +628,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                        if (ma != null && ma.inner is BaseAccess && sig.is_virtual) {
                                // normal return value for base access
-                       } else if (!get_signal_has_emitter (sig)) {
+                       } else if (!get_signal_has_emitter (sig) || ma.source_reference.file == 
sig.source_reference.file) {
                                return_result_via_out_param = true;
                        }
                }
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index 3f4d15d..628b28c 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -1182,6 +1182,10 @@ public class Vala.GIRWriter : CodeVisitor {
                if (!check_accessibility (sig)) {
                        return;
                }
+
+               if (sig.emitter != null) {
+                       sig.emitter.accept (this);
+               }
                
                write_indent ();
                buffer.append_printf ("<glib:signal name=\"%s\"", CCodeBaseModule.get_ccode_name (sig));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 901cb28..01ad63a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -173,6 +173,7 @@ TESTS = \
        objects/bug663134.vala \
        objects/bug664529.vala \
        objects/bug667668.vala \
+       objects/bug681356.vala \
        objects/bug683646.vala \
        objects/bug695671.vala \
        objects/bug701978.vala \
diff --git a/tests/objects/bug681356.vala b/tests/objects/bug681356.vala
new file mode 100644
index 0000000..326dedb
--- /dev/null
+++ b/tests/objects/bug681356.vala
@@ -0,0 +1,13 @@
+public class Foo : GLib.Object {
+       [HasEmitter]
+       public signal int bar (int i);
+}
+
+void main () {
+       var f = new Foo ();
+
+       f.bar.connect (i => i + 12);
+
+       var res = f.bar (30);
+       assert (res == 42);
+}
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index 17e858f..d11180f 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -59,6 +59,12 @@ public class Vala.Signal : Symbol, Lockable, Callable {
         * */
        public Method default_handler { get; private set; }
 
+       /**
+        * Refers to the public signal emitter method, which is an anonymous
+        * function in the scope.
+        * */
+       public Method emitter { get; private set; }
+
        private bool lock_used = false;
 
        private DataType _return_type;
@@ -158,6 +164,9 @@ public class Vala.Signal : Symbol, Lockable, Callable {
                } else if (default_handler != null) {
                        default_handler.accept (visitor);
                }
+               if (emitter != null) {
+                       emitter.accept (visitor);
+               }
        }
 
        public bool get_lock_used () {
@@ -219,6 +228,33 @@ public class Vala.Signal : Symbol, Lockable, Callable {
                        default_handler.check (context);
                }
 
+               if (!external_package && get_attribute ("HasEmitter") != null) {
+                       emitter = new Method (name, return_type, source_reference);
+
+                       emitter.owner = owner;
+                       emitter.access = access;
+
+                       var body = new Block (source_reference);
+                       var call = new MethodCall (new MemberAccess.simple (name, source_reference), 
source_reference);
+
+                       foreach (Parameter param in parameters) {
+                               emitter.add_parameter (param);
+                               call.add_argument (new MemberAccess.simple (param.name, source_reference));
+                       }
+
+                       if (return_type is VoidType) {
+                               body.add_statement (new ExpressionStatement (call, source_reference));
+                       } else {
+                               body.add_statement (new ReturnStatement (call, source_reference));
+                       }
+                       emitter.body = body;
+
+                       var cl = parent_symbol as ObjectTypeSymbol;
+
+                       cl.add_hidden_method (emitter);
+                       emitter.check (context);
+               }
+
 
                if (!external_package && !hides && get_hidden_member () != null) {
                        Report.warning (source_reference, "%s hides inherited signal `%s'. Use the `new' 
keyword if hiding was intentional".printf (get_full_name (), get_hidden_member ().get_full_name ()));


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