[vala/staging] vala: Enforce "return yield ..." syntax to be expected
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] vala: Enforce "return yield ..." syntax to be expected
- Date: Sat, 22 Sep 2018 14:35:29 +0000 (UTC)
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]