[vala/staging] vala: Enforce "return yield ..." syntax to be expected



commit 898e45a6ff6129fc5c674af48118042dd64123ff
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sat Sep 22 14:44:40 2018 +0200

    vala: Enforce "return yield ..." syntax to be expected
    
    "yield return ..." wasn't handled correctly and resulted in broken c-code.
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/675

 codegen/valagasyncmodule.vala  | 35 +++++------------------------
 tests/Makefile.am              |  1 +
 tests/parser/yield-return.test | 13 +++++++++++
 vala/valacodewriter.vala       |  4 ----
 vala/valagenieparser.vala      |  8 ++-----
 vala/valaparser.vala           | 12 +++++-----
 vala/valayieldstatement.vala   | 51 +-----------------------------------------
 7 files changed, 28 insertions(+), 96 deletions(-)
---
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 9d63ab7ad..f234afdb4 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -773,37 +773,12 @@ public class Vala.GAsyncModule : GtkModule {
                        return;
                }
 
-               if (stmt.yield_expression == null) {
-                       int state = emit_context.next_coroutine_state++;
+               int state = emit_context.next_coroutine_state++;
 
-                       ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), 
"_state_"), new CCodeConstant (state.to_string ()));
-                       ccode.add_return (new CCodeConstant ("FALSE"));
-                       ccode.add_label ("_state_%d".printf (state));
-                       ccode.add_statement (new CCodeEmptyStatement ());
-
-                       return;
-               }
-
-               if (stmt.yield_expression.error) {
-                       stmt.error = true;
-                       return;
-               }
-
-               ccode.add_expression (get_cvalue (stmt.yield_expression));
-
-               if (stmt.tree_can_fail && stmt.yield_expression.tree_can_fail) {
-                       // simple case, no node breakdown necessary
-
-                       add_simple_check (stmt.yield_expression);
-               }
-
-               /* free temporary objects */
-
-               foreach (var value in temp_ref_values) {
-                       ccode.add_expression (destroy_value (value));
-               }
-
-               temp_ref_values.clear ();
+               ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), 
"_state_"), new CCodeConstant (state.to_string ()));
+               ccode.add_return (new CCodeConstant ("FALSE"));
+               ccode.add_label ("_state_%d".printf (state));
+               ccode.add_statement (new CCodeEmptyStatement ());
        }
 
        public override void return_with_exception (CCodeExpression error_expr)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index da1b33169..fc161d099 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -482,6 +482,7 @@ TESTS = \
        parser/unsupported-property-async.test \
        parser/unsupported-property-throws.test \
        parser/yield-method.test \
+       parser/yield-return.test \
        parser/yield-return.vala \
        parser/bug728574.vala \
        parser/bug749576.vala \
diff --git a/tests/parser/yield-return.test b/tests/parser/yield-return.test
new file mode 100644
index 000000000..08256e0cf
--- /dev/null
+++ b/tests/parser/yield-return.test
@@ -0,0 +1,13 @@
+Invalid Code
+
+class Foo {
+       public async Foo () {
+       }
+}
+
+async Foo bar () {
+       yield return new Foo ();
+}
+
+void main () {
+}
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 620e45896..a71a6a382 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -1103,10 +1103,6 @@ public class Vala.CodeWriter : CodeVisitor {
        public override void visit_yield_statement (YieldStatement y) {
                write_indent ();
                write_string ("yield");
-               if (y.yield_expression != null) {
-                       write_string (" ");
-                       y.yield_expression.accept (this);
-               }
                write_string (";");
                write_newline ();
        }
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 24c638492..0220deafa 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -2260,16 +2260,12 @@ public class Vala.Genie.Parser : CodeVisitor {
        Statement parse_yield_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.YIELD);
-               if (current () != TokenType.SEMICOLON && current () != TokenType.EOL && current () != 
TokenType.RETURN) {
+               if (current () != TokenType.SEMICOLON && current () != TokenType.EOL) {
                        prev ();
                        return parse_expression_statement ();
                }
-               Expression expr = null;
-               if (accept (TokenType.RETURN)) {
-                       expr = parse_expression ();
-               }
                expect_terminator ();
-               return new YieldStatement (expr, get_src (begin));
+               return new YieldStatement (get_src (begin));
        }
 
        Statement parse_throw_statement () throws ParseError {
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index c4d8a5313..05b7139bf 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2070,17 +2070,17 @@ public class Vala.Parser : CodeVisitor {
        Statement parse_yield_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.YIELD);
-               if (current () != TokenType.SEMICOLON && current () != TokenType.RETURN) {
+               var token = current ();
+               if (token != TokenType.SEMICOLON) {
                        // yield expression
                        prev ();
+                       if (token == TokenType.RETURN) {
+                               throw new ParseError.SYNTAX ("expected `return yield'");
+                       }
                        return parse_expression_statement ();
                }
-               Expression expr = null;
-               if (accept (TokenType.RETURN)) {
-                       expr = parse_expression ();
-               }
                expect (TokenType.SEMICOLON);
-               return new YieldStatement (expr, get_src (begin));
+               return new YieldStatement (get_src (begin));
        }
 
        Statement parse_throw_statement () throws ParseError {
diff --git a/vala/valayieldstatement.vala b/vala/valayieldstatement.vala
index 5b5a6f307..795de2761 100644
--- a/vala/valayieldstatement.vala
+++ b/vala/valayieldstatement.vala
@@ -24,21 +24,6 @@
  * Represents a yield statement in the source code.
  */
 public class Vala.YieldStatement : CodeNode, Statement {
-       /**
-        * The expression to yield or the method call to yield to.
-        */
-       public Expression? yield_expression {
-               get { return _yield_expression; }
-               set {
-                       _yield_expression = value;
-                       if (_yield_expression != null) {
-                               _yield_expression.parent_node = this;
-                       }
-               }
-       }
-
-       private Expression _yield_expression;
-
        /**
         * Creates a new yield statement.
         *
@@ -46,45 +31,11 @@ public class Vala.YieldStatement : CodeNode, Statement {
         * @param source_reference reference to source code
         * @return                 newly created yield statement
         */
-       public YieldStatement (Expression? yield_expression, SourceReference? source_reference = null) {
-               this.yield_expression = yield_expression;
+       public YieldStatement (SourceReference? source_reference = null) {
                this.source_reference = source_reference;
        }
 
-       public override void accept (CodeVisitor visitor) {
-               visitor.visit_yield_statement (this);
-       }
-
-       public override void accept_children (CodeVisitor visitor) {
-               if (yield_expression != null) {
-                       yield_expression.accept (visitor);
-
-                       visitor.visit_end_full_expression (yield_expression);
-               }
-       }
-
-       public override void replace_expression (Expression old_node, Expression new_node) {
-               if (yield_expression == old_node) {
-                       yield_expression = new_node;
-               }
-       }
-
-       public override bool check (CodeContext context) {
-               if (yield_expression != null) {
-                       yield_expression.check (context);
-                       error = yield_expression.error;
-               }
-
-               return !error;
-       }
-
        public override void emit (CodeGenerator codegen) {
-               if (yield_expression != null) {
-                       yield_expression.emit (codegen);
-
-                       codegen.visit_end_full_expression (yield_expression);
-               }
-
                codegen.visit_yield_statement (this);
        }
 }


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