]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
GAsync: Fix base access in async methods
authorJürg Billeter <j@bitron.ch>
Mon, 16 Nov 2009 21:07:48 +0000 (22:07 +0100)
committerJürg Billeter <j@bitron.ch>
Mon, 16 Nov 2009 21:09:34 +0000 (22:09 +0100)
Fixes bug 601558.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
tests/Makefile.am
tests/asynchronous/bug601558.vala [new file with mode: 0644]
vala/valaparser.vala

index 9b240a4e8628560dc428ba7865d6f6340eb69a65..0a7779f33f51f73ae7b344153ed0cae6173f0ffc 100644 (file)
@@ -3220,7 +3220,15 @@ internal class Vala.CCodeBaseModule : CCodeModule {
        }
 
        public override void visit_base_access (BaseAccess expr) {
-               expr.ccodenode = generate_instance_cast (new CCodeIdentifier ("self"), expr.value_type.data_type);
+               CCodeExpression this_access;
+               if (current_method != null && current_method.coroutine) {
+                       // use closure
+                       this_access = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "self");
+               } else {
+                       this_access = new CCodeIdentifier ("self");
+               }
+
+               expr.ccodenode = generate_instance_cast (this_access, expr.value_type.data_type);
        }
 
        public override void visit_postfix_expression (PostfixExpression expr) {
index c5a188db64036b6ca803be32558b3af102979bfb..4589cbf1b1a4237c87e226e8dc1515d0ef939a71 100644 (file)
@@ -73,6 +73,24 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                        // async call
 
                        async_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
+                       var finish_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+
+                       if (ma.inner is BaseAccess) {
+                               if (m.base_method != null) {
+                                       var base_class = (Class) m.base_method.parent_symbol;
+                                       var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
+                                       vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
+
+                                       async_call.call = new CCodeMemberAccess.pointer (vcast, m.vfunc_name);
+                                       finish_call.call = new CCodeMemberAccess.pointer (vcast, m.get_finish_vfunc_name ());
+                               } else if (m.base_interface_method != null) {
+                                       var base_iface = (Interface) m.base_interface_method.parent_symbol;
+                                       string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
+
+                                       async_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.vfunc_name);
+                                       finish_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.get_finish_vfunc_name ());
+                               }
+                       }
 
                        if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
                                // no finish call
@@ -80,14 +98,14 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                params = m.get_async_begin_parameters ();
                        } else if (ma.member_name == "end" && ma.inner.symbol_reference == ma.symbol_reference) {
                                // no async call
-                               ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+                               ccall = finish_call;
                                params = m.get_async_end_parameters ();
                        } else if (!expr.is_yield_expression) {
                                // same as .begin, backwards compatible to bindings without async methods
                                ccall = async_call;
                                params = m.get_async_begin_parameters ();
                        } else {
-                               ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+                               ccall = finish_call;
 
                                // output arguments used separately
                                out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
index 7e6f222897d8c6946d596f0648e470487625cf34..87d3b72debf815bc1e6d8fb6759a25b8e588123c 100644 (file)
@@ -71,6 +71,7 @@ TESTS = \
        asynchronous/bug598698.vala \
        asynchronous/bug599568.vala \
        asynchronous/bug600827.vala \
+       asynchronous/bug601558.vala \
        dbus/basic-types.test \
        dbus/arrays.test \
        dbus/async.test \
diff --git a/tests/asynchronous/bug601558.vala b/tests/asynchronous/bug601558.vala
new file mode 100644 (file)
index 0000000..cd98c0f
--- /dev/null
@@ -0,0 +1,13 @@
+public class Foo {
+       public virtual async void do_foo () {
+       }
+}
+
+public class Bar : Foo {
+       public override async void do_foo () {
+               yield base.do_foo ();
+       }
+}
+
+void main () {
+}
index 6828341f0b323da57d37113b3ce0c9cef5a6db9b..ff97edf66360ccd98d6a0046cb7aa5369eb3353a 100644 (file)
@@ -854,7 +854,12 @@ public class Vala.Parser : CodeVisitor {
        Expression parse_yield_expression () throws ParseError {
                var begin = get_location ();
                expect (TokenType.YIELD);
-               var member = parse_member_name ();
+               Expression base_expr = null;
+               if (current () == TokenType.BASE) {
+                       base_expr = parse_base_access ();
+                       expect (TokenType.DOT);
+               }
+               var member = parse_member_name (base_expr);
                var call = (MethodCall) parse_method_call (begin, member);
                call.is_yield_expression = true;
                return call;
@@ -3103,7 +3108,7 @@ public class Vala.Parser : CodeVisitor {
                return null;
        }
 
-       MemberAccess parse_member_name () throws ParseError {
+       MemberAccess parse_member_name (Expression? base_expr = null) throws ParseError {
                var begin = get_location ();
                MemberAccess expr = null;
                bool first = true;
@@ -3118,7 +3123,7 @@ public class Vala.Parser : CodeVisitor {
                        }
 
                        List<DataType> type_arg_list = parse_type_argument_list (false);
-                       expr = new MemberAccess (expr, id, get_src (begin));
+                       expr = new MemberAccess (expr != null ? expr : base_expr, id, get_src (begin));
                        expr.qualified = qualified;
                        if (type_arg_list != null) {
                                foreach (DataType type_arg in type_arg_list) {